bashbros 0.1.2 → 0.1.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.
Files changed (65) hide show
  1. package/README.md +727 -265
  2. package/dist/adapters-JAZGGNVP.js +9 -0
  3. package/dist/chunk-4XZ64P4V.js +47 -0
  4. package/dist/chunk-4XZ64P4V.js.map +1 -0
  5. package/dist/{chunk-XCZMQRSX.js → chunk-7OEWYFN3.js} +745 -541
  6. package/dist/chunk-7OEWYFN3.js.map +1 -0
  7. package/dist/{chunk-SQCP6IYB.js → chunk-CG6VEHJM.js} +3 -2
  8. package/dist/chunk-CG6VEHJM.js.map +1 -0
  9. package/dist/{chunk-DLP2O6PN.js → chunk-EMLEJVJZ.js} +102 -1
  10. package/dist/chunk-EMLEJVJZ.js.map +1 -0
  11. package/dist/chunk-IUUBCPMV.js +166 -0
  12. package/dist/chunk-IUUBCPMV.js.map +1 -0
  13. package/dist/chunk-J6ONXY6N.js +146 -0
  14. package/dist/chunk-J6ONXY6N.js.map +1 -0
  15. package/dist/chunk-KYDMPE4N.js +224 -0
  16. package/dist/chunk-KYDMPE4N.js.map +1 -0
  17. package/dist/chunk-LJE4EPIU.js +56 -0
  18. package/dist/chunk-LJE4EPIU.js.map +1 -0
  19. package/dist/chunk-LZYW7XQO.js +339 -0
  20. package/dist/chunk-LZYW7XQO.js.map +1 -0
  21. package/dist/{chunk-YUMNBQAY.js → chunk-RDNSS3ME.js} +587 -12
  22. package/dist/chunk-RDNSS3ME.js.map +1 -0
  23. package/dist/{chunk-BW6XCOJH.js → chunk-RTZ4QWG2.js} +2 -2
  24. package/dist/chunk-RTZ4QWG2.js.map +1 -0
  25. package/dist/chunk-SDN6TAGD.js +157 -0
  26. package/dist/chunk-SDN6TAGD.js.map +1 -0
  27. package/dist/chunk-T5ONCUHZ.js +198 -0
  28. package/dist/chunk-T5ONCUHZ.js.map +1 -0
  29. package/dist/cli.js +1182 -251
  30. package/dist/cli.js.map +1 -1
  31. package/dist/{config-JLLOTFLI.js → config-I5NCK3RJ.js} +2 -2
  32. package/dist/copilot-cli-5WJWK5YT.js +9 -0
  33. package/dist/{db-OBKEXRTP.js → db-ETWTBXAE.js} +2 -2
  34. package/dist/db-checks-2YOVECD4.js +133 -0
  35. package/dist/db-checks-2YOVECD4.js.map +1 -0
  36. package/dist/{display-6LZ2HBCU.js → display-UH7KEHOW.js} +3 -3
  37. package/dist/display-UH7KEHOW.js.map +1 -0
  38. package/dist/gemini-cli-3563EELZ.js +9 -0
  39. package/dist/gemini-cli-3563EELZ.js.map +1 -0
  40. package/dist/index.d.ts +195 -72
  41. package/dist/index.js +119 -398
  42. package/dist/index.js.map +1 -1
  43. package/dist/{ollama-HY35OHW4.js → ollama-5JVKNFOV.js} +2 -2
  44. package/dist/ollama-5JVKNFOV.js.map +1 -0
  45. package/dist/opencode-DRCY275R.js +9 -0
  46. package/dist/opencode-DRCY275R.js.map +1 -0
  47. package/dist/profiles-7CLN6TAT.js +9 -0
  48. package/dist/profiles-7CLN6TAT.js.map +1 -0
  49. package/dist/setup-YS27MOPE.js +124 -0
  50. package/dist/setup-YS27MOPE.js.map +1 -0
  51. package/dist/static/index.html +4815 -2007
  52. package/dist/store-WJ5Y7MOE.js +9 -0
  53. package/dist/store-WJ5Y7MOE.js.map +1 -0
  54. package/dist/writer-3NAVABN6.js +12 -0
  55. package/dist/writer-3NAVABN6.js.map +1 -0
  56. package/package.json +77 -68
  57. package/dist/chunk-BW6XCOJH.js.map +0 -1
  58. package/dist/chunk-DLP2O6PN.js.map +0 -1
  59. package/dist/chunk-SQCP6IYB.js.map +0 -1
  60. package/dist/chunk-XCZMQRSX.js.map +0 -1
  61. package/dist/chunk-YUMNBQAY.js.map +0 -1
  62. /package/dist/{config-JLLOTFLI.js.map → adapters-JAZGGNVP.js.map} +0 -0
  63. /package/dist/{db-OBKEXRTP.js.map → config-I5NCK3RJ.js.map} +0 -0
  64. /package/dist/{display-6LZ2HBCU.js.map → copilot-cli-5WJWK5YT.js.map} +0 -0
  65. /package/dist/{ollama-HY35OHW4.js.map → db-ETWTBXAE.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/claude-code.ts"],"sourcesContent":["/**\n * Claude Code Hook Integration\n * Seamlessly integrate BashBros with Claude Code\n */\n\nimport { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs'\nimport { join } from 'path'\nimport { homedir } from 'os'\n\nexport interface ClaudeSettings {\n hooks?: {\n PreToolUse?: HookConfig[]\n PostToolUse?: HookConfig[]\n SessionEnd?: HookConfig[]\n }\n [key: string]: unknown\n}\n\ninterface HookConfig {\n matcher?: string\n hooks: { type: string; command: string }[]\n}\n\nconst CLAUDE_SETTINGS_PATH = join(homedir(), '.claude', 'settings.json')\nconst CLAUDE_DIR = join(homedir(), '.claude')\n\nconst BASHBROS_HOOK_MARKER = '# bashbros-managed'\n// Use --marker flag for Windows compatibility (ignored by the command but lets us identify our hooks)\nconst BASHBROS_ALL_TOOLS_MARKER = '--marker=bashbros-all-tools'\n\nexport class ClaudeCodeHooks {\n /**\n * Check if Claude Code is installed\n */\n static isClaudeInstalled(): boolean {\n return existsSync(CLAUDE_DIR)\n }\n\n /**\n * Load current Claude settings\n */\n static loadSettings(): ClaudeSettings {\n if (!existsSync(CLAUDE_SETTINGS_PATH)) {\n return {}\n }\n\n try {\n const content = readFileSync(CLAUDE_SETTINGS_PATH, 'utf-8')\n return JSON.parse(content)\n } catch {\n return {}\n }\n }\n\n /**\n * Save Claude settings\n */\n static saveSettings(settings: ClaudeSettings): void {\n if (!existsSync(CLAUDE_DIR)) {\n mkdirSync(CLAUDE_DIR, { recursive: true })\n }\n\n writeFileSync(\n CLAUDE_SETTINGS_PATH,\n JSON.stringify(settings, null, 2),\n 'utf-8'\n )\n }\n\n /**\n * Install BashBros hooks into Claude Code\n */\n static install(): { success: boolean; message: string } {\n if (!this.isClaudeInstalled()) {\n return {\n success: false,\n message: 'Claude Code not found. Install Claude Code first.'\n }\n }\n\n const settings = this.loadSettings()\n\n // Initialize hooks if not present\n if (!settings.hooks) {\n settings.hooks = {}\n }\n\n // Check if already installed\n if (this.isInstalled(settings)) {\n return {\n success: true,\n message: 'BashBros hooks already installed.'\n }\n }\n\n // Add PreToolUse hook for Bash commands\n const preToolUseHook: HookConfig = {\n matcher: 'Bash',\n hooks: [{\n type: 'command',\n command: `bashbros gate \"$TOOL_INPUT\" ${BASHBROS_HOOK_MARKER}`\n }]\n }\n\n // Add PostToolUse hook for metrics\n const postToolUseHook: HookConfig = {\n matcher: 'Bash',\n hooks: [{\n type: 'command',\n command: `bashbros record \"$TOOL_INPUT\" \"$TOOL_OUTPUT\" ${BASHBROS_HOOK_MARKER}`\n }]\n }\n\n // Add SessionEnd hook for reports\n const sessionEndHook: HookConfig = {\n hooks: [{\n type: 'command',\n command: `bashbros session-end ${BASHBROS_HOOK_MARKER}`\n }]\n }\n\n // Merge with existing hooks\n settings.hooks.PreToolUse = [\n ...(settings.hooks.PreToolUse || []),\n preToolUseHook\n ]\n\n settings.hooks.PostToolUse = [\n ...(settings.hooks.PostToolUse || []),\n postToolUseHook\n ]\n\n settings.hooks.SessionEnd = [\n ...(settings.hooks.SessionEnd || []),\n sessionEndHook\n ]\n\n this.saveSettings(settings)\n\n return {\n success: true,\n message: 'BashBros hooks installed successfully.'\n }\n }\n\n /**\n * Uninstall BashBros hooks from Claude Code\n */\n static uninstall(): { success: boolean; message: string } {\n if (!this.isClaudeInstalled()) {\n return {\n success: false,\n message: 'Claude Code not found.'\n }\n }\n\n const settings = this.loadSettings()\n\n if (!settings.hooks) {\n return {\n success: true,\n message: 'No hooks to uninstall.'\n }\n }\n\n // Remove BashBros hooks\n const filterHooks = (hooks: HookConfig[] | undefined): HookConfig[] => {\n if (!hooks) return []\n return hooks.filter(h =>\n !h.hooks.some(hook => hook.command.includes(BASHBROS_HOOK_MARKER))\n )\n }\n\n settings.hooks.PreToolUse = filterHooks(settings.hooks.PreToolUse)\n settings.hooks.PostToolUse = filterHooks(settings.hooks.PostToolUse)\n settings.hooks.SessionEnd = filterHooks(settings.hooks.SessionEnd)\n\n // Clean up empty arrays\n if (settings.hooks.PreToolUse?.length === 0) delete settings.hooks.PreToolUse\n if (settings.hooks.PostToolUse?.length === 0) delete settings.hooks.PostToolUse\n if (settings.hooks.SessionEnd?.length === 0) delete settings.hooks.SessionEnd\n if (Object.keys(settings.hooks).length === 0) delete settings.hooks\n\n this.saveSettings(settings)\n\n return {\n success: true,\n message: 'BashBros hooks uninstalled successfully.'\n }\n }\n\n /**\n * Check if BashBros hooks are installed\n */\n static isInstalled(settings?: ClaudeSettings): boolean {\n const s = settings || this.loadSettings()\n\n if (!s.hooks) return false\n\n const hasMarker = (hooks: HookConfig[] | undefined): boolean => {\n if (!hooks) return false\n return hooks.some(h =>\n h.hooks.some(hook => hook.command.includes(BASHBROS_HOOK_MARKER))\n )\n }\n\n return hasMarker(s.hooks.PreToolUse) ||\n hasMarker(s.hooks.PostToolUse) ||\n hasMarker(s.hooks.SessionEnd)\n }\n\n /**\n * Get hook status\n */\n static getStatus(): {\n claudeInstalled: boolean\n hooksInstalled: boolean\n allToolsInstalled: boolean\n hooks: string[]\n } {\n const claudeInstalled = this.isClaudeInstalled()\n const settings = claudeInstalled ? this.loadSettings() : {}\n const hooksInstalled = this.isInstalled(settings)\n const allToolsInstalled = this.isAllToolsInstalled(settings)\n\n const hooks: string[] = []\n if (settings.hooks?.PreToolUse) hooks.push('PreToolUse (gate)')\n if (settings.hooks?.PostToolUse) hooks.push('PostToolUse (record)')\n if (settings.hooks?.SessionEnd) hooks.push('SessionEnd (report)')\n if (allToolsInstalled) hooks.push('PostToolUse (all-tools)')\n\n return {\n claudeInstalled,\n hooksInstalled,\n allToolsInstalled,\n hooks\n }\n }\n\n /**\n * Check if all-tools recording is installed\n */\n static isAllToolsInstalled(settings?: ClaudeSettings): boolean {\n const s = settings || this.loadSettings()\n\n if (!s.hooks?.PostToolUse) return false\n\n // Check for both old (# bashbros-all-tools) and new (--marker=bashbros-all-tools) formats\n return s.hooks.PostToolUse.some(h =>\n h.hooks.some(hook =>\n hook.command.includes(BASHBROS_ALL_TOOLS_MARKER) ||\n hook.command.includes('bashbros-all-tools')\n )\n )\n }\n\n /**\n * Install all-tools recording hook (records ALL Claude Code tools, not just Bash)\n */\n static installAllTools(): { success: boolean; message: string } {\n if (!this.isClaudeInstalled()) {\n return {\n success: false,\n message: 'Claude Code not found. Install Claude Code first.'\n }\n }\n\n const settings = this.loadSettings()\n\n // Initialize hooks if not present\n if (!settings.hooks) {\n settings.hooks = {}\n }\n\n // Check if already installed\n if (this.isAllToolsInstalled(settings)) {\n return {\n success: true,\n message: 'BashBros all-tools recording already installed.'\n }\n }\n\n // Add PostToolUse hook for ALL tools (empty matcher = all tools)\n const allToolsHook: HookConfig = {\n matcher: '', // Empty matcher matches ALL tools\n hooks: [{\n type: 'command',\n command: `bashbros record-tool ${BASHBROS_ALL_TOOLS_MARKER}`\n }]\n }\n\n // Add to beginning of PostToolUse hooks so it runs for all tools\n settings.hooks.PostToolUse = [\n allToolsHook,\n ...(settings.hooks.PostToolUse || [])\n ]\n\n this.saveSettings(settings)\n\n return {\n success: true,\n message: 'BashBros all-tools recording installed. All Claude Code tools will now be recorded.'\n }\n }\n\n /**\n * Uninstall all-tools recording hook\n */\n static uninstallAllTools(): { success: boolean; message: string } {\n if (!this.isClaudeInstalled()) {\n return {\n success: false,\n message: 'Claude Code not found.'\n }\n }\n\n const settings = this.loadSettings()\n\n if (!settings.hooks?.PostToolUse) {\n return {\n success: true,\n message: 'No all-tools hook to uninstall.'\n }\n }\n\n // Remove all-tools hook (both old and new marker formats)\n settings.hooks.PostToolUse = settings.hooks.PostToolUse.filter(h =>\n !h.hooks.some(hook =>\n hook.command.includes(BASHBROS_ALL_TOOLS_MARKER) ||\n hook.command.includes('bashbros-all-tools')\n )\n )\n\n // Clean up empty array\n if (settings.hooks.PostToolUse.length === 0) {\n delete settings.hooks.PostToolUse\n }\n if (Object.keys(settings.hooks).length === 0) {\n delete settings.hooks\n }\n\n this.saveSettings(settings)\n\n return {\n success: true,\n message: 'BashBros all-tools recording uninstalled.'\n }\n }\n}\n\n/**\n * Gate command - called by PreToolUse hook\n * Returns exit code 0 to allow, non-zero to block\n */\nexport async function gateCommand(command: string): Promise<{\n allowed: boolean\n reason?: string\n riskScore?: number\n}> {\n // Dynamic import to avoid circular deps\n const { PolicyEngine } = await import('../policy/engine.js')\n const { RiskScorer } = await import('../policy/risk-scorer.js')\n const { loadConfig } = await import('../config.js')\n\n const config = loadConfig()\n const engine = new PolicyEngine(config)\n const scorer = new RiskScorer()\n\n const violations = engine.validate(command)\n const risk = scorer.score(command)\n\n if (violations.length > 0) {\n return {\n allowed: false,\n reason: violations[0].message,\n riskScore: risk.score\n }\n }\n\n // Config-driven risk threshold checks\n if (config.riskScoring.enabled) {\n if (risk.score >= config.riskScoring.blockThreshold) {\n return {\n allowed: false,\n reason: `Risk score ${risk.score} >= block threshold ${config.riskScoring.blockThreshold}: ${risk.factors.join(', ')}`,\n riskScore: risk.score\n }\n }\n if (risk.score >= config.riskScoring.warnThreshold) {\n process.stderr.write(`[BashBros] Warning: risk score ${risk.score} (${risk.factors.join(', ')})\\n`)\n }\n }\n\n // DB-backed cross-process checks (fail-open: DB errors never block commands)\n try {\n const { join } = await import('path')\n const { homedir } = await import('os')\n const { DashboardDB } = await import('../dashboard/db.js')\n const { checkLoopDetection, checkAnomalyDetection, checkRateLimit } = await import('../policy/db-checks.js')\n\n const dbPath = join(homedir(), '.bashbros', 'dashboard.db')\n const db = new DashboardDB(dbPath)\n try {\n // Loop detection\n if (config.loopDetection.enabled) {\n const loop = checkLoopDetection(command, config.loopDetection, db)\n if (loop.violation) {\n db.close()\n return { allowed: false, reason: loop.violation.message, riskScore: risk.score }\n }\n if (loop.warning) {\n process.stderr.write(`[BashBros] ${loop.warning}\\n`)\n }\n }\n\n // Anomaly detection\n if (config.anomalyDetection.enabled) {\n const anomaly = checkAnomalyDetection(command, config.anomalyDetection, db)\n if (anomaly.violation) {\n db.close()\n return { allowed: false, reason: anomaly.violation.message, riskScore: risk.score }\n }\n if (anomaly.warning) {\n process.stderr.write(`[BashBros] ${anomaly.warning}\\n`)\n }\n }\n\n // Rate limiting\n if (config.rateLimit.enabled) {\n const rate = checkRateLimit(config.rateLimit, db)\n if (rate.violation) {\n db.close()\n return { allowed: false, reason: rate.violation.message, riskScore: risk.score }\n }\n }\n } finally {\n db.close()\n }\n } catch {\n // Fail-open: DB errors never block commands\n }\n\n return {\n allowed: true,\n riskScore: risk.score\n }\n}\n"],"mappings":"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","names":["join","homedir"]}