classifierApprovals.ts
1 /** 2 * Tracks which tool uses were auto-approved by classifiers. 3 * Populated from useCanUseTool.ts and permissions.ts, read from UserToolSuccessMessage.tsx. 4 */ 5 6 import { feature } from 'bun:bundle' 7 import { createSignal } from './signal.js' 8 9 type ClassifierApproval = { 10 classifier: 'bash' | 'auto-mode' 11 matchedRule?: string 12 reason?: string 13 } 14 15 const CLASSIFIER_APPROVALS = new Map<string, ClassifierApproval>() 16 const CLASSIFIER_CHECKING = new Set<string>() 17 const classifierChecking = createSignal() 18 19 export function setClassifierApproval( 20 toolUseID: string, 21 matchedRule: string, 22 ): void { 23 if (!feature('BASH_CLASSIFIER')) { 24 return 25 } 26 CLASSIFIER_APPROVALS.set(toolUseID, { 27 classifier: 'bash', 28 matchedRule, 29 }) 30 } 31 32 export function getClassifierApproval(toolUseID: string): string | undefined { 33 if (!feature('BASH_CLASSIFIER')) { 34 return undefined 35 } 36 const approval = CLASSIFIER_APPROVALS.get(toolUseID) 37 if (!approval || approval.classifier !== 'bash') return undefined 38 return approval.matchedRule 39 } 40 41 export function setYoloClassifierApproval( 42 toolUseID: string, 43 reason: string, 44 ): void { 45 if (!feature('TRANSCRIPT_CLASSIFIER')) { 46 return 47 } 48 CLASSIFIER_APPROVALS.set(toolUseID, { classifier: 'auto-mode', reason }) 49 } 50 51 export function getYoloClassifierApproval( 52 toolUseID: string, 53 ): string | undefined { 54 if (!feature('TRANSCRIPT_CLASSIFIER')) { 55 return undefined 56 } 57 const approval = CLASSIFIER_APPROVALS.get(toolUseID) 58 if (!approval || approval.classifier !== 'auto-mode') return undefined 59 return approval.reason 60 } 61 62 export function setClassifierChecking(toolUseID: string): void { 63 if (!feature('BASH_CLASSIFIER') && !feature('TRANSCRIPT_CLASSIFIER')) return 64 CLASSIFIER_CHECKING.add(toolUseID) 65 classifierChecking.emit() 66 } 67 68 export function clearClassifierChecking(toolUseID: string): void { 69 if (!feature('BASH_CLASSIFIER') && !feature('TRANSCRIPT_CLASSIFIER')) return 70 CLASSIFIER_CHECKING.delete(toolUseID) 71 classifierChecking.emit() 72 } 73 74 export const subscribeClassifierChecking = classifierChecking.subscribe 75 76 export function isClassifierChecking(toolUseID: string): boolean { 77 return CLASSIFIER_CHECKING.has(toolUseID) 78 } 79 80 export function deleteClassifierApproval(toolUseID: string): void { 81 CLASSIFIER_APPROVALS.delete(toolUseID) 82 } 83 84 export function clearClassifierApprovals(): void { 85 CLASSIFIER_APPROVALS.clear() 86 CLASSIFIER_CHECKING.clear() 87 classifierChecking.emit() 88 }