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.
- package/README.md +727 -265
- package/dist/adapters-JAZGGNVP.js +9 -0
- package/dist/chunk-4XZ64P4V.js +47 -0
- package/dist/chunk-4XZ64P4V.js.map +1 -0
- package/dist/{chunk-XCZMQRSX.js → chunk-7OEWYFN3.js} +745 -541
- package/dist/chunk-7OEWYFN3.js.map +1 -0
- package/dist/{chunk-SQCP6IYB.js → chunk-CG6VEHJM.js} +3 -2
- package/dist/chunk-CG6VEHJM.js.map +1 -0
- package/dist/{chunk-DLP2O6PN.js → chunk-EMLEJVJZ.js} +102 -1
- package/dist/chunk-EMLEJVJZ.js.map +1 -0
- package/dist/chunk-IUUBCPMV.js +166 -0
- package/dist/chunk-IUUBCPMV.js.map +1 -0
- package/dist/chunk-J6ONXY6N.js +146 -0
- package/dist/chunk-J6ONXY6N.js.map +1 -0
- package/dist/chunk-KYDMPE4N.js +224 -0
- package/dist/chunk-KYDMPE4N.js.map +1 -0
- package/dist/chunk-LJE4EPIU.js +56 -0
- package/dist/chunk-LJE4EPIU.js.map +1 -0
- package/dist/chunk-LZYW7XQO.js +339 -0
- package/dist/chunk-LZYW7XQO.js.map +1 -0
- package/dist/{chunk-YUMNBQAY.js → chunk-RDNSS3ME.js} +587 -12
- package/dist/chunk-RDNSS3ME.js.map +1 -0
- package/dist/{chunk-BW6XCOJH.js → chunk-RTZ4QWG2.js} +2 -2
- package/dist/chunk-RTZ4QWG2.js.map +1 -0
- package/dist/chunk-SDN6TAGD.js +157 -0
- package/dist/chunk-SDN6TAGD.js.map +1 -0
- package/dist/chunk-T5ONCUHZ.js +198 -0
- package/dist/chunk-T5ONCUHZ.js.map +1 -0
- package/dist/cli.js +1182 -251
- package/dist/cli.js.map +1 -1
- package/dist/{config-JLLOTFLI.js → config-I5NCK3RJ.js} +2 -2
- package/dist/copilot-cli-5WJWK5YT.js +9 -0
- package/dist/{db-OBKEXRTP.js → db-ETWTBXAE.js} +2 -2
- package/dist/db-checks-2YOVECD4.js +133 -0
- package/dist/db-checks-2YOVECD4.js.map +1 -0
- package/dist/{display-6LZ2HBCU.js → display-UH7KEHOW.js} +3 -3
- package/dist/display-UH7KEHOW.js.map +1 -0
- package/dist/gemini-cli-3563EELZ.js +9 -0
- package/dist/gemini-cli-3563EELZ.js.map +1 -0
- package/dist/index.d.ts +195 -72
- package/dist/index.js +119 -398
- package/dist/index.js.map +1 -1
- package/dist/{ollama-HY35OHW4.js → ollama-5JVKNFOV.js} +2 -2
- package/dist/ollama-5JVKNFOV.js.map +1 -0
- package/dist/opencode-DRCY275R.js +9 -0
- package/dist/opencode-DRCY275R.js.map +1 -0
- package/dist/profiles-7CLN6TAT.js +9 -0
- package/dist/profiles-7CLN6TAT.js.map +1 -0
- package/dist/setup-YS27MOPE.js +124 -0
- package/dist/setup-YS27MOPE.js.map +1 -0
- package/dist/static/index.html +4815 -2007
- package/dist/store-WJ5Y7MOE.js +9 -0
- package/dist/store-WJ5Y7MOE.js.map +1 -0
- package/dist/writer-3NAVABN6.js +12 -0
- package/dist/writer-3NAVABN6.js.map +1 -0
- package/package.json +77 -68
- package/dist/chunk-BW6XCOJH.js.map +0 -1
- package/dist/chunk-DLP2O6PN.js.map +0 -1
- package/dist/chunk-SQCP6IYB.js.map +0 -1
- package/dist/chunk-XCZMQRSX.js.map +0 -1
- package/dist/chunk-YUMNBQAY.js.map +0 -1
- /package/dist/{config-JLLOTFLI.js.map → adapters-JAZGGNVP.js.map} +0 -0
- /package/dist/{db-OBKEXRTP.js.map → config-I5NCK3RJ.js.map} +0 -0
- /package/dist/{display-6LZ2HBCU.js.map → copilot-cli-5WJWK5YT.js.map} +0 -0
- /package/dist/{ollama-HY35OHW4.js.map → db-ETWTBXAE.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/integration/bashgym.ts","../src/core.ts","../src/policy/loop-detector.ts","../src/policy/anomaly-detector.ts","../src/policy/output-scanner.ts","../src/bro/profiler.ts","../src/bro/router.ts","../src/bro/suggester.ts","../src/bro/worker.ts","../src/bro/bro.ts","../src/observability/cost.ts","../src/observability/report.ts","../src/safety/undo-stack.ts"],"sourcesContent":["/**\r\n * Bashgym Integration for Bashbros\r\n *\r\n * Provides integration between bashbros (security middleware + AI sidekick) and\r\n * bashgym (self-improving agent training) through a shared directory protocol.\r\n *\r\n * Key features:\r\n * - Trace export to shared directory\r\n * - Settings synchronization\r\n * - Model update watcher for hot-swap\r\n *\r\n * Data Flow:\r\n * bashbros captures traces -> bashgym trains -> GGUF to Ollama -> bashbros sidekick improves\r\n */\r\n\r\nimport { existsSync, mkdirSync, writeFileSync, readFileSync, watch, FSWatcher } from 'fs'\r\nimport { join } from 'path'\r\nimport { homedir } from 'os'\r\nimport { EventEmitter } from 'events'\r\nimport type { CommandResult, PolicyViolation } from '../types.js'\r\n\r\n// ============================================================================\r\n// Types\r\n// ============================================================================\r\n\r\nexport type CaptureMode = 'everything' | 'successful_only' | 'sidekick_curated'\r\nexport type TrainingTrigger = 'manual' | 'quality_based' | 'scheduled'\r\n\r\nexport interface IntegrationSettings {\r\n version: string\r\n updated_at: string | null\r\n updated_by: string | null\r\n\r\n integration: {\r\n enabled: boolean\r\n linked_at: string | null\r\n }\r\n\r\n capture: {\r\n mode: CaptureMode\r\n auto_stream: boolean\r\n }\r\n\r\n training: {\r\n auto_enabled: boolean\r\n quality_threshold: number\r\n trigger: TrainingTrigger\r\n }\r\n\r\n security: {\r\n bashbros_primary: boolean\r\n policy_path: string | null\r\n }\r\n\r\n model_sync: {\r\n auto_export_ollama: boolean\r\n ollama_model_name: string\r\n notify_on_update: boolean\r\n }\r\n}\r\n\r\nexport interface TraceData {\r\n version: string\r\n metadata: {\r\n user_initial_prompt: string\r\n source_tool: string\r\n task_id?: string\r\n verification_passed: boolean\r\n capture_mode: CaptureMode\r\n session_id: string\r\n }\r\n trace: TraceStep[]\r\n bashbros_extensions: {\r\n security_events: SecurityEvent[]\r\n sidekick_annotations: SidekickAnnotations\r\n }\r\n}\r\n\r\nexport interface TraceStep {\r\n tool_name: string\r\n command: string\r\n output: string\r\n success: boolean\r\n exit_code?: number\r\n timestamp: string\r\n cwd?: string\r\n}\r\n\r\nexport interface SecurityEvent {\r\n type: string\r\n timestamp: string\r\n command?: string\r\n violation?: PolicyViolation\r\n}\r\n\r\nexport interface SidekickAnnotations {\r\n teachable_moment: boolean\r\n complexity: 'easy' | 'medium' | 'hard'\r\n tags?: string[]\r\n}\r\n\r\nexport interface ModelManifest {\r\n latest: string\r\n versions: ModelVersion[]\r\n rollback_available: boolean\r\n}\r\n\r\nexport interface ModelVersion {\r\n version: string\r\n created: string\r\n traces_used: number\r\n quality_avg: number\r\n gguf_path: string | null\r\n}\r\n\r\nexport interface BashgymStatus {\r\n heartbeat: string\r\n version: string\r\n pending_traces: number\r\n processed_traces: number\r\n model_version: string | null\r\n}\r\n\r\n// ============================================================================\r\n// Events\r\n// ============================================================================\r\n\r\nexport interface BashgymIntegrationEvents {\r\n 'model:updated': (version: string, manifest: ModelManifest) => void\r\n 'settings:changed': (settings: IntegrationSettings) => void\r\n 'trace:exported': (filename: string) => void\r\n 'connected': () => void\r\n 'disconnected': () => void\r\n}\r\n\r\n// ============================================================================\r\n// Integration Class\r\n// ============================================================================\r\n\r\nconst DEFAULT_SETTINGS: IntegrationSettings = {\r\n version: '1.0',\r\n updated_at: null,\r\n updated_by: null,\r\n integration: {\r\n enabled: false,\r\n linked_at: null,\r\n },\r\n capture: {\r\n mode: 'successful_only',\r\n auto_stream: true,\r\n },\r\n training: {\r\n auto_enabled: false,\r\n quality_threshold: 50,\r\n trigger: 'quality_based',\r\n },\r\n security: {\r\n bashbros_primary: true,\r\n policy_path: null,\r\n },\r\n model_sync: {\r\n auto_export_ollama: true,\r\n ollama_model_name: 'bashgym-sidekick',\r\n notify_on_update: true,\r\n },\r\n}\r\n\r\nexport class BashgymIntegration extends EventEmitter {\r\n private integrationDir: string\r\n private settings: IntegrationSettings | null = null\r\n private manifest: ModelManifest | null = null\r\n private settingsWatcher: FSWatcher | null = null\r\n private modelWatcher: FSWatcher | null = null\r\n private sessionId: string\r\n private traceBuffer: TraceStep[] = []\r\n private securityEvents: SecurityEvent[] = []\r\n private currentPrompt: string = ''\r\n\r\n // Directory paths\r\n private tracesDir: string\r\n private pendingDir: string\r\n private modelsDir: string\r\n private configDir: string\r\n private statusDir: string\r\n\r\n constructor(integrationDir?: string) {\r\n super()\r\n\r\n this.integrationDir = integrationDir || join(homedir(), '.bashgym', 'integration')\r\n this.tracesDir = join(this.integrationDir, 'traces')\r\n this.pendingDir = join(this.tracesDir, 'pending')\r\n this.modelsDir = join(this.integrationDir, 'models')\r\n this.configDir = join(this.integrationDir, 'config')\r\n this.statusDir = join(this.integrationDir, 'status')\r\n\r\n this.sessionId = `bashbros-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\r\n }\r\n\r\n /**\r\n * Initialize the integration\r\n */\r\n async initialize(): Promise<boolean> {\r\n // Check if bashgym integration directory exists\r\n if (!existsSync(this.integrationDir)) {\r\n return false\r\n }\r\n\r\n // Load settings\r\n this.settings = this.loadSettings()\r\n if (!this.settings?.integration.enabled) {\r\n return false\r\n }\r\n\r\n // Load model manifest\r\n this.manifest = this.loadManifest()\r\n\r\n // Start watching for changes\r\n this.startWatching()\r\n\r\n // Update bashbros status\r\n this.updateStatus()\r\n\r\n this.emit('connected')\r\n return true\r\n }\r\n\r\n /**\r\n * Check if bashgym is available\r\n */\r\n isAvailable(): boolean {\r\n return existsSync(this.integrationDir) && existsSync(this.configDir)\r\n }\r\n\r\n /**\r\n * Check if integration is linked\r\n */\r\n isLinked(): boolean {\r\n const settings = this.getSettings()\r\n return !!(settings?.integration.enabled && settings.integration.linked_at !== null)\r\n }\r\n\r\n // =========================================================================\r\n // Settings Management\r\n // =========================================================================\r\n\r\n getSettings(): IntegrationSettings | null {\r\n if (!this.settings) {\r\n this.settings = this.loadSettings()\r\n }\r\n return this.settings\r\n }\r\n\r\n private loadSettings(): IntegrationSettings | null {\r\n const settingsPath = join(this.configDir, 'settings.json')\r\n\r\n if (!existsSync(settingsPath)) {\r\n return null\r\n }\r\n\r\n try {\r\n const content = readFileSync(settingsPath, 'utf-8')\r\n return JSON.parse(content) as IntegrationSettings\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n updateSettings(updates: Partial<IntegrationSettings>): void {\r\n const current = this.getSettings() || { ...DEFAULT_SETTINGS }\r\n\r\n // Deep merge updates\r\n const updated: IntegrationSettings = {\r\n ...current,\r\n ...updates,\r\n updated_at: new Date().toISOString(),\r\n updated_by: 'bashbros',\r\n }\r\n\r\n // Write to file\r\n const settingsPath = join(this.configDir, 'settings.json')\r\n writeFileSync(settingsPath, JSON.stringify(updated, null, 2))\r\n\r\n this.settings = updated\r\n this.emit('settings:changed', updated)\r\n }\r\n\r\n // =========================================================================\r\n // Trace Export\r\n // =========================================================================\r\n\r\n /**\r\n * Start a new trace session\r\n */\r\n startSession(prompt: string): void {\r\n this.currentPrompt = prompt\r\n this.traceBuffer = []\r\n this.securityEvents = []\r\n }\r\n\r\n /**\r\n * Add a step to the current trace\r\n */\r\n addStep(step: Omit<TraceStep, 'timestamp'>): void {\r\n this.traceBuffer.push({\r\n ...step,\r\n timestamp: new Date().toISOString(),\r\n })\r\n }\r\n\r\n /**\r\n * Add a command result to the trace\r\n */\r\n addCommandResult(result: CommandResult): void {\r\n this.addStep({\r\n tool_name: 'Bash',\r\n command: result.command,\r\n output: result.output || '',\r\n success: result.allowed && !result.error,\r\n exit_code: result.exitCode,\r\n cwd: process.cwd(),\r\n })\r\n\r\n // Track security events\r\n if (result.violations.length > 0) {\r\n this.securityEvents.push({\r\n type: 'violation',\r\n timestamp: new Date().toISOString(),\r\n command: result.command,\r\n violation: result.violations[0],\r\n })\r\n }\r\n }\r\n\r\n /**\r\n * Add a file operation to the trace\r\n */\r\n addFileOperation(operation: 'Read' | 'Write' | 'Edit', path: string, success: boolean, output?: string): void {\r\n this.addStep({\r\n tool_name: operation,\r\n command: path,\r\n output: output || '',\r\n success,\r\n })\r\n }\r\n\r\n /**\r\n * End the session and export the trace\r\n */\r\n async endSession(verificationPassed: boolean = false): Promise<string | null> {\r\n if (!this.currentPrompt || this.traceBuffer.length === 0) {\r\n return null\r\n }\r\n\r\n const settings = this.getSettings()\r\n if (!settings?.integration.enabled) {\r\n return null\r\n }\r\n\r\n // Check capture mode\r\n if (settings.capture.mode === 'successful_only' && !verificationPassed) {\r\n // Don't export failed traces\r\n this.clearSession()\r\n return null\r\n }\r\n\r\n // Build trace data\r\n const traceData: TraceData = {\r\n version: '1.0',\r\n metadata: {\r\n user_initial_prompt: this.currentPrompt,\r\n source_tool: 'bashbros',\r\n session_id: this.sessionId,\r\n verification_passed: verificationPassed,\r\n capture_mode: settings.capture.mode,\r\n },\r\n trace: this.traceBuffer,\r\n bashbros_extensions: {\r\n security_events: this.securityEvents,\r\n sidekick_annotations: {\r\n teachable_moment: this.determineTeachableMoment(),\r\n complexity: this.determineComplexity(),\r\n },\r\n },\r\n }\r\n\r\n // Export to pending directory\r\n const filename = `${Date.now()}-${this.sessionId.slice(-8)}.json`\r\n const filepath = join(this.pendingDir, filename)\r\n\r\n try {\r\n // Ensure directory exists\r\n if (!existsSync(this.pendingDir)) {\r\n mkdirSync(this.pendingDir, { recursive: true })\r\n }\r\n\r\n writeFileSync(filepath, JSON.stringify(traceData, null, 2))\r\n this.emit('trace:exported', filename)\r\n\r\n this.clearSession()\r\n return filename\r\n } catch (error) {\r\n console.error('Failed to export trace:', error)\r\n return null\r\n }\r\n }\r\n\r\n private clearSession(): void {\r\n this.currentPrompt = ''\r\n this.traceBuffer = []\r\n this.securityEvents = []\r\n this.sessionId = `bashbros-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`\r\n }\r\n\r\n private determineTeachableMoment(): boolean {\r\n // Heuristics for identifying teachable moments\r\n // - Session has multiple steps\r\n // - Includes error recovery\r\n // - Uses diverse tools\r\n const hasMultipleSteps = this.traceBuffer.length >= 3\r\n const hasErrorRecovery = this.traceBuffer.some((s, i) =>\r\n !s.success && i < this.traceBuffer.length - 1 && this.traceBuffer[i + 1].success\r\n )\r\n const toolNames = new Set(this.traceBuffer.map(s => s.tool_name))\r\n const hasDiverseTools = toolNames.size >= 2\r\n\r\n return hasMultipleSteps && (hasErrorRecovery || hasDiverseTools)\r\n }\r\n\r\n private determineComplexity(): 'easy' | 'medium' | 'hard' {\r\n const stepCount = this.traceBuffer.length\r\n const toolCount = new Set(this.traceBuffer.map(s => s.tool_name)).size\r\n const hasErrors = this.traceBuffer.some(s => !s.success)\r\n\r\n if (stepCount <= 3 && toolCount <= 2 && !hasErrors) {\r\n return 'easy'\r\n }\r\n\r\n if (stepCount >= 10 || toolCount >= 4 || this.securityEvents.length > 0) {\r\n return 'hard'\r\n }\r\n\r\n return 'medium'\r\n }\r\n\r\n // =========================================================================\r\n // Model Management\r\n // =========================================================================\r\n\r\n /**\r\n * Get current model version\r\n */\r\n getCurrentModelVersion(): string | null {\r\n const manifest = this.loadManifest()\r\n return manifest?.latest || null\r\n }\r\n\r\n /**\r\n * Get model manifest\r\n */\r\n getModelManifest(): ModelManifest | null {\r\n return this.manifest || this.loadManifest()\r\n }\r\n\r\n private loadManifest(): ModelManifest | null {\r\n const manifestPath = join(this.modelsDir, 'manifest.json')\r\n\r\n if (!existsSync(manifestPath)) {\r\n return null\r\n }\r\n\r\n try {\r\n const content = readFileSync(manifestPath, 'utf-8')\r\n return JSON.parse(content) as ModelManifest\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n /**\r\n * Get path to latest GGUF model\r\n */\r\n getLatestModelPath(): string | null {\r\n const latestPath = join(this.modelsDir, 'latest', 'sidekick.gguf')\r\n\r\n if (existsSync(latestPath)) {\r\n return latestPath\r\n }\r\n\r\n return null\r\n }\r\n\r\n /**\r\n * Get Ollama model name for sidekick\r\n */\r\n getOllamaModelName(): string {\r\n const settings = this.getSettings()\r\n return settings?.model_sync.ollama_model_name || 'bashgym-sidekick'\r\n }\r\n\r\n // =========================================================================\r\n // File Watching\r\n // =========================================================================\r\n\r\n private startWatching(): void {\r\n // Watch settings file\r\n const settingsPath = join(this.configDir, 'settings.json')\r\n if (existsSync(settingsPath)) {\r\n try {\r\n this.settingsWatcher = watch(settingsPath, (eventType) => {\r\n if (eventType === 'change') {\r\n const newSettings = this.loadSettings()\r\n if (newSettings) {\r\n this.settings = newSettings\r\n this.emit('settings:changed', newSettings)\r\n }\r\n }\r\n })\r\n } catch {\r\n // Watching may not be supported\r\n }\r\n }\r\n\r\n // Watch model manifest\r\n const manifestPath = join(this.modelsDir, 'manifest.json')\r\n if (existsSync(manifestPath)) {\r\n try {\r\n this.modelWatcher = watch(manifestPath, (eventType) => {\r\n if (eventType === 'change') {\r\n const oldVersion = this.manifest?.latest\r\n const newManifest = this.loadManifest()\r\n\r\n if (newManifest && newManifest.latest !== oldVersion) {\r\n this.manifest = newManifest\r\n this.emit('model:updated', newManifest.latest, newManifest)\r\n }\r\n }\r\n })\r\n } catch {\r\n // Watching may not be supported\r\n }\r\n }\r\n }\r\n\r\n stopWatching(): void {\r\n if (this.settingsWatcher) {\r\n this.settingsWatcher.close()\r\n this.settingsWatcher = null\r\n }\r\n\r\n if (this.modelWatcher) {\r\n this.modelWatcher.close()\r\n this.modelWatcher = null\r\n }\r\n }\r\n\r\n // =========================================================================\r\n // Status Management\r\n // =========================================================================\r\n\r\n private updateStatus(): void {\r\n const statusPath = join(this.statusDir, 'bashbros.json')\r\n\r\n const status = {\r\n heartbeat: new Date().toISOString(),\r\n version: '1.0',\r\n session_id: this.sessionId,\r\n active: true,\r\n }\r\n\r\n try {\r\n if (!existsSync(this.statusDir)) {\r\n mkdirSync(this.statusDir, { recursive: true })\r\n }\r\n writeFileSync(statusPath, JSON.stringify(status, null, 2))\r\n } catch {\r\n // Status update failed - non-critical\r\n }\r\n }\r\n\r\n /**\r\n * Check if bashgym is actively running\r\n */\r\n isBashgymRunning(): boolean {\r\n const statusPath = join(this.statusDir, 'bashgym.json')\r\n\r\n if (!existsSync(statusPath)) {\r\n return false\r\n }\r\n\r\n try {\r\n const content = readFileSync(statusPath, 'utf-8')\r\n const status = JSON.parse(content) as BashgymStatus\r\n\r\n // Check if heartbeat is recent (within 5 minutes)\r\n const heartbeat = new Date(status.heartbeat)\r\n const age = Date.now() - heartbeat.getTime()\r\n\r\n return age < 5 * 60 * 1000\r\n } catch {\r\n return false\r\n }\r\n }\r\n\r\n // =========================================================================\r\n // Cleanup\r\n // =========================================================================\r\n\r\n dispose(): void {\r\n this.stopWatching()\r\n this.emit('disconnected')\r\n }\r\n}\r\n\r\n// ============================================================================\r\n// Singleton Instance\r\n// ============================================================================\r\n\r\nlet _integration: BashgymIntegration | null = null\r\n\r\nexport function getBashgymIntegration(): BashgymIntegration {\r\n if (!_integration) {\r\n _integration = new BashgymIntegration()\r\n }\r\n return _integration\r\n}\r\n\r\nexport function resetBashgymIntegration(): void {\r\n if (_integration) {\r\n _integration.dispose()\r\n }\r\n _integration = null\r\n}\r\n","import * as pty from 'node-pty'\r\nimport { EventEmitter } from 'events'\r\nimport type { BashBrosConfig, CommandResult, PolicyViolation } from './types.js'\r\nimport { PolicyEngine } from './policy/engine.js'\r\nimport { AuditLogger } from './audit.js'\r\nimport { loadConfig } from './config.js'\r\n\r\nexport interface BashBrosEvents {\r\n command: (command: string) => void\r\n allowed: (result: CommandResult) => void\r\n blocked: (command: string, violations: PolicyViolation[]) => void\r\n output: (data: string) => void\r\n error: (error: Error) => void\r\n}\r\n\r\nexport class BashBros extends EventEmitter {\r\n private config: BashBrosConfig\r\n private policy: PolicyEngine\r\n private audit: AuditLogger\r\n private ptyProcess: pty.IPty | null = null\r\n private shell: string\r\n private pendingCommand: string = ''\r\n private commandStartTime: number = 0\r\n\r\n constructor(configPath?: string) {\r\n super()\r\n this.config = loadConfig(configPath)\r\n this.policy = new PolicyEngine(this.config)\r\n this.audit = new AuditLogger(this.config.audit)\r\n this.shell = process.platform === 'win32' ? 'powershell.exe' : 'bash'\r\n }\r\n\r\n start(): void {\r\n this.ptyProcess = pty.spawn(this.shell, [], {\r\n name: 'xterm-color',\r\n cols: 80,\r\n rows: 30,\r\n cwd: process.cwd(),\r\n env: process.env as { [key: string]: string }\r\n })\r\n\r\n this.ptyProcess.onData((data: string) => {\r\n this.emit('output', data)\r\n })\r\n\r\n this.ptyProcess.onExit(({ exitCode }) => {\r\n this.emit('exit', exitCode)\r\n })\r\n }\r\n\r\n execute(command: string): CommandResult {\r\n const startTime = Date.now()\r\n const violations = this.policy.validate(command)\r\n\r\n if (violations.length > 0) {\r\n const result: CommandResult = {\r\n command,\r\n allowed: false,\r\n duration: Date.now() - startTime,\r\n violations\r\n }\r\n\r\n this.audit.log({\r\n timestamp: new Date(),\r\n command,\r\n allowed: false,\r\n violations,\r\n duration: result.duration,\r\n agent: this.config.agent\r\n })\r\n\r\n this.emit('blocked', command, violations)\r\n return result\r\n }\r\n\r\n // Command is allowed - execute it\r\n this.commandStartTime = startTime\r\n this.pendingCommand = command\r\n\r\n if (this.ptyProcess) {\r\n this.ptyProcess.write(command + '\\r')\r\n }\r\n\r\n const result: CommandResult = {\r\n command,\r\n allowed: true,\r\n duration: Date.now() - startTime,\r\n violations: []\r\n }\r\n\r\n this.audit.log({\r\n timestamp: new Date(),\r\n command,\r\n allowed: true,\r\n violations: [],\r\n duration: result.duration,\r\n agent: this.config.agent\r\n })\r\n\r\n this.emit('allowed', result)\r\n return result\r\n }\r\n\r\n validateOnly(command: string): PolicyViolation[] {\r\n return this.policy.validate(command)\r\n }\r\n\r\n isAllowed(command: string): boolean {\r\n return this.policy.isAllowed(command)\r\n }\r\n\r\n resize(cols: number, rows: number): void {\r\n if (this.ptyProcess) {\r\n this.ptyProcess.resize(cols, rows)\r\n }\r\n }\r\n\r\n write(data: string): void {\r\n if (this.ptyProcess) {\r\n this.ptyProcess.write(data)\r\n }\r\n }\r\n\r\n stop(): void {\r\n if (this.ptyProcess) {\r\n this.ptyProcess.kill()\r\n this.ptyProcess = null\r\n }\r\n }\r\n\r\n getConfig(): BashBrosConfig {\r\n return this.config\r\n }\r\n}\r\n","/**\r\n * Loop Detection\r\n * Detects when agents get stuck in repetitive patterns\r\n */\r\n\r\nexport interface LoopConfig {\r\n maxRepeats: number // Same command N times triggers alert\r\n maxTurns: number // Total commands before hard stop\r\n similarityThreshold: number // 0-1, how similar commands must be\r\n cooldownMs: number // Min time between identical commands\r\n windowSize: number // Commands to look back\r\n}\r\n\r\nexport interface LoopAlert {\r\n type: 'exact_repeat' | 'semantic_repeat' | 'tool_hammering' | 'max_turns'\r\n command: string\r\n count: number\r\n message: string\r\n}\r\n\r\ninterface CommandEntry {\r\n command: string\r\n timestamp: number\r\n normalized: string\r\n}\r\n\r\nconst DEFAULT_CONFIG: LoopConfig = {\r\n maxRepeats: 3,\r\n maxTurns: 100,\r\n similarityThreshold: 0.85,\r\n cooldownMs: 1000,\r\n windowSize: 20\r\n}\r\n\r\nexport class LoopDetector {\r\n private config: LoopConfig\r\n private history: CommandEntry[] = []\r\n private turnCount: number = 0\r\n\r\n constructor(config: Partial<LoopConfig> = {}) {\r\n this.config = { ...DEFAULT_CONFIG, ...config }\r\n }\r\n\r\n /**\r\n * Record a command and check for loops\r\n */\r\n check(command: string): LoopAlert | null {\r\n const now = Date.now()\r\n const normalized = this.normalize(command)\r\n\r\n this.turnCount++\r\n\r\n // Check max turns first\r\n if (this.turnCount >= this.config.maxTurns) {\r\n return {\r\n type: 'max_turns',\r\n command,\r\n count: this.turnCount,\r\n message: `Maximum turns reached (${this.config.maxTurns}). Session may be stuck.`\r\n }\r\n }\r\n\r\n // Check for exact repeats\r\n const exactMatches = this.history.filter(h => h.command === command)\r\n if (exactMatches.length >= this.config.maxRepeats) {\r\n return {\r\n type: 'exact_repeat',\r\n command,\r\n count: exactMatches.length + 1,\r\n message: `Command repeated ${exactMatches.length + 1} times: \"${command.slice(0, 50)}...\"`\r\n }\r\n }\r\n\r\n // Check cooldown (same command too fast)\r\n const lastSame = exactMatches[exactMatches.length - 1]\r\n if (lastSame && (now - lastSame.timestamp) < this.config.cooldownMs) {\r\n return {\r\n type: 'exact_repeat',\r\n command,\r\n count: 2,\r\n message: `Rapid repeat detected (${now - lastSame.timestamp}ms apart)`\r\n }\r\n }\r\n\r\n // Check for semantic repeats (similar commands)\r\n const recentWindow = this.history.slice(-this.config.windowSize)\r\n const similarCount = recentWindow.filter(h =>\r\n this.similarity(h.normalized, normalized) >= this.config.similarityThreshold\r\n ).length\r\n\r\n if (similarCount >= this.config.maxRepeats) {\r\n return {\r\n type: 'semantic_repeat',\r\n command,\r\n count: similarCount + 1,\r\n message: `Similar commands repeated ${similarCount + 1} times`\r\n }\r\n }\r\n\r\n // Check for tool hammering (same base command)\r\n const baseCommand = command.split(/\\s+/)[0]\r\n const toolCount = recentWindow.filter(h =>\r\n h.command.split(/\\s+/)[0] === baseCommand\r\n ).length\r\n\r\n if (toolCount >= this.config.maxRepeats * 2) {\r\n return {\r\n type: 'tool_hammering',\r\n command,\r\n count: toolCount + 1,\r\n message: `Tool \"${baseCommand}\" called ${toolCount + 1} times in last ${this.config.windowSize} commands`\r\n }\r\n }\r\n\r\n // Record this command\r\n this.history.push({ command, timestamp: now, normalized })\r\n\r\n // Trim history\r\n if (this.history.length > this.config.windowSize * 2) {\r\n this.history = this.history.slice(-this.config.windowSize)\r\n }\r\n\r\n return null\r\n }\r\n\r\n /**\r\n * Normalize command for comparison\r\n */\r\n private normalize(command: string): string {\r\n return command\r\n .toLowerCase()\r\n .replace(/[\"']/g, '') // Remove quotes\r\n .replace(/\\s+/g, ' ') // Normalize whitespace\r\n .replace(/\\d+/g, 'N') // Replace numbers\r\n .replace(/[a-f0-9]{8,}/gi, 'H') // Replace hashes\r\n .trim()\r\n }\r\n\r\n /**\r\n * Calculate similarity between two strings (Jaccard index on words)\r\n */\r\n private similarity(a: string, b: string): number {\r\n const wordsA = new Set(a.split(/\\s+/))\r\n const wordsB = new Set(b.split(/\\s+/))\r\n\r\n const intersection = new Set([...wordsA].filter(x => wordsB.has(x)))\r\n const union = new Set([...wordsA, ...wordsB])\r\n\r\n if (union.size === 0) return 1\r\n return intersection.size / union.size\r\n }\r\n\r\n /**\r\n * Get current turn count\r\n */\r\n getTurnCount(): number {\r\n return this.turnCount\r\n }\r\n\r\n /**\r\n * Get command frequency map\r\n */\r\n getFrequencyMap(): Map<string, number> {\r\n const freq = new Map<string, number>()\r\n for (const entry of this.history) {\r\n const base = entry.command.split(/\\s+/)[0]\r\n freq.set(base, (freq.get(base) || 0) + 1)\r\n }\r\n return freq\r\n }\r\n\r\n /**\r\n * Reset detector state\r\n */\r\n reset(): void {\r\n this.history = []\r\n this.turnCount = 0\r\n }\r\n\r\n /**\r\n * Get stats for reporting\r\n */\r\n getStats(): {\r\n turnCount: number\r\n uniqueCommands: number\r\n topCommands: [string, number][]\r\n } {\r\n const freq = this.getFrequencyMap()\r\n const sorted = [...freq.entries()].sort((a, b) => b[1] - a[1])\r\n\r\n return {\r\n turnCount: this.turnCount,\r\n uniqueCommands: freq.size,\r\n topCommands: sorted.slice(0, 5)\r\n }\r\n }\r\n}\r\n","/**\r\n * Anomaly Detection\r\n * Flag unusual patterns without ML\r\n */\r\n\r\nexport interface AnomalyConfig {\r\n workingHours?: [number, number] // [startHour, endHour] in 24h format\r\n typicalCommandsPerMinute?: number // Normal rate\r\n knownPaths?: string[] // Expected paths for this project\r\n suspiciousPatterns?: RegExp[] // Additional patterns to flag\r\n enabled?: boolean\r\n}\r\n\r\nexport interface Anomaly {\r\n type: 'timing' | 'frequency' | 'path' | 'pattern' | 'behavior'\r\n severity: 'info' | 'warning' | 'alert'\r\n message: string\r\n details: Record<string, unknown>\r\n}\r\n\r\ninterface CommandRecord {\r\n command: string\r\n timestamp: number\r\n path?: string\r\n}\r\n\r\nconst DEFAULT_CONFIG: Required<AnomalyConfig> = {\r\n workingHours: [6, 22], // 6 AM to 10 PM\r\n typicalCommandsPerMinute: 30,\r\n knownPaths: [],\r\n suspiciousPatterns: [],\r\n enabled: true\r\n}\r\n\r\n// Default suspicious patterns\r\nconst DEFAULT_SUSPICIOUS_PATTERNS: RegExp[] = [\r\n /\\bpasswd\\b/,\r\n /\\bshadow\\b/,\r\n /\\/root\\//,\r\n /\\.ssh\\//,\r\n /\\.gnupg\\//,\r\n /\\.aws\\//,\r\n /\\.kube\\//,\r\n /wallet/i,\r\n /crypto/i,\r\n /bitcoin/i,\r\n /ethereum/i,\r\n /private.*key/i,\r\n]\r\n\r\nexport class AnomalyDetector {\r\n private config: Required<AnomalyConfig>\r\n private commands: CommandRecord[] = []\r\n private baselinePaths: Set<string> = new Set()\r\n private baselineCommands: Set<string> = new Set()\r\n private learningMode: boolean = true\r\n private learningCount: number = 0\r\n private readonly LEARNING_THRESHOLD = 50\r\n\r\n constructor(config: AnomalyConfig = {}) {\r\n this.config = { ...DEFAULT_CONFIG, ...config }\r\n }\r\n\r\n /**\r\n * Check a command for anomalies\r\n */\r\n check(command: string, cwd?: string): Anomaly[] {\r\n if (!this.config.enabled) return []\r\n\r\n const anomalies: Anomaly[] = []\r\n const now = Date.now()\r\n\r\n // Record for learning/baseline\r\n this.commands.push({ command, timestamp: now, path: cwd })\r\n if (this.commands.length > 1000) {\r\n this.commands = this.commands.slice(-500)\r\n }\r\n\r\n // Learning mode: build baseline\r\n if (this.learningMode) {\r\n this.learn(command, cwd)\r\n if (this.learningCount >= this.LEARNING_THRESHOLD) {\r\n this.learningMode = false\r\n }\r\n return anomalies // Don't flag during learning\r\n }\r\n\r\n // Check timing\r\n const timingAnomaly = this.checkTiming(now)\r\n if (timingAnomaly) anomalies.push(timingAnomaly)\r\n\r\n // Check frequency\r\n const freqAnomaly = this.checkFrequency(now)\r\n if (freqAnomaly) anomalies.push(freqAnomaly)\r\n\r\n // Check paths\r\n if (cwd) {\r\n const pathAnomaly = this.checkPath(cwd)\r\n if (pathAnomaly) anomalies.push(pathAnomaly)\r\n }\r\n\r\n // Check patterns\r\n const patternAnomalies = this.checkPatterns(command)\r\n anomalies.push(...patternAnomalies)\r\n\r\n // Check behavior\r\n const behaviorAnomaly = this.checkBehavior(command)\r\n if (behaviorAnomaly) anomalies.push(behaviorAnomaly)\r\n\r\n return anomalies\r\n }\r\n\r\n /**\r\n * Learn from command (build baseline)\r\n */\r\n private learn(command: string, cwd?: string): void {\r\n this.learningCount++\r\n\r\n // Learn command patterns\r\n const baseCmd = command.split(/\\s+/)[0]\r\n this.baselineCommands.add(baseCmd)\r\n\r\n // Learn paths\r\n if (cwd) {\r\n this.baselinePaths.add(cwd)\r\n // Also add parent directories\r\n const parts = cwd.split(/[/\\\\]/)\r\n for (let i = 1; i <= parts.length; i++) {\r\n this.baselinePaths.add(parts.slice(0, i).join('/'))\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Check for timing anomalies\r\n */\r\n private checkTiming(now: number): Anomaly | null {\r\n const hour = new Date(now).getHours()\r\n const [start, end] = this.config.workingHours\r\n\r\n if (hour < start || hour >= end) {\r\n return {\r\n type: 'timing',\r\n severity: 'info',\r\n message: `Activity outside normal hours (${hour}:00)`,\r\n details: { hour, workingHours: this.config.workingHours }\r\n }\r\n }\r\n\r\n return null\r\n }\r\n\r\n /**\r\n * Check for frequency anomalies\r\n */\r\n private checkFrequency(now: number): Anomaly | null {\r\n const oneMinuteAgo = now - 60000\r\n const recentCommands = this.commands.filter(c => c.timestamp > oneMinuteAgo)\r\n const rate = recentCommands.length\r\n\r\n if (rate > this.config.typicalCommandsPerMinute * 2) {\r\n return {\r\n type: 'frequency',\r\n severity: 'warning',\r\n message: `High command rate: ${rate}/min (typical: ${this.config.typicalCommandsPerMinute})`,\r\n details: { rate, typical: this.config.typicalCommandsPerMinute }\r\n }\r\n }\r\n\r\n // Check for burst (many commands in very short time)\r\n const fiveSecondsAgo = now - 5000\r\n const burstCommands = this.commands.filter(c => c.timestamp > fiveSecondsAgo)\r\n if (burstCommands.length > 10) {\r\n return {\r\n type: 'frequency',\r\n severity: 'alert',\r\n message: `Burst detected: ${burstCommands.length} commands in 5 seconds`,\r\n details: { count: burstCommands.length, window: '5s' }\r\n }\r\n }\r\n\r\n return null\r\n }\r\n\r\n /**\r\n * Check for unusual path access\r\n */\r\n private checkPath(path: string): Anomaly | null {\r\n // Skip if we have known paths configured\r\n if (this.config.knownPaths.length > 0) {\r\n const isKnown = this.config.knownPaths.some(p =>\r\n path.startsWith(p) || path.includes(p)\r\n )\r\n if (!isKnown) {\r\n return {\r\n type: 'path',\r\n severity: 'warning',\r\n message: `Access to unexpected path: ${path}`,\r\n details: { path, knownPaths: this.config.knownPaths }\r\n }\r\n }\r\n }\r\n\r\n // Check against learned baseline\r\n if (!this.learningMode && this.baselinePaths.size > 0) {\r\n const isBaseline = this.baselinePaths.has(path) ||\r\n [...this.baselinePaths].some(p => path.startsWith(p))\r\n\r\n if (!isBaseline) {\r\n return {\r\n type: 'path',\r\n severity: 'info',\r\n message: `New path accessed: ${path}`,\r\n details: { path, isNew: true }\r\n }\r\n }\r\n }\r\n\r\n return null\r\n }\r\n\r\n /**\r\n * Check for suspicious patterns\r\n */\r\n private checkPatterns(command: string): Anomaly[] {\r\n const anomalies: Anomaly[] = []\r\n const allPatterns = [...DEFAULT_SUSPICIOUS_PATTERNS, ...this.config.suspiciousPatterns]\r\n\r\n for (const pattern of allPatterns) {\r\n if (pattern.test(command)) {\r\n anomalies.push({\r\n type: 'pattern',\r\n severity: 'warning',\r\n message: `Suspicious pattern detected: ${pattern.source}`,\r\n details: { command: command.slice(0, 100), pattern: pattern.source }\r\n })\r\n }\r\n }\r\n\r\n return anomalies\r\n }\r\n\r\n /**\r\n * Check for behavioral anomalies\r\n */\r\n private checkBehavior(command: string): Anomaly | null {\r\n const baseCmd = command.split(/\\s+/)[0]\r\n\r\n // Check for new command type after learning\r\n if (!this.learningMode && this.baselineCommands.size > 0) {\r\n if (!this.baselineCommands.has(baseCmd)) {\r\n // Only flag if it's potentially sensitive\r\n const sensitiveCommands = new Set([\r\n 'curl', 'wget', 'nc', 'netcat', 'ssh', 'scp', 'rsync',\r\n 'sudo', 'su', 'chmod', 'chown', 'mount', 'umount'\r\n ])\r\n\r\n if (sensitiveCommands.has(baseCmd)) {\r\n return {\r\n type: 'behavior',\r\n severity: 'warning',\r\n message: `New sensitive command type: ${baseCmd}`,\r\n details: { command: baseCmd, isNew: true }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return null\r\n }\r\n\r\n /**\r\n * Get anomaly stats\r\n */\r\n getStats(): {\r\n learningMode: boolean\r\n learningProgress: number\r\n baselineCommands: number\r\n baselinePaths: number\r\n recentCommandRate: number\r\n } {\r\n const now = Date.now()\r\n const oneMinuteAgo = now - 60000\r\n const recentRate = this.commands.filter(c => c.timestamp > oneMinuteAgo).length\r\n\r\n return {\r\n learningMode: this.learningMode,\r\n learningProgress: Math.min(100, Math.round((this.learningCount / this.LEARNING_THRESHOLD) * 100)),\r\n baselineCommands: this.baselineCommands.size,\r\n baselinePaths: this.baselinePaths.size,\r\n recentCommandRate: recentRate\r\n }\r\n }\r\n\r\n /**\r\n * Force end learning mode\r\n */\r\n endLearning(): void {\r\n this.learningMode = false\r\n }\r\n\r\n /**\r\n * Reset and restart learning\r\n */\r\n reset(): void {\r\n this.commands = []\r\n this.baselinePaths.clear()\r\n this.baselineCommands.clear()\r\n this.learningMode = true\r\n this.learningCount = 0\r\n }\r\n}\r\n","/**\r\n * Output Scanner\r\n * Scan command output for leaked secrets and sensitive data\r\n */\r\n\r\nimport type { OutputScanningPolicy } from '../types.js'\r\n\r\nexport interface ScanResult {\r\n hasSecrets: boolean\r\n hasErrors: boolean\r\n redactedOutput: string\r\n findings: Finding[]\r\n}\r\n\r\nexport interface Finding {\r\n type: 'secret' | 'error' | 'sensitive'\r\n pattern: string\r\n message: string\r\n line?: number\r\n}\r\n\r\n// Built-in secret patterns\r\nconst SECRET_PATTERNS: { pattern: RegExp; name: string }[] = [\r\n // API Keys\r\n { pattern: /sk-[A-Za-z0-9]{20,}/, name: 'OpenAI API Key' },\r\n { pattern: /sk-ant-[A-Za-z0-9\\-]{20,}/, name: 'Anthropic API Key' },\r\n { pattern: /ghp_[A-Za-z0-9]{36}/, name: 'GitHub Token' },\r\n { pattern: /gho_[A-Za-z0-9]{36}/, name: 'GitHub OAuth Token' },\r\n { pattern: /github_pat_[A-Za-z0-9_]{22,}/, name: 'GitHub PAT' },\r\n { pattern: /glpat-[A-Za-z0-9\\-]{20,}/, name: 'GitLab Token' },\r\n { pattern: /xox[baprs]-[A-Za-z0-9\\-]{10,}/, name: 'Slack Token' },\r\n { pattern: /sk_live_[A-Za-z0-9]{24,}/, name: 'Stripe Secret Key' },\r\n { pattern: /sq0atp-[A-Za-z0-9\\-_]{22,}/, name: 'Square Token' },\r\n { pattern: /AKIA[A-Z0-9]{16}/, name: 'AWS Access Key' },\r\n { pattern: /amzn\\.mws\\.[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/, name: 'Amazon MWS Key' },\r\n\r\n // OAuth/JWT\r\n { pattern: /Bearer\\s+[A-Za-z0-9\\-._~+/]+=*/, name: 'Bearer Token' },\r\n { pattern: /eyJ[A-Za-z0-9\\-_]+\\.eyJ[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+/, name: 'JWT Token' },\r\n\r\n // Credentials in output\r\n { pattern: /password\\s*[=:]\\s*['\"]?[^\\s'\"]{4,}['\"]?/i, name: 'Password' },\r\n { pattern: /passwd\\s*[=:]\\s*['\"]?[^\\s'\"]{4,}['\"]?/i, name: 'Password' },\r\n { pattern: /api[_-]?key\\s*[=:]\\s*['\"]?[^\\s'\"]{8,}['\"]?/i, name: 'API Key' },\r\n { pattern: /secret\\s*[=:]\\s*['\"]?[^\\s'\"]{8,}['\"]?/i, name: 'Secret' },\r\n { pattern: /token\\s*[=:]\\s*['\"]?[^\\s'\"]{8,}['\"]?/i, name: 'Token' },\r\n\r\n // Private keys\r\n { pattern: /-----BEGIN\\s+(RSA\\s+)?PRIVATE\\s+KEY-----/, name: 'Private Key' },\r\n { pattern: /-----BEGIN\\s+EC\\s+PRIVATE\\s+KEY-----/, name: 'EC Private Key' },\r\n { pattern: /-----BEGIN\\s+OPENSSH\\s+PRIVATE\\s+KEY-----/, name: 'SSH Private Key' },\r\n { pattern: /-----BEGIN\\s+PGP\\s+PRIVATE\\s+KEY\\s+BLOCK-----/, name: 'PGP Private Key' },\r\n\r\n // Database URLs\r\n { pattern: /mongodb(\\+srv)?:\\/\\/[^:]+:[^@]+@/, name: 'MongoDB Connection String' },\r\n { pattern: /postgres(ql)?:\\/\\/[^:]+:[^@]+@/, name: 'PostgreSQL Connection String' },\r\n { pattern: /mysql:\\/\\/[^:]+:[^@]+@/, name: 'MySQL Connection String' },\r\n { pattern: /redis:\\/\\/[^:]+:[^@]+@/, name: 'Redis Connection String' },\r\n\r\n // SSH\r\n { pattern: /ssh-rsa\\s+[A-Za-z0-9+/]+[=]{0,2}/, name: 'SSH Public Key' },\r\n { pattern: /ssh-ed25519\\s+[A-Za-z0-9+/]+/, name: 'SSH ED25519 Key' },\r\n]\r\n\r\n// Error patterns to detect\r\nconst ERROR_PATTERNS: { pattern: RegExp; name: string }[] = [\r\n { pattern: /EACCES|EPERM|permission denied/i, name: 'Permission Error' },\r\n { pattern: /ENOENT|no such file|not found/i, name: 'File Not Found' },\r\n { pattern: /ECONNREFUSED|connection refused/i, name: 'Connection Refused' },\r\n { pattern: /ETIMEDOUT|timed out/i, name: 'Timeout Error' },\r\n { pattern: /segmentation fault|core dumped/i, name: 'Crash' },\r\n { pattern: /out of memory|OOM|cannot allocate/i, name: 'Memory Error' },\r\n { pattern: /stack trace|traceback|at\\s+\\S+:\\d+:\\d+/i, name: 'Stack Trace' },\r\n { pattern: /error:|fatal:|failed:/i, name: 'Error Message' },\r\n]\r\n\r\nexport class OutputScanner {\r\n private secretPatterns: RegExp[]\r\n private redactPatterns: RegExp[]\r\n private policy: OutputScanningPolicy\r\n\r\n constructor(policy: OutputScanningPolicy) {\r\n this.policy = policy\r\n\r\n // Compile secret patterns\r\n this.secretPatterns = SECRET_PATTERNS.map(p => p.pattern)\r\n\r\n // Compile custom redact patterns\r\n this.redactPatterns = (policy.redactPatterns || [])\r\n .map(p => {\r\n try {\r\n return new RegExp(p, 'gi')\r\n } catch {\r\n return null\r\n }\r\n })\r\n .filter((p): p is RegExp => p !== null)\r\n }\r\n\r\n /**\r\n * Scan output for secrets and sensitive data\r\n */\r\n scan(output: string): ScanResult {\r\n if (!this.policy.enabled) {\r\n return {\r\n hasSecrets: false,\r\n hasErrors: false,\r\n redactedOutput: output,\r\n findings: []\r\n }\r\n }\r\n\r\n const findings: Finding[] = []\r\n let hasSecrets = false\r\n let hasErrors = false\r\n\r\n // Truncate if needed\r\n let processedOutput = output\r\n if (output.length > this.policy.maxOutputLength) {\r\n processedOutput = output.slice(0, this.policy.maxOutputLength) + '\\n... [truncated]'\r\n }\r\n\r\n // Scan for secrets\r\n if (this.policy.scanForSecrets) {\r\n const secretFindings = this.scanForSecrets(processedOutput)\r\n if (secretFindings.length > 0) {\r\n hasSecrets = true\r\n findings.push(...secretFindings)\r\n }\r\n }\r\n\r\n // Scan for errors\r\n if (this.policy.scanForErrors) {\r\n const errorFindings = this.scanForErrors(processedOutput)\r\n if (errorFindings.length > 0) {\r\n hasErrors = true\r\n findings.push(...errorFindings)\r\n }\r\n }\r\n\r\n // Redact sensitive data\r\n const redactedOutput = this.redact(processedOutput)\r\n\r\n return {\r\n hasSecrets,\r\n hasErrors,\r\n redactedOutput,\r\n findings\r\n }\r\n }\r\n\r\n /**\r\n * Scan for secrets in output\r\n */\r\n private scanForSecrets(output: string): Finding[] {\r\n const findings: Finding[] = []\r\n const lines = output.split('\\n')\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i]\r\n\r\n for (const { pattern, name } of SECRET_PATTERNS) {\r\n if (pattern.test(line)) {\r\n findings.push({\r\n type: 'secret',\r\n pattern: name,\r\n message: `Potential ${name} found in output`,\r\n line: i + 1\r\n })\r\n }\r\n }\r\n }\r\n\r\n return findings\r\n }\r\n\r\n /**\r\n * Scan for error patterns in output\r\n */\r\n private scanForErrors(output: string): Finding[] {\r\n const findings: Finding[] = []\r\n const lines = output.split('\\n')\r\n\r\n for (let i = 0; i < lines.length; i++) {\r\n const line = lines[i]\r\n\r\n for (const { pattern, name } of ERROR_PATTERNS) {\r\n if (pattern.test(line)) {\r\n findings.push({\r\n type: 'error',\r\n pattern: name,\r\n message: `${name} detected`,\r\n line: i + 1\r\n })\r\n break // Only report first error type per line\r\n }\r\n }\r\n }\r\n\r\n return findings\r\n }\r\n\r\n /**\r\n * Redact sensitive data from output\r\n */\r\n redact(output: string): string {\r\n let redacted = output\r\n\r\n // Redact built-in secret patterns\r\n for (const { pattern, name } of SECRET_PATTERNS) {\r\n redacted = redacted.replace(new RegExp(pattern.source, 'g'), `[REDACTED ${name}]`)\r\n }\r\n\r\n // Redact custom patterns\r\n for (const pattern of this.redactPatterns) {\r\n redacted = redacted.replace(pattern, '[REDACTED]')\r\n }\r\n\r\n return redacted\r\n }\r\n\r\n /**\r\n * Check if output contains any secrets\r\n */\r\n hasSecrets(output: string): boolean {\r\n for (const pattern of this.secretPatterns) {\r\n if (pattern.test(output)) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n /**\r\n * Get summary of findings\r\n */\r\n static summarize(findings: Finding[]): string {\r\n if (findings.length === 0) {\r\n return 'No issues found'\r\n }\r\n\r\n const secrets = findings.filter(f => f.type === 'secret')\r\n const errors = findings.filter(f => f.type === 'error')\r\n\r\n const parts: string[] = []\r\n if (secrets.length > 0) {\r\n parts.push(`${secrets.length} potential secret(s)`)\r\n }\r\n if (errors.length > 0) {\r\n parts.push(`${errors.length} error(s)`)\r\n }\r\n\r\n return parts.join(', ')\r\n }\r\n}\r\n","import { execFileSync, execSync } from 'child_process'\nimport { existsSync, readFileSync, realpathSync } from 'fs'\nimport { homedir, platform, arch, cpus, totalmem } from 'os'\nimport { join } from 'path'\n\nexport interface SystemProfile {\n // System basics\n platform: string\n arch: string\n shell: string\n cpuCores: number\n memoryGB: number\n\n // Languages & runtimes\n python: VersionInfo | null\n node: VersionInfo | null\n rust: VersionInfo | null\n go: VersionInfo | null\n java: VersionInfo | null\n ruby: VersionInfo | null\n\n // Package managers\n npm: VersionInfo | null\n pnpm: VersionInfo | null\n yarn: VersionInfo | null\n pip: VersionInfo | null\n cargo: VersionInfo | null\n brew: VersionInfo | null\n\n // Dev tools\n git: VersionInfo | null\n docker: VersionInfo | null\n kubectl: VersionInfo | null\n aws: VersionInfo | null\n gcloud: VersionInfo | null\n\n // AI tools\n claude: boolean\n clawdbot: boolean\n aider: boolean\n ollama: OllamaInfo | null\n\n // Project context (updated per-project)\n projectType: string | null\n projectDeps: string[]\n envVars: string[] // Names only, not values\n\n // User patterns (learned over time)\n commonCommands: CommandPattern[]\n workingHours: string | null\n preferredEditor: string | null\n\n // Last updated\n timestamp: Date\n}\n\nexport interface VersionInfo {\n version: string\n path: string\n}\n\nexport interface OllamaInfo {\n version: string\n models: string[]\n}\n\nexport interface CommandPattern {\n command: string\n frequency: number\n lastUsed: Date\n}\n\n// Allowlist of safe commands to probe\nconst SAFE_VERSION_COMMANDS: Record<string, string[]> = {\n python: ['--version'],\n python3: ['--version'],\n node: ['--version'],\n rustc: ['--version'],\n go: ['version'],\n java: ['-version'],\n ruby: ['--version'],\n npm: ['--version'],\n pnpm: ['--version'],\n yarn: ['--version'],\n pip: ['--version'],\n pip3: ['--version'],\n cargo: ['--version'],\n brew: ['--version'],\n git: ['--version'],\n docker: ['--version'],\n kubectl: ['version', '--client', '--short'],\n aws: ['--version'],\n gcloud: ['--version'],\n ollama: ['--version'],\n code: ['--version'],\n cursor: ['--version'],\n vim: ['--version'],\n nvim: ['--version'],\n nano: ['--version'],\n emacs: ['--version']\n}\n\nexport class SystemProfiler {\n private profile: SystemProfile | null = null\n private profilePath: string\n\n constructor() {\n this.profilePath = join(homedir(), '.bashbros', 'system-profile.json')\n }\n\n async scan(): Promise<SystemProfile> {\n const profile: SystemProfile = {\n platform: platform(),\n arch: arch(),\n shell: this.detectShell(),\n cpuCores: cpus().length,\n memoryGB: Math.round(totalmem() / (1024 ** 3)),\n\n python: this.getVersionSafe('python') || this.getVersionSafe('python3'),\n node: this.getVersionSafe('node'),\n rust: this.getVersionSafe('rustc'),\n go: this.getVersionSafe('go'),\n java: this.getVersionSafe('java'),\n ruby: this.getVersionSafe('ruby'),\n\n npm: this.getVersionSafe('npm'),\n pnpm: this.getVersionSafe('pnpm'),\n yarn: this.getVersionSafe('yarn'),\n pip: this.getVersionSafe('pip') || this.getVersionSafe('pip3'),\n cargo: this.getVersionSafe('cargo'),\n brew: this.getVersionSafe('brew'),\n\n git: this.getVersionSafe('git'),\n docker: this.getVersionSafe('docker'),\n kubectl: this.getVersionSafe('kubectl'),\n aws: this.getVersionSafe('aws'),\n gcloud: this.getVersionSafe('gcloud'),\n\n claude: this.commandExists('claude'),\n clawdbot: this.commandExists('clawdbot'),\n aider: this.commandExists('aider'),\n ollama: this.getOllamaInfo(),\n\n projectType: null,\n projectDeps: [],\n envVars: this.getEnvVarNames(),\n\n commonCommands: [],\n workingHours: null,\n preferredEditor: this.detectEditor(),\n\n timestamp: new Date()\n }\n\n this.profile = profile\n this.save()\n\n return profile\n }\n\n scanProject(projectPath: string): Partial<SystemProfile> {\n // SECURITY: Resolve symlinks and validate path\n let resolvedPath: string\n try {\n resolvedPath = realpathSync(projectPath)\n } catch {\n resolvedPath = projectPath\n }\n\n const updates: Partial<SystemProfile> = {\n projectType: this.detectProjectType(resolvedPath),\n projectDeps: this.detectDependencies(resolvedPath)\n }\n\n if (this.profile) {\n this.profile = { ...this.profile, ...updates }\n this.save()\n }\n\n return updates\n }\n\n private detectShell(): string {\n if (platform() === 'win32') {\n return process.env.COMSPEC || 'cmd.exe'\n }\n return process.env.SHELL || '/bin/bash'\n }\n\n /**\n * SECURITY FIX: Use execFileSync with array args instead of string concatenation\n */\n private getVersionSafe(cmd: string): VersionInfo | null {\n const args = SAFE_VERSION_COMMANDS[cmd]\n if (!args) {\n return null // Only allow whitelisted commands\n }\n\n try {\n // SECURITY: Use execFileSync with explicit args array\n const output = execFileSync(cmd, args, {\n encoding: 'utf-8',\n timeout: 5000,\n stdio: ['pipe', 'pipe', 'pipe'],\n windowsHide: true\n }).trim()\n\n const version = this.parseVersion(output)\n const path = this.getCommandPathSafe(cmd)\n\n return { version, path }\n } catch {\n return null\n }\n }\n\n private parseVersion(output: string): string {\n // Extract version number from various formats\n const match = output.match(/(\\d+\\.\\d+(?:\\.\\d+)?(?:-[\\w.]+)?)/i)\n return match ? match[1] : output.split('\\n')[0].slice(0, 50)\n }\n\n /**\n * SECURITY FIX: Use execFileSync for which/where command\n */\n private getCommandPathSafe(cmd: string): string {\n try {\n const whichCmd = platform() === 'win32' ? 'where' : 'which'\n // SECURITY: Use execFileSync with array args\n const result = execFileSync(whichCmd, [cmd], {\n encoding: 'utf-8',\n timeout: 3000,\n stdio: ['pipe', 'pipe', 'pipe'],\n windowsHide: true\n }).trim().split('\\n')[0]\n\n return result\n } catch {\n return cmd\n }\n }\n\n private commandExists(cmd: string): boolean {\n try {\n const whichCmd = platform() === 'win32' ? 'where' : 'which'\n // SECURITY: Use execFileSync with array args\n execFileSync(whichCmd, [cmd], {\n stdio: 'pipe',\n timeout: 3000,\n windowsHide: true\n })\n return true\n } catch {\n return false\n }\n }\n\n private getOllamaInfo(): OllamaInfo | null {\n try {\n // SECURITY: Use execFileSync with array args\n const version = execFileSync('ollama', ['--version'], {\n encoding: 'utf-8',\n timeout: 5000,\n windowsHide: true\n }).trim()\n\n let models: string[] = []\n try {\n const modelList = execFileSync('ollama', ['list'], {\n encoding: 'utf-8',\n timeout: 10000,\n windowsHide: true\n })\n models = modelList\n .split('\\n')\n .slice(1) // Skip header\n .map(line => line.split(/\\s+/)[0])\n .filter(Boolean)\n } catch {\n // Ollama might not have models or not be running\n }\n\n return { version, models }\n } catch {\n return null\n }\n }\n\n private getEnvVarNames(): string[] {\n // Return environment variable names (not values) for context\n // Only include safe, non-sensitive variable names\n const safePatterns = [\n /^PATH$/i,\n /^HOME$/i,\n /^USER$/i,\n /^SHELL$/i,\n /^TERM$/i,\n /^LANG$/i,\n /^NODE_VERSION$/i,\n /^PYTHON.*VERSION$/i,\n /^JAVA_HOME$/i,\n /^GOPATH$/i,\n /^EDITOR$/i,\n /^VISUAL$/i\n ]\n\n return Object.keys(process.env).filter(key =>\n safePatterns.some(pattern => pattern.test(key))\n )\n }\n\n private detectEditor(): string | null {\n const editor = process.env.EDITOR || process.env.VISUAL\n\n if (editor) return editor\n\n // Check for common editors\n const editors = ['code', 'cursor', 'vim', 'nvim', 'nano', 'emacs']\n for (const ed of editors) {\n if (this.commandExists(ed)) return ed\n }\n\n return null\n }\n\n private detectProjectType(projectPath: string): string | null {\n const checks: [string, string][] = [\n ['package.json', 'node'],\n ['pyproject.toml', 'python'],\n ['requirements.txt', 'python'],\n ['Cargo.toml', 'rust'],\n ['go.mod', 'go'],\n ['pom.xml', 'java'],\n ['build.gradle', 'java'],\n ['Gemfile', 'ruby'],\n ['composer.json', 'php']\n ]\n\n for (const [file, type] of checks) {\n const filePath = join(projectPath, file)\n // SECURITY: Check file exists without following symlinks first\n if (existsSync(filePath)) {\n try {\n // Verify it resolves to expected location\n const realPath = realpathSync(filePath)\n if (realPath.startsWith(realpathSync(projectPath))) {\n return type\n }\n } catch {\n // Skip if can't resolve\n }\n }\n }\n\n return null\n }\n\n private detectDependencies(projectPath: string): string[] {\n const deps: string[] = []\n\n // Check package.json\n const pkgPath = join(projectPath, 'package.json')\n if (existsSync(pkgPath)) {\n try {\n // SECURITY: Verify path resolves within project\n const realPkgPath = realpathSync(pkgPath)\n if (realPkgPath.startsWith(realpathSync(projectPath))) {\n const pkg = JSON.parse(readFileSync(realPkgPath, 'utf-8'))\n deps.push(...Object.keys(pkg.dependencies || {}))\n deps.push(...Object.keys(pkg.devDependencies || {}))\n }\n } catch { /* ignore */ }\n }\n\n // Check requirements.txt\n const reqPath = join(projectPath, 'requirements.txt')\n if (existsSync(reqPath)) {\n try {\n // SECURITY: Verify path resolves within project\n const realReqPath = realpathSync(reqPath)\n if (realReqPath.startsWith(realpathSync(projectPath))) {\n const reqs = readFileSync(realReqPath, 'utf-8')\n const packages = reqs.split('\\n')\n .map(line => line.split(/[=<>]/)[0].trim())\n .filter(Boolean)\n deps.push(...packages)\n }\n } catch { /* ignore */ }\n }\n\n return deps.slice(0, 100) // Limit to top 100\n }\n\n load(): SystemProfile | null {\n if (existsSync(this.profilePath)) {\n try {\n const data = readFileSync(this.profilePath, 'utf-8')\n this.profile = JSON.parse(data)\n return this.profile\n } catch {\n return null\n }\n }\n return null\n }\n\n private save(): void {\n try {\n const { writeFileSync, mkdirSync, chmodSync } = require('fs')\n const dir = join(homedir(), '.bashbros')\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 }) // SECURITY: Restrict directory permissions\n }\n const filePath = this.profilePath\n writeFileSync(filePath, JSON.stringify(this.profile, null, 2))\n\n // SECURITY: Restrict file permissions (owner read/write only)\n try {\n chmodSync(filePath, 0o600)\n } catch {\n // Windows doesn't support chmod the same way\n }\n } catch { /* ignore */ }\n }\n\n get(): SystemProfile | null {\n return this.profile\n }\n\n toContext(): string {\n if (!this.profile) return 'System profile not available.'\n\n const p = this.profile\n const lines: string[] = [\n `## System Context`,\n `- Platform: ${p.platform} (${p.arch})`,\n `- Shell: ${p.shell}`,\n `- CPU: ${p.cpuCores} cores, RAM: ${p.memoryGB}GB`,\n ''\n ]\n\n if (p.python) lines.push(`- Python: ${p.python.version}`)\n if (p.node) lines.push(`- Node: ${p.node.version}`)\n if (p.rust) lines.push(`- Rust: ${p.rust.version}`)\n if (p.go) lines.push(`- Go: ${p.go.version}`)\n\n if (p.git) lines.push(`- Git: ${p.git.version}`)\n if (p.docker) lines.push(`- Docker: ${p.docker.version}`)\n\n if (p.ollama) {\n lines.push(`- Ollama: ${p.ollama.version}`)\n if (p.ollama.models.length > 0) {\n lines.push(` Models: ${p.ollama.models.join(', ')}`)\n }\n }\n\n if (p.projectType) {\n lines.push('')\n lines.push(`## Project: ${p.projectType}`)\n if (p.projectDeps.length > 0) {\n lines.push(`Dependencies: ${p.projectDeps.slice(0, 20).join(', ')}`)\n }\n }\n\n return lines.join('\\n')\n }\n}\n","import type { SystemProfile } from './profiler.js'\nimport type { OllamaClient } from './ollama.js'\n\nexport type RouteDecision = 'bro' | 'main' | 'both'\n\nexport interface RoutingRule {\n pattern: RegExp\n route: RouteDecision\n reason: string\n}\n\nexport interface RoutingResult {\n decision: RouteDecision\n reason: string\n confidence: number\n}\n\nexport class TaskRouter {\n private rules: RoutingRule[]\n private profile: SystemProfile | null\n private ollama: OllamaClient | null\n\n constructor(profile: SystemProfile | null = null, ollama: OllamaClient | null = null) {\n this.profile = profile\n this.ollama = ollama\n this.rules = this.buildDefaultRules()\n }\n\n private buildDefaultRules(): RoutingRule[] {\n return [\n // Simple file operations → Bash Bro\n { pattern: /^ls\\b/, route: 'bro', reason: 'Simple file listing' },\n { pattern: /^cat\\s+\\S+$/, route: 'bro', reason: 'Simple file read' },\n { pattern: /^head\\b/, route: 'bro', reason: 'File head' },\n { pattern: /^tail\\b/, route: 'bro', reason: 'File tail' },\n { pattern: /^wc\\b/, route: 'bro', reason: 'Word count' },\n { pattern: /^pwd$/, route: 'bro', reason: 'Print directory' },\n { pattern: /^cd\\s+/, route: 'bro', reason: 'Change directory' },\n { pattern: /^mkdir\\s+/, route: 'bro', reason: 'Create directory' },\n { pattern: /^touch\\s+/, route: 'bro', reason: 'Create file' },\n { pattern: /^cp\\s+/, route: 'bro', reason: 'Copy file' },\n { pattern: /^mv\\s+/, route: 'bro', reason: 'Move file' },\n { pattern: /^rm\\s+(?!-rf)/, route: 'bro', reason: 'Remove file (safe)' },\n\n // Simple searches → Bash Bro\n { pattern: /^grep\\s+-[ril]*\\s+['\"]?\\w+['\"]?\\s+\\S+$/, route: 'bro', reason: 'Simple grep' },\n { pattern: /^find\\s+\\.\\s+-name\\s+/, route: 'bro', reason: 'Simple find' },\n { pattern: /^which\\s+/, route: 'bro', reason: 'Which command' },\n\n // Git simple operations → Bash Bro\n { pattern: /^git\\s+status$/, route: 'bro', reason: 'Git status' },\n { pattern: /^git\\s+branch$/, route: 'bro', reason: 'Git branch list' },\n { pattern: /^git\\s+log\\s+--oneline/, route: 'bro', reason: 'Git log' },\n { pattern: /^git\\s+diff$/, route: 'bro', reason: 'Git diff' },\n { pattern: /^git\\s+add\\s+/, route: 'bro', reason: 'Git add' },\n\n // Package info → Bash Bro\n { pattern: /^npm\\s+list/, route: 'bro', reason: 'NPM list' },\n { pattern: /^pip\\s+list/, route: 'bro', reason: 'Pip list' },\n { pattern: /^pip\\s+show\\s+/, route: 'bro', reason: 'Pip show' },\n\n // Environment checks → Bash Bro\n { pattern: /^python\\s+--version/, route: 'bro', reason: 'Python version' },\n { pattern: /^node\\s+--version/, route: 'bro', reason: 'Node version' },\n { pattern: /^npm\\s+--version/, route: 'bro', reason: 'NPM version' },\n { pattern: /^env$/, route: 'bro', reason: 'Environment vars' },\n { pattern: /^echo\\s+\\$\\w+$/, route: 'bro', reason: 'Echo env var' },\n\n // Complex operations → Main agent\n { pattern: /refactor/i, route: 'main', reason: 'Refactoring requires reasoning' },\n { pattern: /implement/i, route: 'main', reason: 'Implementation requires reasoning' },\n { pattern: /explain/i, route: 'main', reason: 'Explanation requires reasoning' },\n { pattern: /debug/i, route: 'main', reason: 'Debugging requires reasoning' },\n { pattern: /fix\\s+/i, route: 'main', reason: 'Fixing requires reasoning' },\n { pattern: /why/i, route: 'main', reason: 'Explanation required' },\n { pattern: /how\\s+(do|can|should)/i, route: 'main', reason: 'Guidance required' },\n\n // Git complex → Main agent\n { pattern: /^git\\s+rebase/, route: 'main', reason: 'Rebase needs oversight' },\n { pattern: /^git\\s+merge/, route: 'main', reason: 'Merge needs oversight' },\n { pattern: /^git\\s+reset/, route: 'main', reason: 'Reset needs oversight' },\n\n // Parallel tasks → Both\n { pattern: /^(npm|yarn|pnpm)\\s+(test|run\\s+test)/, route: 'both', reason: 'Tests can run in background' },\n { pattern: /^pytest/, route: 'both', reason: 'Tests can run in background' },\n { pattern: /^(npm|yarn|pnpm)\\s+run\\s+build/, route: 'both', reason: 'Build can run in background' },\n { pattern: /^docker\\s+build/, route: 'both', reason: 'Docker build can run in background' },\n ]\n }\n\n route(command: string): RoutingResult {\n // Check rules in order\n for (const rule of this.rules) {\n if (rule.pattern.test(command)) {\n return {\n decision: rule.route,\n reason: rule.reason,\n confidence: 0.9\n }\n }\n }\n\n // Default: if it looks simple, route to bro\n if (this.looksSimple(command)) {\n return {\n decision: 'bro',\n reason: 'Appears to be a simple command',\n confidence: 0.6\n }\n }\n\n // Default to main agent for complex/unknown\n return {\n decision: 'main',\n reason: 'Complex or unknown command',\n confidence: 0.5\n }\n }\n\n async routeAsync(command: string): Promise<RoutingResult> {\n // Fast path: pattern match\n const patternResult = this.route(command)\n if (patternResult.confidence >= 0.7) {\n return patternResult\n }\n\n // AI fallback for ambiguous commands\n if (!this.ollama) {\n return patternResult\n }\n\n try {\n const prompt = `Classify this command as one of: bro (simple, local task), main (complex, needs reasoning), both (can run in background). Command: \"${command}\". Respond with ONLY one word: bro, main, or both.`\n\n const response = await this.ollama.generate(prompt, 'You are a command classifier. Respond with exactly one word: bro, main, or both.')\n\n const decision = response.trim().toLowerCase() as RouteDecision\n if (['bro', 'main', 'both'].includes(decision)) {\n return { decision, reason: 'AI classification', confidence: 0.8 }\n }\n } catch {\n // AI unavailable - fallback\n }\n\n return { decision: 'main', reason: 'AI fallback - defaulting to main', confidence: 0.5 }\n }\n\n private looksSimple(command: string): boolean {\n // Heuristics for simple commands\n const words = command.split(/\\s+/)\n\n // Very short commands are usually simple\n if (words.length <= 3) return true\n\n // No pipes, redirects, or logic operators\n if (/[|><&;]/.test(command)) return false\n\n // No subshells\n if (/[$`(]/.test(command)) return false\n\n return true\n }\n\n addRule(pattern: RegExp, route: RouteDecision, reason: string): void {\n this.rules.unshift({ pattern, route, reason }) // Add to front for priority\n }\n\n updateProfile(profile: SystemProfile): void {\n this.profile = profile\n\n // Add project-specific rules based on profile\n if (profile.projectType === 'python') {\n this.addRule(/^python\\s+-c\\s+/, 'bro', 'Simple Python one-liner')\n this.addRule(/^pip\\s+install\\s+/, 'bro', 'Pip install')\n }\n\n if (profile.projectType === 'node') {\n this.addRule(/^npx\\s+/, 'bro', 'NPX command')\n this.addRule(/^npm\\s+install\\s+/, 'bro', 'NPM install')\n }\n }\n}\n","import type { SystemProfile } from './profiler.js'\nimport type { OllamaClient } from './ollama.js'\nimport type { AuditEntry } from '../types.js'\n\nexport interface Suggestion {\n command: string\n description: string\n confidence: number\n source: 'pattern' | 'history' | 'context' | 'model'\n}\n\nexport class CommandSuggester {\n private history: AuditEntry[] = []\n private profile: SystemProfile | null = null\n private patterns: Map<string, string[]> = new Map()\n private ollama: OllamaClient | null\n private aiCache: Map<string, { suggestions: Suggestion[], expiry: number }> = new Map()\n\n constructor(profile: SystemProfile | null = null, ollama: OllamaClient | null = null) {\n this.profile = profile\n this.ollama = ollama\n this.initPatterns()\n }\n\n private initPatterns(): void {\n // Common command sequences\n this.patterns.set('git status', ['git add .', 'git diff', 'git stash'])\n this.patterns.set('git add', ['git commit -m \"\"', 'git status'])\n this.patterns.set('git commit', ['git push', 'git log --oneline -5'])\n this.patterns.set('git pull', ['git status', 'git log --oneline -5'])\n this.patterns.set('git checkout', ['git status', 'git branch'])\n\n this.patterns.set('npm install', ['npm run build', 'npm test', 'npm start'])\n this.patterns.set('npm test', ['npm run build', 'git add .'])\n this.patterns.set('npm run build', ['npm start', 'npm test'])\n\n this.patterns.set('pip install', ['pip freeze', 'python -m pytest'])\n this.patterns.set('pytest', ['git add .', 'python -m pytest -v'])\n\n this.patterns.set('docker build', ['docker run', 'docker images'])\n this.patterns.set('docker run', ['docker ps', 'docker logs'])\n\n this.patterns.set('cd', ['ls', 'ls -la', 'git status'])\n this.patterns.set('mkdir', ['cd', 'touch'])\n this.patterns.set('ls', ['cd', 'cat', 'vim'])\n }\n\n suggest(context: SuggestionContext): Suggestion[] {\n const suggestions: Suggestion[] = []\n\n // 1. Pattern-based suggestions\n if (context.lastCommand) {\n const patternSuggestions = this.suggestFromPatterns(context.lastCommand)\n suggestions.push(...patternSuggestions)\n }\n\n // 2. History-based suggestions\n const historySuggestions = this.suggestFromHistory(context)\n suggestions.push(...historySuggestions)\n\n // 3. Context-based suggestions\n const contextSuggestions = this.suggestFromContext(context)\n suggestions.push(...contextSuggestions)\n\n // Dedupe and sort by confidence\n const unique = this.dedupeAndRank(suggestions)\n\n return unique.slice(0, 5) // Top 5\n }\n\n async suggestAsync(context: SuggestionContext): Promise<Suggestion[]> {\n // Get pattern/history/context suggestions first\n const suggestions = this.suggest(context)\n\n if (!this.ollama) return suggestions\n\n // Check cache\n const cacheKey = JSON.stringify({ lc: context.lastCommand, lo: context.lastOutput?.slice(0, 100) })\n const cached = this.aiCache.get(cacheKey)\n if (cached && cached.expiry > Date.now()) {\n suggestions.push(...cached.suggestions)\n return this.dedupeAndRank(suggestions).slice(0, 5)\n }\n\n // Call Ollama\n try {\n const contextStr = `Last command: ${context.lastCommand || 'none'}\\nOutput: ${(context.lastOutput || '').slice(0, 200)}\\nProject: ${context.projectType || 'unknown'}`\n const aiSuggestion = await this.ollama.suggestCommand(contextStr)\n\n if (aiSuggestion) {\n const aiSuggestions: Suggestion[] = [{\n command: aiSuggestion,\n description: 'AI suggestion',\n confidence: 0.75,\n source: 'model'\n }]\n\n this.aiCache.set(cacheKey, { suggestions: aiSuggestions, expiry: Date.now() + 5 * 60 * 1000 })\n suggestions.push(...aiSuggestions)\n }\n } catch {\n // AI unavailable\n }\n\n return this.dedupeAndRank(suggestions).slice(0, 5)\n }\n\n private suggestFromPatterns(lastCommand: string): Suggestion[] {\n const suggestions: Suggestion[] = []\n\n // Find matching pattern key\n for (const [key, commands] of this.patterns) {\n if (lastCommand.startsWith(key)) {\n for (const cmd of commands) {\n suggestions.push({\n command: cmd,\n description: `Common follow-up to \"${key}\"`,\n confidence: 0.8,\n source: 'pattern'\n })\n }\n break\n }\n }\n\n return suggestions\n }\n\n private suggestFromHistory(context: SuggestionContext): Suggestion[] {\n if (this.history.length < 3) return []\n\n const suggestions: Suggestion[] = []\n\n // Find commands that often follow the current context\n const recentCommands = this.history.slice(-20)\n const following = new Map<string, number>()\n\n for (let i = 0; i < recentCommands.length - 1; i++) {\n const current = recentCommands[i].command\n const next = recentCommands[i + 1].command\n\n if (context.lastCommand && current.startsWith(context.lastCommand.split(' ')[0])) {\n const count = following.get(next) || 0\n following.set(next, count + 1)\n }\n }\n\n // Convert to suggestions\n for (const [cmd, count] of following) {\n if (count >= 2) {\n suggestions.push({\n command: cmd,\n description: 'Based on your history',\n confidence: Math.min(0.9, 0.5 + count * 0.1),\n source: 'history'\n })\n }\n }\n\n return suggestions\n }\n\n private suggestFromContext(context: SuggestionContext): Suggestion[] {\n const suggestions: Suggestion[] = []\n\n // Project-type specific suggestions\n if (context.projectType === 'node' && context.cwd) {\n if (context.files?.includes('package.json')) {\n suggestions.push({\n command: 'npm install',\n description: 'Install dependencies',\n confidence: 0.7,\n source: 'context'\n })\n }\n }\n\n if (context.projectType === 'python' && context.cwd) {\n if (context.files?.includes('requirements.txt')) {\n suggestions.push({\n command: 'pip install -r requirements.txt',\n description: 'Install dependencies',\n confidence: 0.7,\n source: 'context'\n })\n }\n }\n\n // Error-based suggestions\n if (context.lastError) {\n if (context.lastError.includes('ModuleNotFoundError')) {\n const match = context.lastError.match(/No module named '(\\w+)'/)\n if (match) {\n suggestions.push({\n command: `pip install ${match[1]}`,\n description: `Install missing module`,\n confidence: 0.9,\n source: 'context'\n })\n }\n }\n\n if (context.lastError.includes('Cannot find module')) {\n suggestions.push({\n command: 'npm install',\n description: 'Install missing dependencies',\n confidence: 0.85,\n source: 'context'\n })\n }\n }\n\n return suggestions\n }\n\n private dedupeAndRank(suggestions: Suggestion[]): Suggestion[] {\n const seen = new Set<string>()\n const unique: Suggestion[] = []\n\n // Sort by confidence first\n suggestions.sort((a, b) => b.confidence - a.confidence)\n\n for (const s of suggestions) {\n if (!seen.has(s.command)) {\n seen.add(s.command)\n unique.push(s)\n }\n }\n\n return unique\n }\n\n recordCommand(entry: AuditEntry): void {\n this.history.push(entry)\n // Keep last 100 commands\n if (this.history.length > 100) {\n this.history = this.history.slice(-100)\n }\n }\n\n updateProfile(profile: SystemProfile): void {\n this.profile = profile\n }\n}\n\nexport interface SuggestionContext {\n lastCommand?: string\n lastOutput?: string\n lastError?: string\n cwd?: string\n projectType?: string\n files?: string[]\n}\n","import { spawn, ChildProcess } from 'child_process'\nimport { EventEmitter } from 'events'\n\nexport interface BackgroundTask {\n id: string\n command: string\n status: 'running' | 'completed' | 'failed' | 'cancelled'\n startTime: Date\n endTime?: Date\n output: string[]\n exitCode?: number\n}\n\n// Maximum tasks to keep in history\nconst MAX_TASK_HISTORY = 100\n\n/**\n * Safely parse a command string into executable parts.\n * Prevents shell injection by NOT using shell: true\n */\nfunction parseCommand(command: string): { cmd: string; args: string[] } {\n // Handle quoted strings properly\n const tokens: string[] = []\n let current = ''\n let inQuote: string | null = null\n\n for (let i = 0; i < command.length; i++) {\n const char = command[i]\n\n if (inQuote) {\n if (char === inQuote) {\n inQuote = null\n } else {\n current += char\n }\n } else if (char === '\"' || char === \"'\") {\n inQuote = char\n } else if (char === ' ' || char === '\\t') {\n if (current) {\n tokens.push(current)\n current = ''\n }\n } else {\n current += char\n }\n }\n\n if (current) {\n tokens.push(current)\n }\n\n return {\n cmd: tokens[0] || '',\n args: tokens.slice(1)\n }\n}\n\n/**\n * Validate command doesn't contain dangerous shell metacharacters\n */\nfunction validateCommand(command: string): { valid: boolean; reason?: string } {\n // Block shell metacharacters that could enable injection\n const dangerousPatterns = [\n /[;&|`$]/, // Shell operators and command substitution\n /\\$\\(/, // Command substitution\n />\\s*>/, // Append redirect\n />\\s*\\//, // Redirect to absolute path\n /<\\s*\\//, // Input from absolute path\n /\\|\\s*\\w+/, // Pipe to command\n ]\n\n for (const pattern of dangerousPatterns) {\n if (pattern.test(command)) {\n return {\n valid: false,\n reason: `Command contains potentially dangerous pattern: ${pattern.source}`\n }\n }\n }\n\n return { valid: true }\n}\n\nexport class BackgroundWorker extends EventEmitter {\n private tasks: Map<string, BackgroundTask> = new Map()\n private processes: Map<string, ChildProcess> = new Map()\n private taskIdCounter = 0\n\n spawn(command: string, cwd?: string): BackgroundTask {\n // Validate command first\n const validation = validateCommand(command)\n if (!validation.valid) {\n throw new Error(`Security: ${validation.reason}`)\n }\n\n const id = `task_${++this.taskIdCounter}`\n\n const task: BackgroundTask = {\n id,\n command,\n status: 'running',\n startTime: new Date(),\n output: []\n }\n\n this.tasks.set(id, task)\n\n // Parse command safely\n const { cmd, args } = parseCommand(command)\n\n if (!cmd) {\n task.status = 'failed'\n task.endTime = new Date()\n task.output.push('Error: Empty command')\n return task\n }\n\n // SECURITY FIX: Use shell: false to prevent injection\n const proc = spawn(cmd, args, {\n cwd: cwd || process.cwd(),\n shell: false, // CRITICAL: Never use shell: true\n stdio: ['pipe', 'pipe', 'pipe'],\n env: process.env\n })\n\n this.processes.set(id, proc)\n\n proc.stdout?.on('data', (data: Buffer) => {\n const line = data.toString()\n task.output.push(line)\n this.emit('output', { taskId: id, data: line, stream: 'stdout' })\n })\n\n proc.stderr?.on('data', (data: Buffer) => {\n const line = data.toString()\n task.output.push(line)\n this.emit('output', { taskId: id, data: line, stream: 'stderr' })\n })\n\n proc.on('close', (code: number | null) => {\n task.status = code === 0 ? 'completed' : 'failed'\n task.endTime = new Date()\n task.exitCode = code ?? undefined\n this.processes.delete(id)\n\n this.emit('complete', {\n taskId: id,\n exitCode: code,\n duration: task.endTime.getTime() - task.startTime.getTime()\n })\n\n // Notify user\n this.notifyCompletion(task)\n\n // Cleanup old tasks\n this.cleanupOldTasks()\n })\n\n proc.on('error', (error: Error) => {\n task.status = 'failed'\n task.endTime = new Date()\n task.output.push(`Error: ${error.message}`)\n this.processes.delete(id)\n\n this.emit('error', { taskId: id, error })\n })\n\n this.emit('started', { taskId: id, command })\n\n return task\n }\n\n cancel(taskId: string): boolean {\n const proc = this.processes.get(taskId)\n const task = this.tasks.get(taskId)\n\n if (proc && task) {\n proc.kill('SIGTERM')\n task.status = 'cancelled'\n task.endTime = new Date()\n this.processes.delete(taskId)\n return true\n }\n\n return false\n }\n\n getTask(taskId: string): BackgroundTask | undefined {\n return this.tasks.get(taskId)\n }\n\n getRunningTasks(): BackgroundTask[] {\n return Array.from(this.tasks.values()).filter(t => t.status === 'running')\n }\n\n getAllTasks(): BackgroundTask[] {\n return Array.from(this.tasks.values())\n }\n\n getRecentTasks(limit: number = 10): BackgroundTask[] {\n return Array.from(this.tasks.values())\n .sort((a, b) => b.startTime.getTime() - a.startTime.getTime())\n .slice(0, limit)\n }\n\n private cleanupOldTasks(): void {\n // Remove completed tasks beyond limit\n const tasks = Array.from(this.tasks.entries())\n .filter(([_, t]) => t.status !== 'running')\n .sort((a, b) => b[1].startTime.getTime() - a[1].startTime.getTime())\n\n if (tasks.length > MAX_TASK_HISTORY) {\n const toRemove = tasks.slice(MAX_TASK_HISTORY)\n for (const [id] of toRemove) {\n this.tasks.delete(id)\n }\n }\n }\n\n private notifyCompletion(task: BackgroundTask): void {\n const duration = task.endTime\n ? Math.round((task.endTime.getTime() - task.startTime.getTime()) / 1000)\n : 0\n\n const icon = task.status === 'completed' ? '✓' : '✗'\n const status = task.status === 'completed' ? 'completed' : 'failed'\n\n console.log(`\\n🤝 Bash Bro: Background task ${icon} ${status}`)\n console.log(` Command: ${task.command}`)\n console.log(` Duration: ${duration}s`)\n\n if (task.status === 'failed' && task.output.length > 0) {\n const lastLines = task.output.slice(-3).join('').trim()\n if (lastLines) {\n console.log(` Last output: ${lastLines.slice(0, 100)}`)\n }\n }\n\n console.log()\n }\n\n formatStatus(): string {\n const running = this.getRunningTasks()\n\n if (running.length === 0) {\n return 'No background tasks running.'\n }\n\n const lines = ['Background tasks:']\n for (const task of running) {\n const elapsed = Math.round((Date.now() - task.startTime.getTime()) / 1000)\n lines.push(` [${task.id}] ${task.command} (${elapsed}s)`)\n }\n\n return lines.join('\\n')\n }\n}\n","import { execFileSync } from 'child_process'\nimport { EventEmitter } from 'events'\nimport type { BashBrosConfig } from '../types.js'\nimport { SystemProfiler, SystemProfile } from './profiler.js'\nimport { TaskRouter, RoutingResult } from './router.js'\nimport { CommandSuggester, Suggestion, SuggestionContext } from './suggester.js'\nimport { BackgroundWorker, BackgroundTask } from './worker.js'\nimport { OllamaClient } from './ollama.js'\nimport { getBashgymIntegration, type ModelManifest } from '../integration/bashgym.js'\nimport { AdapterRegistry, type AdapterEntry, type AdapterPurpose } from './adapters.js'\nimport { ProfileManager, type ModelProfile } from './profiles.js'\n\nexport interface BroConfig {\n modelEndpoint?: string // Ollama endpoint (default: http://localhost:11434)\n modelName?: string // e.g., 'qwen2.5-coder:7b'\n enableSuggestions?: boolean\n enableRouting?: boolean\n enableBackground?: boolean\n enableOllama?: boolean // Use Ollama for AI features\n enableBashgymIntegration?: boolean // Enable bashgym integration for model hot-swap\n activeProfile?: string // Active model profile name\n}\n\n// Allowlist of commands that can be executed directly\nconst SAFE_COMMANDS = new Set([\n 'ls', 'dir', 'cat', 'head', 'tail', 'grep', 'find', 'wc',\n 'pwd', 'cd', 'mkdir', 'touch', 'cp', 'mv', 'rm',\n 'git', 'npm', 'npx', 'pnpm', 'yarn', 'node', 'python', 'python3',\n 'pip', 'pip3', 'pytest', 'cargo', 'go', 'rustc',\n 'docker', 'kubectl', 'echo', 'which', 'where', 'type',\n 'date', 'whoami', 'hostname', 'env', 'printenv'\n])\n\n/**\n * Parse command into executable and arguments safely\n */\nfunction parseCommandSafe(command: string): { cmd: string; args: string[] } | null {\n const tokens: string[] = []\n let current = ''\n let inQuote: string | null = null\n\n for (let i = 0; i < command.length; i++) {\n const char = command[i]\n\n if (inQuote) {\n if (char === inQuote) {\n inQuote = null\n } else {\n current += char\n }\n } else if (char === '\"' || char === \"'\") {\n inQuote = char\n } else if (char === ' ' || char === '\\t') {\n if (current) {\n tokens.push(current)\n current = ''\n }\n } else {\n current += char\n }\n }\n\n if (current) {\n tokens.push(current)\n }\n\n if (tokens.length === 0) {\n return null\n }\n\n const cmd = tokens[0]\n\n // SECURITY: Only allow whitelisted commands\n if (!SAFE_COMMANDS.has(cmd)) {\n return null\n }\n\n return {\n cmd,\n args: tokens.slice(1)\n }\n}\n\n/**\n * Validate command doesn't contain shell injection patterns\n */\nfunction validateCommandSafety(command: string): { safe: boolean; reason?: string } {\n const dangerousPatterns = [\n /[;&|`]/, // Shell operators\n /\\$\\(/, // Command substitution\n /\\$\\{/, // Variable expansion\n />\\s*>/, // Append redirect\n /[<>]\\s*\\//, // Redirect to/from absolute path\n /\\|\\s*\\w+/, // Pipe to command\n /\\\\x[0-9a-f]/i, // Hex escapes\n /\\\\[0-7]{3}/, // Octal escapes\n ]\n\n for (const pattern of dangerousPatterns) {\n if (pattern.test(command)) {\n return { safe: false, reason: `Contains dangerous pattern` }\n }\n }\n\n return { safe: true }\n}\n\nexport class BashBro extends EventEmitter {\n private profiler: SystemProfiler\n private router: TaskRouter\n private suggester: CommandSuggester\n private worker: BackgroundWorker\n private ollama: OllamaClient | null = null\n private profile: SystemProfile | null = null\n private config: BroConfig\n private ollamaAvailable: boolean = false\n private bashgymModelVersion: string | null = null\n private adapterRegistry: AdapterRegistry\n private profileManager: ProfileManager\n private activeProfile: ModelProfile | null = null\n\n constructor(config: BroConfig = {}) {\n super()\n\n this.config = {\n enableSuggestions: true,\n enableRouting: true,\n enableBackground: true,\n enableOllama: true,\n enableBashgymIntegration: true,\n ...config\n }\n\n this.profiler = new SystemProfiler()\n this.worker = new BackgroundWorker()\n\n // Initialize Ollama client first so router/suggester can use it\n if (this.config.enableOllama) {\n this.ollama = new OllamaClient({\n host: this.config.modelEndpoint,\n model: this.config.modelName\n })\n }\n\n // Pass Ollama client to router and suggester for AI-enhanced features\n this.router = new TaskRouter(null, this.ollama)\n this.suggester = new CommandSuggester(null, this.ollama)\n\n // Forward worker events\n this.worker.on('complete', (data) => this.emit('task:complete', data))\n this.worker.on('output', (data) => this.emit('task:output', data))\n this.worker.on('error', (data) => this.emit('task:error', data))\n\n // Initialize bashgym integration for model hot-swap\n if (this.config.enableBashgymIntegration) {\n this.initBashgymIntegration()\n }\n\n // Initialize adapter registry and profile manager\n this.adapterRegistry = new AdapterRegistry()\n this.profileManager = new ProfileManager()\n if (this.config.activeProfile) {\n this.activeProfile = this.profileManager.load(this.config.activeProfile)\n }\n }\n\n /**\n * Initialize bashgym integration for model hot-swap\n */\n private initBashgymIntegration(): void {\n try {\n const integration = getBashgymIntegration()\n\n // Listen for model updates\n integration.on('model:updated', (version: string, manifest: ModelManifest) => {\n this.handleModelUpdate(version, manifest)\n })\n\n // Check if we should use the bashgym sidekick model\n if (integration.isLinked()) {\n const modelName = integration.getOllamaModelName()\n const currentVersion = integration.getCurrentModelVersion()\n\n if (currentVersion && this.ollama) {\n // Use the bashgym-trained sidekick model\n this.ollama.setModel(`${modelName}:${currentVersion}`)\n this.bashgymModelVersion = currentVersion\n console.log(`🤝 Bash Bro: Using bashgym sidekick model (${currentVersion})`)\n }\n }\n } catch {\n // Integration not available - continue without it\n }\n }\n\n /**\n * Handle model update from bashgym (hot-swap)\n */\n private handleModelUpdate(version: string, manifest: ModelManifest): void {\n if (!this.ollama) return\n\n // Don't update if it's the same version\n if (version === this.bashgymModelVersion) return\n\n try {\n const integration = getBashgymIntegration()\n const modelName = integration.getOllamaModelName()\n\n // Hot-swap to the new model\n this.ollama.setModel(`${modelName}:${version}`)\n this.bashgymModelVersion = version\n\n console.log(`🤝 Bash Bro: Model hot-swapped to ${version}`)\n this.emit('model:updated', version)\n } catch (error) {\n console.error('Failed to hot-swap model:', error)\n }\n }\n\n async initialize(): Promise<void> {\n // Load or scan system profile\n this.profile = this.profiler.load()\n\n if (!this.profile || this.isProfileStale()) {\n console.log('🤝 Bash Bro: Scanning your system...')\n this.profile = await this.profiler.scan()\n console.log('🤝 Bash Bro: System profile updated!')\n }\n\n this.router.updateProfile(this.profile)\n this.suggester.updateProfile(this.profile)\n\n // Check Ollama availability\n if (this.ollama) {\n this.ollamaAvailable = await this.ollama.isAvailable()\n if (this.ollamaAvailable) {\n console.log('🤝 Bash Bro: Ollama connected')\n }\n }\n\n this.emit('ready', this.profile)\n }\n\n private isProfileStale(): boolean {\n if (!this.profile) return true\n\n const age = Date.now() - new Date(this.profile.timestamp).getTime()\n const oneDay = 24 * 60 * 60 * 1000\n\n return age > oneDay\n }\n\n scanProject(projectPath: string): void {\n this.profiler.scanProject(projectPath)\n this.profile = this.profiler.get()\n\n if (this.profile) {\n this.router.updateProfile(this.profile)\n this.suggester.updateProfile(this.profile)\n }\n }\n\n route(command: string): RoutingResult {\n if (!this.config.enableRouting) {\n return { decision: 'main', reason: 'Routing disabled', confidence: 1 }\n }\n\n return this.router.route(command)\n }\n\n suggest(context: SuggestionContext): Suggestion[] {\n if (!this.config.enableSuggestions) {\n return []\n }\n\n return this.suggester.suggest(context)\n }\n\n /**\n * AI-enhanced async routing - uses pattern matching first, falls back to Ollama\n */\n async routeAsync(command: string): Promise<RoutingResult> {\n if (!this.config.enableRouting) {\n return { decision: 'main', reason: 'Routing disabled', confidence: 1 }\n }\n return this.router.routeAsync(command)\n }\n\n /**\n * AI-enhanced async suggestions - pattern matching + Ollama suggestions with caching\n */\n async suggestAsync(context: SuggestionContext): Promise<Suggestion[]> {\n if (!this.config.enableSuggestions) return []\n return this.suggester.suggestAsync(context)\n }\n\n /**\n * SECURITY FIX: Safe command execution with validation\n */\n async execute(command: string): Promise<string> {\n // Validate command safety\n const safety = validateCommandSafety(command)\n if (!safety.safe) {\n return `Security: Command blocked - ${safety.reason}`\n }\n\n // Parse command safely\n const parsed = parseCommandSafe(command)\n if (!parsed) {\n return `Security: Command not in allowlist. Only safe commands can be executed directly.`\n }\n\n try {\n // SECURITY: Use execFileSync with array args, no shell\n const output = execFileSync(parsed.cmd, parsed.args, {\n encoding: 'utf-8',\n timeout: 30000,\n cwd: process.cwd(),\n windowsHide: true\n })\n return output\n } catch (error: any) {\n return error.message || 'Command failed'\n }\n }\n\n runBackground(command: string, cwd?: string): BackgroundTask {\n if (!this.config.enableBackground) {\n throw new Error('Background tasks disabled')\n }\n\n return this.worker.spawn(command, cwd)\n }\n\n cancelBackground(taskId: string): boolean {\n return this.worker.cancel(taskId)\n }\n\n getBackgroundTasks(): BackgroundTask[] {\n return this.worker.getRunningTasks()\n }\n\n getSystemContext(): string {\n return this.profiler.toContext()\n }\n\n getProfile(): SystemProfile | null {\n return this.profile\n }\n\n /**\n * Check if Ollama is available for AI features\n */\n isOllamaAvailable(): boolean {\n return this.ollamaAvailable\n }\n\n /**\n * Ask Bash Bro (via Ollama) to suggest the next command\n */\n async aiSuggest(context: string): Promise<string | null> {\n if (!this.ollama || !this.ollamaAvailable) {\n return null\n }\n\n const startTime = Date.now()\n try {\n const result = await this.ollama.suggestCommand(context)\n const latency = Date.now() - startTime\n\n this.emit('bro:suggestion', {\n input: context,\n output: result ?? '',\n model: this.ollama.getModel(),\n latencyMs: latency,\n success: result !== null\n })\n\n return result\n } catch (error) {\n const latency = Date.now() - startTime\n this.emit('bro:suggestion', {\n input: context,\n output: '',\n model: this.ollama?.getModel() ?? 'unknown',\n latencyMs: latency,\n success: false\n })\n return null\n }\n }\n\n /**\n * Ask Bash Bro to explain a command\n */\n async aiExplain(command: string): Promise<string> {\n if (!this.ollama || !this.ollamaAvailable) {\n return 'Ollama not available for explanations.'\n }\n\n const startTime = Date.now()\n try {\n const result = await this.ollama.explainCommand(command)\n const latency = Date.now() - startTime\n\n this.emit('bro:explanation', {\n input: command,\n output: result,\n model: this.ollama.getModel(),\n latencyMs: latency,\n success: true\n })\n\n return result\n } catch (error) {\n const latency = Date.now() - startTime\n this.emit('bro:explanation', {\n input: command,\n output: 'Could not explain command.',\n model: this.ollama?.getModel() ?? 'unknown',\n latencyMs: latency,\n success: false\n })\n return 'Could not explain command.'\n }\n }\n\n /**\n * Ask Bash Bro to fix a failed command\n */\n async aiFix(command: string, error: string): Promise<string | null> {\n if (!this.ollama || !this.ollamaAvailable) {\n return null\n }\n\n const startTime = Date.now()\n try {\n const result = await this.ollama.fixCommand(command, error)\n const latency = Date.now() - startTime\n\n this.emit('bro:fix', {\n input: `${command} | Error: ${error}`,\n output: result ?? '',\n model: this.ollama.getModel(),\n latencyMs: latency,\n success: result !== null\n })\n\n return result\n } catch (err) {\n const latency = Date.now() - startTime\n this.emit('bro:fix', {\n input: `${command} | Error: ${error}`,\n output: '',\n model: this.ollama?.getModel() ?? 'unknown',\n latencyMs: latency,\n success: false\n })\n return null\n }\n }\n\n /**\n * Set the Ollama model to use\n */\n setModel(model: string): void {\n if (this.ollama) {\n this.ollama.setModel(model)\n }\n }\n\n /**\n * Generate a shell script from natural language description\n */\n async aiGenerateScript(description: string): Promise<string | null> {\n if (!this.ollama || !this.ollamaAvailable) {\n return null\n }\n\n const shell = this.profile?.shell || 'bash'\n const startTime = Date.now()\n\n try {\n const result = await this.ollama.generateScript(description, shell)\n const latency = Date.now() - startTime\n\n this.emit('bro:script', {\n input: description,\n output: result ?? '',\n model: this.ollama.getModel(),\n latencyMs: latency,\n success: result !== null\n })\n\n return result\n } catch (error) {\n const latency = Date.now() - startTime\n this.emit('bro:script', {\n input: description,\n output: '',\n model: this.ollama?.getModel() ?? 'unknown',\n latencyMs: latency,\n success: false\n })\n return null\n }\n }\n\n /**\n * Analyze command for security risks using AI\n */\n async aiAnalyzeSafety(command: string): Promise<{\n safe: boolean\n risk: 'low' | 'medium' | 'high' | 'critical'\n explanation: string\n suggestions: string[]\n }> {\n if (!this.ollama || !this.ollamaAvailable) {\n return {\n safe: true,\n risk: 'low',\n explanation: 'AI analysis not available.',\n suggestions: []\n }\n }\n\n const startTime = Date.now()\n try {\n const result = await this.ollama.analyzeCommandSafety(command)\n const latency = Date.now() - startTime\n\n this.emit('bro:safety', {\n input: command,\n output: `Risk: ${result.risk} - ${result.explanation}`,\n model: this.ollama.getModel(),\n latencyMs: latency,\n success: true\n })\n\n return result\n } catch (error) {\n const latency = Date.now() - startTime\n this.emit('bro:safety', {\n input: command,\n output: 'Analysis failed',\n model: this.ollama?.getModel() ?? 'unknown',\n latencyMs: latency,\n success: false\n })\n return {\n safe: true,\n risk: 'low',\n explanation: 'Analysis unavailable.',\n suggestions: []\n }\n }\n }\n\n /**\n * Summarize a terminal session\n */\n async aiSummarize(commands: { command: string; output?: string; error?: string }[]): Promise<string> {\n if (!this.ollama || !this.ollamaAvailable) {\n return 'AI not available for summaries.'\n }\n\n return this.ollama.summarizeSession(commands)\n }\n\n /**\n * Get AI help for a topic or command\n */\n async aiHelp(topic: string): Promise<string> {\n if (!this.ollama || !this.ollamaAvailable) {\n return 'AI not available for help.'\n }\n\n return this.ollama.getHelp(topic)\n }\n\n /**\n * Convert natural language to command\n */\n async aiToCommand(description: string): Promise<string | null> {\n if (!this.ollama || !this.ollamaAvailable) {\n return null\n }\n\n return this.ollama.naturalToCommand(description)\n }\n\n /**\n * Get bashgym sidekick model version (if using)\n */\n getBashgymModelVersion(): string | null {\n return this.bashgymModelVersion\n }\n\n /**\n * Check if using bashgym-trained sidekick model\n */\n isUsingBashgymModel(): boolean {\n return this.bashgymModelVersion !== null\n }\n\n /**\n * Force refresh the bashgym model (check for updates)\n */\n refreshBashgymModel(): boolean {\n if (!this.config.enableBashgymIntegration) {\n return false\n }\n\n try {\n const integration = getBashgymIntegration()\n const currentVersion = integration.getCurrentModelVersion()\n\n if (currentVersion && currentVersion !== this.bashgymModelVersion) {\n const modelName = integration.getOllamaModelName()\n if (this.ollama) {\n this.ollama.setModel(`${modelName}:${currentVersion}`)\n this.bashgymModelVersion = currentVersion\n this.emit('model:updated', currentVersion)\n return true\n }\n }\n } catch {\n // Ignore errors\n }\n\n return false\n }\n\n /**\n * Get model name for a specific purpose (checks active profile for adapter override)\n */\n private getModelForPurpose(purpose: AdapterPurpose): string | null {\n if (!this.activeProfile) return null\n return this.profileManager.getModelForPurpose(this.activeProfile, purpose)\n }\n\n /**\n * Get discovered LoRA adapters\n */\n getAdapters(): AdapterEntry[] {\n return this.adapterRegistry.discover()\n }\n\n /**\n * Get available model profiles\n */\n getProfiles(): ModelProfile[] {\n return this.profileManager.list()\n }\n\n /**\n * Get the active model profile\n */\n getActiveProfile(): ModelProfile | null {\n return this.activeProfile\n }\n\n /**\n * Set the active model profile by name\n */\n setActiveProfile(name: string): boolean {\n const profile = this.profileManager.load(name)\n if (!profile) return false\n this.activeProfile = profile\n this.emit('profile:changed', profile)\n return true\n }\n\n // Format a nice status message\n status(): string {\n const lines: string[] = [\n '🤝 Bash Bro Status',\n '─'.repeat(40)\n ]\n\n if (this.profile) {\n lines.push(`Platform: ${this.profile.platform} (${this.profile.arch})`)\n lines.push(`Shell: ${this.profile.shell}`)\n\n if (this.profile.python) {\n lines.push(`Python: ${this.profile.python.version}`)\n }\n if (this.profile.node) {\n lines.push(`Node: ${this.profile.node.version}`)\n }\n\n if (this.profile.ollama) {\n lines.push(`Ollama: ${this.profile.ollama.version}`)\n if (this.profile.ollama.models.length > 0) {\n lines.push(` Models: ${this.profile.ollama.models.join(', ')}`)\n }\n }\n\n if (this.profile.projectType) {\n lines.push(`Project: ${this.profile.projectType}`)\n }\n }\n\n // Ollama connection status\n lines.push('')\n if (this.ollamaAvailable) {\n const model = this.ollama?.getModel() || 'default'\n if (this.bashgymModelVersion) {\n lines.push(`AI: Connected (bashgym sidekick ${this.bashgymModelVersion})`)\n } else {\n lines.push(`AI: Connected (${model})`)\n }\n } else {\n lines.push('AI: Not connected (run Ollama for AI features)')\n }\n\n // Bashgym integration status\n if (this.config.enableBashgymIntegration) {\n try {\n const integration = getBashgymIntegration()\n if (integration.isLinked()) {\n lines.push(`BashGym: Linked`)\n if (integration.isBashgymRunning()) {\n lines.push(` Status: Running`)\n }\n }\n } catch {\n // Integration not available\n }\n }\n\n lines.push('')\n lines.push(this.worker.formatStatus())\n\n return lines.join('\\n')\n }\n}\n","/**\r\n * Cost Estimation\r\n * Estimate API costs based on session complexity\r\n */\r\n\r\nexport interface CostEstimate {\r\n estimatedTokens: number\r\n estimatedCost: number // USD\r\n breakdown: {\r\n inputTokens: number\r\n outputTokens: number\r\n toolCalls: number\r\n contextTokens: number\r\n }\r\n model: string\r\n confidence: 'low' | 'medium' | 'high'\r\n}\r\n\r\nexport interface ModelPricing {\r\n inputPer1k: number // USD per 1K input tokens\r\n outputPer1k: number // USD per 1K output tokens\r\n}\r\n\r\n// Pricing as of 2025 (update as needed)\r\nconst MODEL_PRICING: Record<string, ModelPricing> = {\r\n 'claude-opus-4': { inputPer1k: 0.015, outputPer1k: 0.075 },\r\n 'claude-sonnet-4': { inputPer1k: 0.003, outputPer1k: 0.015 },\r\n 'claude-haiku-4': { inputPer1k: 0.00025, outputPer1k: 0.00125 },\r\n 'gpt-4o': { inputPer1k: 0.005, outputPer1k: 0.015 },\r\n 'gpt-4o-mini': { inputPer1k: 0.00015, outputPer1k: 0.0006 },\r\n 'default': { inputPer1k: 0.003, outputPer1k: 0.015 }\r\n}\r\n\r\n// Heuristics for token estimation\r\nconst AVG_CHARS_PER_TOKEN = 4\r\nconst AVG_TOOL_CALL_TOKENS = 150\r\nconst AVG_TOOL_RESULT_TOKENS = 500\r\nconst CONTEXT_OVERHEAD_RATIO = 0.2 // 20% overhead for system prompts, etc.\r\n\r\nexport class CostEstimator {\r\n private model: string\r\n private pricing: ModelPricing\r\n private totalInputTokens: number = 0\r\n private totalOutputTokens: number = 0\r\n private toolCallCount: number = 0\r\n\r\n constructor(model: string = 'claude-sonnet-4') {\r\n this.model = model\r\n this.pricing = MODEL_PRICING[model] || MODEL_PRICING['default']\r\n }\r\n\r\n /**\r\n * Estimate tokens from text\r\n */\r\n estimateTokens(text: string): number {\r\n return Math.ceil(text.length / AVG_CHARS_PER_TOKEN)\r\n }\r\n\r\n /**\r\n * Record a tool call with input and output\r\n */\r\n recordToolCall(input: string, output?: string): void {\r\n this.toolCallCount++\r\n\r\n // Estimate input tokens (command + tool overhead)\r\n const inputTokens = this.estimateTokens(input) + AVG_TOOL_CALL_TOKENS\r\n this.totalInputTokens += inputTokens\r\n\r\n // Estimate output tokens (result + overhead)\r\n if (output) {\r\n const outputTokens = this.estimateTokens(output) + 50 // Response overhead\r\n this.totalOutputTokens += outputTokens\r\n } else {\r\n this.totalOutputTokens += AVG_TOOL_RESULT_TOKENS\r\n }\r\n }\r\n\r\n /**\r\n * Get current cost estimate\r\n */\r\n getEstimate(): CostEstimate {\r\n // Add context overhead\r\n const contextTokens = Math.ceil(\r\n (this.totalInputTokens + this.totalOutputTokens) * CONTEXT_OVERHEAD_RATIO\r\n )\r\n\r\n const totalInput = this.totalInputTokens + contextTokens\r\n const totalOutput = this.totalOutputTokens\r\n\r\n // Calculate cost\r\n const inputCost = (totalInput / 1000) * this.pricing.inputPer1k\r\n const outputCost = (totalOutput / 1000) * this.pricing.outputPer1k\r\n const totalCost = inputCost + outputCost\r\n\r\n // Determine confidence based on data points\r\n let confidence: CostEstimate['confidence']\r\n if (this.toolCallCount < 5) confidence = 'low'\r\n else if (this.toolCallCount < 20) confidence = 'medium'\r\n else confidence = 'high'\r\n\r\n return {\r\n estimatedTokens: totalInput + totalOutput,\r\n estimatedCost: Math.round(totalCost * 10000) / 10000, // 4 decimal places\r\n breakdown: {\r\n inputTokens: totalInput,\r\n outputTokens: totalOutput,\r\n toolCalls: this.toolCallCount,\r\n contextTokens\r\n },\r\n model: this.model,\r\n confidence\r\n }\r\n }\r\n\r\n /**\r\n * Format cost for display\r\n */\r\n static formatCost(cost: number): string {\r\n if (cost < 0.01) return `$${(cost * 100).toFixed(2)}¢`\r\n if (cost < 1) return `$${cost.toFixed(3)}`\r\n return `$${cost.toFixed(2)}`\r\n }\r\n\r\n /**\r\n * Get cost projection for N more commands\r\n */\r\n projectCost(additionalCommands: number): CostEstimate {\r\n if (this.toolCallCount === 0) {\r\n // Use defaults if no data\r\n const projectedInput = additionalCommands * (AVG_TOOL_CALL_TOKENS + 50)\r\n const projectedOutput = additionalCommands * AVG_TOOL_RESULT_TOKENS\r\n\r\n const inputCost = (projectedInput / 1000) * this.pricing.inputPer1k\r\n const outputCost = (projectedOutput / 1000) * this.pricing.outputPer1k\r\n\r\n return {\r\n estimatedTokens: projectedInput + projectedOutput,\r\n estimatedCost: inputCost + outputCost,\r\n breakdown: {\r\n inputTokens: projectedInput,\r\n outputTokens: projectedOutput,\r\n toolCalls: additionalCommands,\r\n contextTokens: 0\r\n },\r\n model: this.model,\r\n confidence: 'low'\r\n }\r\n }\r\n\r\n // Project based on current averages\r\n const avgInputPerCall = this.totalInputTokens / this.toolCallCount\r\n const avgOutputPerCall = this.totalOutputTokens / this.toolCallCount\r\n\r\n const projectedInput = this.totalInputTokens + (additionalCommands * avgInputPerCall)\r\n const projectedOutput = this.totalOutputTokens + (additionalCommands * avgOutputPerCall)\r\n const contextTokens = Math.ceil((projectedInput + projectedOutput) * CONTEXT_OVERHEAD_RATIO)\r\n\r\n const totalInput = projectedInput + contextTokens\r\n const totalOutput = projectedOutput\r\n\r\n const inputCost = (totalInput / 1000) * this.pricing.inputPer1k\r\n const outputCost = (totalOutput / 1000) * this.pricing.outputPer1k\r\n\r\n return {\r\n estimatedTokens: totalInput + totalOutput,\r\n estimatedCost: inputCost + outputCost,\r\n breakdown: {\r\n inputTokens: Math.ceil(totalInput),\r\n outputTokens: Math.ceil(totalOutput),\r\n toolCalls: this.toolCallCount + additionalCommands,\r\n contextTokens\r\n },\r\n model: this.model,\r\n confidence: this.toolCallCount >= 10 ? 'high' : 'medium'\r\n }\r\n }\r\n\r\n /**\r\n * Set model for pricing\r\n */\r\n setModel(model: string): void {\r\n this.model = model\r\n this.pricing = MODEL_PRICING[model] || MODEL_PRICING['default']\r\n }\r\n\r\n /**\r\n * Reset counters\r\n */\r\n reset(): void {\r\n this.totalInputTokens = 0\r\n this.totalOutputTokens = 0\r\n this.toolCallCount = 0\r\n }\r\n\r\n /**\r\n * Add custom model pricing\r\n */\r\n static addModelPricing(model: string, pricing: ModelPricing): void {\r\n MODEL_PRICING[model] = pricing\r\n }\r\n}\r\n","/**\r\n * Session Reports\r\n * Generate human-readable reports of agent activity\r\n */\r\n\r\nimport type { SessionMetrics } from './metrics.js'\r\nimport type { CostEstimate } from './cost.js'\r\n\r\nexport interface ReportOptions {\r\n showCommands?: boolean\r\n showBlocked?: boolean\r\n showRisk?: boolean\r\n showPaths?: boolean\r\n showCost?: boolean\r\n format?: 'text' | 'json' | 'markdown'\r\n}\r\n\r\nconst DEFAULT_OPTIONS: ReportOptions = {\r\n showCommands: true,\r\n showBlocked: true,\r\n showRisk: true,\r\n showPaths: true,\r\n showCost: true,\r\n format: 'text'\r\n}\r\n\r\nexport class ReportGenerator {\r\n /**\r\n * Generate a session report\r\n */\r\n static generate(\r\n metrics: SessionMetrics,\r\n cost?: CostEstimate,\r\n options: ReportOptions = {}\r\n ): string {\r\n const opts = { ...DEFAULT_OPTIONS, ...options }\r\n\r\n switch (opts.format) {\r\n case 'json':\r\n return this.generateJSON(metrics, cost)\r\n case 'markdown':\r\n return this.generateMarkdown(metrics, cost, opts)\r\n default:\r\n return this.generateText(metrics, cost, opts)\r\n }\r\n }\r\n\r\n /**\r\n * Generate text report\r\n */\r\n private static generateText(\r\n metrics: SessionMetrics,\r\n cost?: CostEstimate,\r\n opts: ReportOptions = {}\r\n ): string {\r\n const lines: string[] = []\r\n const duration = this.formatDuration(metrics.duration)\r\n\r\n lines.push(`Session Report (${duration})`)\r\n lines.push('─'.repeat(45))\r\n lines.push('')\r\n\r\n // Summary line\r\n const blockedPct = metrics.commandCount > 0\r\n ? Math.round((metrics.blockedCount / metrics.commandCount) * 100)\r\n : 0\r\n lines.push(`Commands: ${metrics.commandCount} total, ${metrics.blockedCount} blocked (${blockedPct}%)`)\r\n lines.push('')\r\n\r\n // Risk distribution\r\n if (opts.showRisk) {\r\n const total = metrics.commandCount || 1\r\n const { safe, caution, dangerous, critical } = metrics.riskDistribution\r\n\r\n const safePct = Math.round((safe / total) * 100)\r\n const cautionPct = Math.round((caution / total) * 100)\r\n const dangerousPct = Math.round((dangerous / total) * 100)\r\n const criticalPct = Math.round((critical / total) * 100)\r\n\r\n lines.push('Risk Distribution:')\r\n lines.push(` ${this.progressBar(safePct, 20)} ${safePct}% safe`)\r\n lines.push(` ${this.progressBar(cautionPct, 20)} ${cautionPct}% caution`)\r\n lines.push(` ${this.progressBar(dangerousPct, 20)} ${dangerousPct}% dangerous`)\r\n if (critical > 0) {\r\n lines.push(` ${this.progressBar(criticalPct, 20)} ${criticalPct}% CRITICAL`)\r\n }\r\n lines.push(` Average risk score: ${metrics.avgRiskScore.toFixed(1)}/10`)\r\n lines.push('')\r\n }\r\n\r\n // Top commands\r\n if (opts.showCommands && metrics.topCommands.length > 0) {\r\n lines.push('Top Commands:')\r\n for (const [cmd, count] of metrics.topCommands.slice(0, 5)) {\r\n const pct = Math.round((count / metrics.commandCount) * 100)\r\n lines.push(` ${cmd.padEnd(15)} ${count.toString().padStart(3)} (${pct}%)`)\r\n }\r\n lines.push('')\r\n }\r\n\r\n // Blocked commands\r\n if (opts.showBlocked && metrics.blockedCount > 0) {\r\n lines.push('Violations by Type:')\r\n for (const [type, count] of Object.entries(metrics.violationsByType)) {\r\n lines.push(` ${type}: ${count}`)\r\n }\r\n lines.push('')\r\n }\r\n\r\n // Paths\r\n if (opts.showPaths) {\r\n if (metrics.filesModified.length > 0) {\r\n lines.push(`Files Modified: ${metrics.filesModified.length}`)\r\n for (const file of metrics.filesModified.slice(0, 5)) {\r\n lines.push(` • ${file}`)\r\n }\r\n if (metrics.filesModified.length > 5) {\r\n lines.push(` ... and ${metrics.filesModified.length - 5} more`)\r\n }\r\n lines.push('')\r\n }\r\n\r\n lines.push(`Paths Accessed: ${metrics.pathsAccessed.length} unique`)\r\n lines.push('')\r\n }\r\n\r\n // Cost estimate\r\n if (opts.showCost && cost) {\r\n lines.push('Cost Estimate:')\r\n lines.push(` Tokens: ~${cost.estimatedTokens.toLocaleString()} (${cost.confidence} confidence)`)\r\n lines.push(` Cost: ~${this.formatCost(cost.estimatedCost)} (${cost.model})`)\r\n lines.push('')\r\n }\r\n\r\n // Performance\r\n lines.push('Performance:')\r\n lines.push(` Avg execution time: ${metrics.avgExecutionTime.toFixed(0)}ms`)\r\n lines.push(` Total execution time: ${this.formatDuration(metrics.totalExecutionTime)}`)\r\n lines.push('')\r\n\r\n lines.push(`Session ID: ${metrics.sessionId}`)\r\n\r\n return lines.join('\\n')\r\n }\r\n\r\n /**\r\n * Generate markdown report\r\n */\r\n private static generateMarkdown(\r\n metrics: SessionMetrics,\r\n cost?: CostEstimate,\r\n opts: ReportOptions = {}\r\n ): string {\r\n const lines: string[] = []\r\n const duration = this.formatDuration(metrics.duration)\r\n\r\n lines.push(`# Session Report`)\r\n lines.push('')\r\n lines.push(`**Duration:** ${duration}`)\r\n lines.push(`**Session ID:** \\`${metrics.sessionId}\\``)\r\n lines.push('')\r\n\r\n // Summary table\r\n lines.push('## Summary')\r\n lines.push('')\r\n lines.push('| Metric | Value |')\r\n lines.push('|--------|-------|')\r\n lines.push(`| Commands | ${metrics.commandCount} |`)\r\n lines.push(`| Blocked | ${metrics.blockedCount} |`)\r\n lines.push(`| Unique Commands | ${metrics.uniqueCommands} |`)\r\n lines.push(`| Avg Risk Score | ${metrics.avgRiskScore.toFixed(1)}/10 |`)\r\n lines.push('')\r\n\r\n // Risk distribution\r\n if (opts.showRisk) {\r\n lines.push('## Risk Distribution')\r\n lines.push('')\r\n lines.push('| Level | Count | Percentage |')\r\n lines.push('|-------|-------|------------|')\r\n const total = metrics.commandCount || 1\r\n for (const [level, count] of Object.entries(metrics.riskDistribution)) {\r\n const pct = Math.round((count / total) * 100)\r\n lines.push(`| ${level} | ${count} | ${pct}% |`)\r\n }\r\n lines.push('')\r\n }\r\n\r\n // Top commands\r\n if (opts.showCommands && metrics.topCommands.length > 0) {\r\n lines.push('## Top Commands')\r\n lines.push('')\r\n lines.push('| Command | Count |')\r\n lines.push('|---------|-------|')\r\n for (const [cmd, count] of metrics.topCommands.slice(0, 10)) {\r\n lines.push(`| \\`${cmd}\\` | ${count} |`)\r\n }\r\n lines.push('')\r\n }\r\n\r\n // Cost\r\n if (opts.showCost && cost) {\r\n lines.push('## Cost Estimate')\r\n lines.push('')\r\n lines.push(`- **Tokens:** ~${cost.estimatedTokens.toLocaleString()}`)\r\n lines.push(`- **Cost:** ~${this.formatCost(cost.estimatedCost)}`)\r\n lines.push(`- **Model:** ${cost.model}`)\r\n lines.push(`- **Confidence:** ${cost.confidence}`)\r\n lines.push('')\r\n }\r\n\r\n return lines.join('\\n')\r\n }\r\n\r\n /**\r\n * Generate JSON report\r\n */\r\n private static generateJSON(\r\n metrics: SessionMetrics,\r\n cost?: CostEstimate\r\n ): string {\r\n return JSON.stringify({ metrics, cost }, null, 2)\r\n }\r\n\r\n /**\r\n * Generate a simple progress bar\r\n */\r\n private static progressBar(percent: number, width: number): string {\r\n const filled = Math.round((percent / 100) * width)\r\n const empty = width - filled\r\n return '█'.repeat(filled) + '░'.repeat(empty)\r\n }\r\n\r\n /**\r\n * Format duration\r\n */\r\n private static formatDuration(ms: number): string {\r\n if (ms < 1000) return `${ms}ms`\r\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`\r\n if (ms < 3600000) {\r\n const mins = Math.floor(ms / 60000)\r\n const secs = Math.floor((ms % 60000) / 1000)\r\n return `${mins}m ${secs}s`\r\n }\r\n const hours = Math.floor(ms / 3600000)\r\n const mins = Math.floor((ms % 3600000) / 60000)\r\n return `${hours}h ${mins}m`\r\n }\r\n\r\n /**\r\n * Format cost\r\n */\r\n private static formatCost(cost: number): string {\r\n if (cost < 0.01) return `$${(cost * 100).toFixed(2)}¢`\r\n if (cost < 1) return `$${cost.toFixed(3)}`\r\n return `$${cost.toFixed(2)}`\r\n }\r\n\r\n /**\r\n * Generate a one-line summary\r\n */\r\n static oneLine(metrics: SessionMetrics): string {\r\n const duration = this.formatDuration(metrics.duration)\r\n const blockedPct = metrics.commandCount > 0\r\n ? Math.round((metrics.blockedCount / metrics.commandCount) * 100)\r\n : 0\r\n\r\n return `${metrics.commandCount} cmds (${blockedPct}% blocked) | ` +\r\n `risk: ${metrics.avgRiskScore.toFixed(1)}/10 | ${duration}`\r\n }\r\n}\r\n","/**\r\n * Undo Stack\r\n * Track file changes for rollback capability\r\n */\r\n\r\nimport { existsSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, copyFileSync, readdirSync, statSync } from 'fs'\r\nimport { join, dirname, basename } from 'path'\r\nimport { homedir } from 'os'\r\nimport type { UndoPolicy } from '../types.js'\r\n\r\nexport interface UndoEntry {\r\n id: string\r\n timestamp: Date\r\n path: string\r\n operation: 'create' | 'modify' | 'delete'\r\n backupPath?: string\r\n originalContent?: string\r\n command?: string\r\n}\r\n\r\nexport interface UndoResult {\r\n success: boolean\r\n message: string\r\n entry?: UndoEntry\r\n}\r\n\r\nexport interface UndoConfig {\r\n maxStackSize: number\r\n maxFileSize: number\r\n ttlMinutes: number\r\n backupPath: string\r\n enabled: boolean\r\n}\r\n\r\nconst DEFAULT_CONFIG: UndoConfig = {\r\n maxStackSize: 100,\r\n maxFileSize: 10 * 1024 * 1024, // 10MB\r\n ttlMinutes: 60,\r\n backupPath: join(homedir(), '.bashbros', 'undo'),\r\n enabled: true\r\n}\r\n\r\nexport class UndoStack {\r\n private stack: UndoEntry[] = []\r\n private sessionId: string\r\n private config: UndoConfig\r\n private undoDir: string\r\n\r\n constructor(policy?: Partial<UndoPolicy>) {\r\n this.config = { ...DEFAULT_CONFIG }\r\n\r\n if (policy) {\r\n if (typeof policy.maxStackSize === 'number') this.config.maxStackSize = policy.maxStackSize\r\n if (typeof policy.maxFileSize === 'number') this.config.maxFileSize = policy.maxFileSize\r\n if (typeof policy.ttlMinutes === 'number') this.config.ttlMinutes = policy.ttlMinutes\r\n if (typeof policy.backupPath === 'string') {\r\n this.config.backupPath = policy.backupPath.replace('~', homedir())\r\n }\r\n if (typeof policy.enabled === 'boolean') this.config.enabled = policy.enabled\r\n }\r\n\r\n this.undoDir = this.config.backupPath\r\n this.sessionId = Date.now().toString(36)\r\n this.ensureUndoDir()\r\n\r\n // Clean up old backups on init\r\n this.cleanupOldBackups()\r\n }\r\n\r\n private ensureUndoDir(): void {\r\n if (!existsSync(this.undoDir)) {\r\n mkdirSync(this.undoDir, { recursive: true, mode: 0o700 })\r\n }\r\n }\r\n\r\n /**\r\n * Clean up backups older than TTL\r\n */\r\n cleanupOldBackups(): number {\r\n if (!this.config.enabled || this.config.ttlMinutes <= 0) return 0\r\n\r\n const cutoff = Date.now() - (this.config.ttlMinutes * 60 * 1000)\r\n let cleaned = 0\r\n\r\n try {\r\n const files = readdirSync(this.undoDir)\r\n\r\n for (const file of files) {\r\n if (!file.endsWith('.backup')) continue\r\n\r\n const filePath = join(this.undoDir, file)\r\n try {\r\n const stats = statSync(filePath)\r\n if (stats.mtimeMs < cutoff) {\r\n unlinkSync(filePath)\r\n cleaned++\r\n }\r\n } catch { /* ignore individual file errors */ }\r\n }\r\n } catch { /* ignore dir errors */ }\r\n\r\n return cleaned\r\n }\r\n\r\n private generateId(): string {\r\n return `${this.sessionId}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`\r\n }\r\n\r\n /**\r\n * Check if undo is enabled\r\n */\r\n isEnabled(): boolean {\r\n return this.config.enabled\r\n }\r\n\r\n /**\r\n * Record a file creation\r\n */\r\n recordCreate(path: string, command?: string): UndoEntry {\r\n const entry: UndoEntry = {\r\n id: this.generateId(),\r\n timestamp: new Date(),\r\n path,\r\n operation: 'create',\r\n command\r\n }\r\n\r\n this.push(entry)\r\n return entry\r\n }\r\n\r\n /**\r\n * Record a file modification (backs up original)\r\n */\r\n recordModify(path: string, command?: string): UndoEntry | null {\r\n if (!this.config.enabled || !existsSync(path)) {\r\n return null\r\n }\r\n\r\n // Check file size\r\n const stats = statSync(path)\r\n if (stats.size > this.config.maxFileSize) {\r\n // Too large, just record without backup\r\n const entry: UndoEntry = {\r\n id: this.generateId(),\r\n timestamp: new Date(),\r\n path,\r\n operation: 'modify',\r\n command\r\n }\r\n this.push(entry)\r\n return entry\r\n }\r\n\r\n // Create backup\r\n const id = this.generateId()\r\n const backupPath = join(this.undoDir, `${id}.backup`)\r\n\r\n try {\r\n copyFileSync(path, backupPath)\r\n\r\n const entry: UndoEntry = {\r\n id,\r\n timestamp: new Date(),\r\n path,\r\n operation: 'modify',\r\n backupPath,\r\n command\r\n }\r\n\r\n this.push(entry)\r\n return entry\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n /**\r\n * Record a file deletion (backs up content)\r\n */\r\n recordDelete(path: string, command?: string): UndoEntry | null {\r\n if (!this.config.enabled || !existsSync(path)) {\r\n return null\r\n }\r\n\r\n const stats = statSync(path)\r\n if (stats.size > this.config.maxFileSize) {\r\n // Too large, just record without backup\r\n const entry: UndoEntry = {\r\n id: this.generateId(),\r\n timestamp: new Date(),\r\n path,\r\n operation: 'delete',\r\n command\r\n }\r\n this.push(entry)\r\n return entry\r\n }\r\n\r\n // Create backup\r\n const id = this.generateId()\r\n const backupPath = join(this.undoDir, `${id}.backup`)\r\n\r\n try {\r\n copyFileSync(path, backupPath)\r\n\r\n const entry: UndoEntry = {\r\n id,\r\n timestamp: new Date(),\r\n path,\r\n operation: 'delete',\r\n backupPath,\r\n command\r\n }\r\n\r\n this.push(entry)\r\n return entry\r\n } catch {\r\n return null\r\n }\r\n }\r\n\r\n /**\r\n * Auto-detect operation from command\r\n */\r\n recordFromCommand(command: string, paths: string[]): UndoEntry[] {\r\n const entries: UndoEntry[] = []\r\n\r\n // Detect operation type\r\n const isCreate = /^(touch|mkdir|cp|mv|>|>>)/.test(command) ||\r\n /^(echo|cat|printf).*>/.test(command)\r\n const isDelete = /^rm\\s/.test(command)\r\n const isModify = /^(sed|awk|vim|vi|nano|code)\\s/.test(command) ||\r\n /^(echo|cat).*>>/.test(command)\r\n\r\n for (const path of paths) {\r\n let entry: UndoEntry | null = null\r\n\r\n if (isDelete && existsSync(path)) {\r\n entry = this.recordDelete(path, command)\r\n } else if (isModify && existsSync(path)) {\r\n entry = this.recordModify(path, command)\r\n } else if (isCreate && !existsSync(path)) {\r\n entry = this.recordCreate(path, command)\r\n }\r\n\r\n if (entry) {\r\n entries.push(entry)\r\n }\r\n }\r\n\r\n return entries\r\n }\r\n\r\n /**\r\n * Undo the last operation\r\n */\r\n undo(): UndoResult {\r\n const entry = this.stack.pop()\r\n\r\n if (!entry) {\r\n return { success: false, message: 'Nothing to undo' }\r\n }\r\n\r\n return this.undoEntry(entry)\r\n }\r\n\r\n /**\r\n * Undo a specific entry\r\n */\r\n undoEntry(entry: UndoEntry): UndoResult {\r\n try {\r\n switch (entry.operation) {\r\n case 'create':\r\n // Undo create = delete the file\r\n if (existsSync(entry.path)) {\r\n unlinkSync(entry.path)\r\n return {\r\n success: true,\r\n message: `Deleted created file: ${entry.path}`,\r\n entry\r\n }\r\n }\r\n return {\r\n success: false,\r\n message: `File already deleted: ${entry.path}`,\r\n entry\r\n }\r\n\r\n case 'modify':\r\n // Undo modify = restore from backup\r\n if (entry.backupPath && existsSync(entry.backupPath)) {\r\n copyFileSync(entry.backupPath, entry.path)\r\n return {\r\n success: true,\r\n message: `Restored: ${entry.path}`,\r\n entry\r\n }\r\n }\r\n return {\r\n success: false,\r\n message: `No backup available for: ${entry.path}`,\r\n entry\r\n }\r\n\r\n case 'delete':\r\n // Undo delete = restore from backup\r\n if (entry.backupPath && existsSync(entry.backupPath)) {\r\n // Ensure directory exists\r\n const dir = dirname(entry.path)\r\n if (!existsSync(dir)) {\r\n mkdirSync(dir, { recursive: true })\r\n }\r\n copyFileSync(entry.backupPath, entry.path)\r\n return {\r\n success: true,\r\n message: `Restored deleted file: ${entry.path}`,\r\n entry\r\n }\r\n }\r\n return {\r\n success: false,\r\n message: `No backup available for: ${entry.path}`,\r\n entry\r\n }\r\n\r\n default:\r\n return {\r\n success: false,\r\n message: `Unknown operation: ${entry.operation}`,\r\n entry\r\n }\r\n }\r\n } catch (error: any) {\r\n return {\r\n success: false,\r\n message: `Undo failed: ${error.message}`,\r\n entry\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Undo all operations in the session\r\n */\r\n undoAll(): UndoResult[] {\r\n const results: UndoResult[] = []\r\n\r\n while (this.stack.length > 0) {\r\n results.push(this.undo())\r\n }\r\n\r\n return results\r\n }\r\n\r\n /**\r\n * Get the undo stack\r\n */\r\n getStack(): UndoEntry[] {\r\n return [...this.stack]\r\n }\r\n\r\n /**\r\n * Get stack size\r\n */\r\n size(): number {\r\n return this.stack.length\r\n }\r\n\r\n /**\r\n * Clear the stack (and backups)\r\n */\r\n clear(): void {\r\n // Delete backup files\r\n for (const entry of this.stack) {\r\n if (entry.backupPath && existsSync(entry.backupPath)) {\r\n try {\r\n unlinkSync(entry.backupPath)\r\n } catch { /* ignore */ }\r\n }\r\n }\r\n\r\n this.stack = []\r\n }\r\n\r\n /**\r\n * Push entry to stack\r\n */\r\n private push(entry: UndoEntry): void {\r\n this.stack.push(entry)\r\n\r\n // Limit stack size\r\n if (this.stack.length > this.config.maxStackSize) {\r\n const removed = this.stack.shift()\r\n // Clean up backup\r\n if (removed?.backupPath && existsSync(removed.backupPath)) {\r\n try {\r\n unlinkSync(removed.backupPath)\r\n } catch { /* ignore */ }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Format stack for display\r\n */\r\n formatStack(): string {\r\n if (this.stack.length === 0) {\r\n return 'Undo stack is empty'\r\n }\r\n\r\n const lines: string[] = ['Undo Stack:', '']\r\n\r\n for (let i = this.stack.length - 1; i >= 0; i--) {\r\n const entry = this.stack[i]\r\n const hasBackup = entry.backupPath ? '✓' : '✗'\r\n const time = entry.timestamp.toLocaleTimeString()\r\n const op = entry.operation.padEnd(6)\r\n\r\n lines.push(`${i + 1}. [${time}] ${op} ${entry.path} (backup: ${hasBackup})`)\r\n if (entry.command) {\r\n lines.push(` └─ ${entry.command.slice(0, 60)}...`)\r\n }\r\n }\r\n\r\n return lines.join('\\n')\r\n }\r\n}\r\n"],"mappings":"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","names":["EventEmitter","EventEmitter","result","DEFAULT_CONFIG","existsSync","readFileSync","homedir","join","writeFileSync","mkdirSync","spawn","EventEmitter","execFileSync","EventEmitter","EventEmitter","execFileSync","projectedInput","projectedOutput","inputCost","outputCost","mins","existsSync","mkdirSync","join","homedir","DEFAULT_CONFIG"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
loadConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RTZ4QWG2.js";
|
|
5
5
|
|
|
6
6
|
// src/transparency/display.ts
|
|
7
7
|
import chalk from "chalk";
|
|
@@ -11,6 +11,7 @@ var AGENT_DISPLAY_NAMES = {
|
|
|
11
11
|
"clawdbot": "Clawdbot (legacy)",
|
|
12
12
|
"aider": "Aider",
|
|
13
13
|
"gemini-cli": "Gemini CLI",
|
|
14
|
+
"copilot-cli": "Copilot CLI",
|
|
14
15
|
"opencode": "OpenCode",
|
|
15
16
|
"custom": "Custom Agent"
|
|
16
17
|
};
|
|
@@ -210,4 +211,4 @@ export {
|
|
|
210
211
|
formatPermissionsTable,
|
|
211
212
|
formatAgentSummary
|
|
212
213
|
};
|
|
213
|
-
//# sourceMappingURL=chunk-
|
|
214
|
+
//# sourceMappingURL=chunk-CG6VEHJM.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/transparency/display.ts"],"sourcesContent":["/**\n * Display utilities for agent transparency\n * Formats agent info and permissions for CLI output\n */\n\nimport chalk from 'chalk'\nimport type { AgentConfigInfo, EffectivePermissions, AgentType } from '../types.js'\nimport { loadConfig } from '../config.js'\n\n// Human-readable agent names\nconst AGENT_DISPLAY_NAMES: Record<AgentType, string> = {\n 'claude-code': 'Claude Code',\n 'moltbot': 'Moltbot',\n 'clawdbot': 'Clawdbot (legacy)',\n 'aider': 'Aider',\n 'gemini-cli': 'Gemini CLI',\n 'copilot-cli': 'Copilot CLI',\n 'opencode': 'OpenCode',\n 'custom': 'Custom Agent'\n}\n\n/**\n * Format a single agent's info for display\n */\nexport function formatAgentInfo(info: AgentConfigInfo): string {\n const lines: string[] = []\n const name = AGENT_DISPLAY_NAMES[info.agent] || info.agent\n\n lines.push(chalk.bold(`${name} (${info.agent})`))\n\n // Status\n const statusIcon = info.installed ? chalk.green('Installed') : chalk.dim('Not found')\n lines.push(` Status: ${statusIcon}`)\n\n if (info.version) {\n lines.push(` Version: ${info.version}`)\n }\n\n // Config\n if (info.configPath) {\n const configStatus = info.configExists ? chalk.green(info.configPath) : chalk.yellow(`${info.configPath} (not found)`)\n lines.push(` Config: ${configStatus}`)\n } else {\n lines.push(` Config: ${chalk.dim('No known config location')}`)\n }\n\n if (info.lastModified) {\n lines.push(` Modified: ${info.lastModified.toLocaleDateString()} ${info.lastModified.toLocaleTimeString()}`)\n }\n\n // Hooks\n if (info.hooks && info.hooks.length > 0) {\n lines.push(` Hooks: ${info.hooks.join(', ')}`)\n }\n\n // Permissions\n if (info.permissions) {\n lines.push(` Permissions:`)\n\n if (info.permissions.allowedPaths && info.permissions.allowedPaths.length > 0) {\n const paths = info.permissions.allowedPaths.slice(0, 5).join(', ')\n const more = info.permissions.allowedPaths.length > 5 ? ` (+${info.permissions.allowedPaths.length - 5} more)` : ''\n lines.push(` Allowed paths: ${paths}${more}`)\n }\n\n if (info.permissions.blockedCommands && info.permissions.blockedCommands.length > 0) {\n lines.push(` Blocked commands: ${info.permissions.blockedCommands.length} patterns`)\n }\n\n if (info.permissions.rateLimit) {\n lines.push(` Rate limit: ${info.permissions.rateLimit}`)\n }\n\n if (info.permissions.securityProfile) {\n lines.push(` Security profile: ${info.permissions.securityProfile}`)\n }\n }\n\n // BashBros integration\n const integrationStatus = info.bashbrosIntegrated\n ? chalk.green('Hooks installed')\n : chalk.yellow('Not integrated (no hooks)')\n lines.push(` Bashbros: ${integrationStatus}`)\n\n return lines.join('\\n')\n}\n\n/**\n * Format all agents info\n */\nexport function formatAllAgentsInfo(agents: AgentConfigInfo[]): string {\n const lines: string[] = [\n chalk.bold.cyan('AGENT CONFIGURATIONS'),\n chalk.dim('='.repeat(40)),\n ''\n ]\n\n const installed = agents.filter(a => a.installed)\n const notInstalled = agents.filter(a => !a.installed)\n\n if (installed.length === 0) {\n lines.push(chalk.yellow('No agents detected.'))\n lines.push('')\n } else {\n for (const agent of installed) {\n lines.push(formatAgentInfo(agent))\n lines.push('')\n }\n }\n\n // Show not-installed agents briefly\n if (notInstalled.length > 0) {\n lines.push(chalk.dim('Other known agents (not installed):'))\n lines.push(chalk.dim(' ' + notInstalled.map(a => AGENT_DISPLAY_NAMES[a.agent]).join(', ')))\n }\n\n return lines.join('\\n')\n}\n\n/**\n * Calculate effective permissions by combining bashbros config with agent config\n */\nexport function getEffectivePermissions(agentInfo: AgentConfigInfo): EffectivePermissions {\n const bashbrosConfig = loadConfig()\n\n // Get bashbros settings\n const bashbrosPaths = bashbrosConfig.paths.allow\n const bashbrosBlocked = bashbrosConfig.commands.block\n const bashbrosRiskThreshold = bashbrosConfig.riskScoring.blockThreshold\n const bashbrosRateLimit = bashbrosConfig.rateLimit.maxPerMinute\n\n // Get agent settings\n const agentPaths = agentInfo.permissions?.allowedPaths || []\n const agentBlocked = agentInfo.permissions?.blockedCommands || []\n const agentRiskThreshold = typeof agentInfo.permissions?.rateLimit === 'number'\n ? agentInfo.permissions.rateLimit\n : null\n const agentRateLimit = null // Most agents don't have rate limits in their config\n\n // Calculate effective (most restrictive)\n // For paths: intersection if both have values, otherwise the one that exists\n let effectivePaths: string[]\n if (bashbrosPaths.length > 0 && agentPaths.length > 0) {\n // Find paths that appear in both (simplified intersection)\n effectivePaths = bashbrosPaths.filter(bp =>\n agentPaths.some(ap => ap === bp || bp.startsWith(ap) || ap.startsWith(bp))\n )\n if (effectivePaths.length === 0) {\n effectivePaths = bashbrosPaths // Fall back to bashbros if no overlap\n }\n } else {\n effectivePaths = bashbrosPaths.length > 0 ? bashbrosPaths : agentPaths\n }\n\n // For blocked commands: union\n const effectiveBlocked = Array.from(new Set([...bashbrosBlocked, ...agentBlocked]))\n\n // For numeric thresholds: use the more restrictive (lower) value\n const effectiveRiskThreshold = agentRiskThreshold !== null\n ? Math.min(bashbrosRiskThreshold, agentRiskThreshold)\n : bashbrosRiskThreshold\n\n const effectiveRateLimit = agentRateLimit !== null\n ? Math.min(bashbrosRateLimit, agentRateLimit)\n : bashbrosRateLimit\n\n return {\n allowedPaths: {\n bashbros: bashbrosPaths,\n agent: agentPaths,\n effective: effectivePaths\n },\n riskThreshold: {\n bashbros: bashbrosRiskThreshold,\n agent: agentRiskThreshold,\n effective: effectiveRiskThreshold\n },\n rateLimit: {\n bashbros: bashbrosRateLimit,\n agent: agentRateLimit,\n effective: effectiveRateLimit\n },\n blockedCommands: {\n bashbros: bashbrosBlocked,\n agent: agentBlocked,\n effective: effectiveBlocked\n }\n }\n}\n\n/**\n * Format permissions comparison table\n */\nexport function formatPermissionsTable(\n agents: AgentConfigInfo[]\n): string {\n const lines: string[] = [\n chalk.bold.cyan('EFFECTIVE PERMISSIONS'),\n chalk.dim('='.repeat(40)),\n ''\n ]\n\n const config = loadConfig()\n\n // Header row\n const installedAgents = agents.filter(a => a.installed)\n const agentHeaders = installedAgents.map(a => AGENT_DISPLAY_NAMES[a.agent].padEnd(12))\n\n lines.push(chalk.bold(' Bashbros ' + agentHeaders.join(' ') + ' Effective'))\n lines.push(chalk.dim('-'.repeat(80)))\n\n // Allowed paths\n const bashbrosPaths = config.paths.allow.slice(0, 3).join(', ') || '*'\n lines.push(`Allowed paths: ${bashbrosPaths.padEnd(12)}`)\n\n for (const agent of installedAgents) {\n const perms = getEffectivePermissions(agent)\n const agentPaths = perms.allowedPaths.agent.slice(0, 2).join(', ') || 'none'\n const effectivePaths = perms.allowedPaths.effective.slice(0, 2).join(', ') || '*'\n\n lines[lines.length - 1] += `${agentPaths.padEnd(12)} `\n\n if (agent === installedAgents[installedAgents.length - 1]) {\n lines[lines.length - 1] += effectivePaths\n }\n }\n\n // Risk threshold\n const bashbrosRisk = config.riskScoring.blockThreshold\n let riskLine = `Risk threshold: ${bashbrosRisk.toString().padEnd(12)}`\n\n for (const agent of installedAgents) {\n const perms = getEffectivePermissions(agent)\n const agentRisk = perms.riskThreshold.agent !== null ? perms.riskThreshold.agent.toString() : 'none'\n riskLine += `${agentRisk.padEnd(12)} `\n\n if (agent === installedAgents[installedAgents.length - 1]) {\n const effectiveRisk = perms.riskThreshold.effective\n const note = effectiveRisk < bashbrosRisk ? ' (stricter)' : ''\n riskLine += `${effectiveRisk}${note}`\n }\n }\n lines.push(riskLine)\n\n // Rate limit\n const bashbrosRate = `${config.rateLimit.maxPerMinute}/min`\n let rateLine = `Rate limit: ${bashbrosRate.padEnd(12)}`\n\n for (const agent of installedAgents) {\n const perms = getEffectivePermissions(agent)\n const agentRate = perms.rateLimit.agent !== null ? `${perms.rateLimit.agent}/min` : 'none'\n rateLine += `${agentRate.padEnd(12)} `\n\n if (agent === installedAgents[installedAgents.length - 1]) {\n rateLine += `${perms.rateLimit.effective}/min`\n }\n }\n lines.push(rateLine)\n\n // Blocked commands count\n const bashbrosBlocked = config.commands.block.length\n let blockedLine = `Blocked commands: ${bashbrosBlocked.toString().padEnd(12)}`\n\n for (const agent of installedAgents) {\n const perms = getEffectivePermissions(agent)\n const agentBlocked = perms.blockedCommands.agent.length\n blockedLine += `${agentBlocked.toString().padEnd(12)} `\n\n if (agent === installedAgents[installedAgents.length - 1]) {\n blockedLine += perms.blockedCommands.effective.length.toString()\n }\n }\n lines.push(blockedLine)\n\n lines.push('')\n lines.push(chalk.dim('Note: Effective = most restrictive combination of all policies'))\n\n return lines.join('\\n')\n}\n\n/**\n * Format a brief summary for scan output\n */\nexport function formatAgentSummary(agents: AgentConfigInfo[]): string {\n const lines: string[] = []\n const installed = agents.filter(a => a.installed)\n\n if (installed.length === 0) {\n lines.push(chalk.dim(' No agents detected'))\n return lines.join('\\n')\n }\n\n for (const agent of installed) {\n const name = AGENT_DISPLAY_NAMES[agent.agent]\n const config = agent.configExists\n ? chalk.green('configured')\n : chalk.yellow('no config')\n const integration = agent.bashbrosIntegrated\n ? chalk.green('integrated')\n : chalk.dim('not integrated')\n\n lines.push(` ${name}: ${config}, ${integration}`)\n }\n\n return lines.join('\\n')\n}\n"],"mappings":"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","names":[]}
|