File size: 2,374 Bytes
064bfd6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import { feature } from 'bun:bundle'
import type { PendingClassifierCheck } from '../../../types/permissions.js'
import { logError } from '../../../utils/log.js'
import type { PermissionDecision } from '../../../utils/permissions/PermissionResult.js'
import type { PermissionUpdate } from '../../../utils/permissions/PermissionUpdateSchema.js'
import type { PermissionContext } from '../PermissionContext.js'
type CoordinatorPermissionParams = {
ctx: PermissionContext
pendingClassifierCheck?: PendingClassifierCheck | undefined
updatedInput: Record<string, unknown> | undefined
suggestions: PermissionUpdate[] | undefined
permissionMode: string | undefined
}
/**
* Handles the coordinator worker permission flow.
*
* For coordinator workers, automated checks (hooks and classifier) are
* awaited sequentially before falling through to the interactive dialog.
*
* Returns a PermissionDecision if the automated checks resolved the
* permission, or null if the caller should fall through to the
* interactive dialog.
*/
async function handleCoordinatorPermission(
params: CoordinatorPermissionParams,
): Promise<PermissionDecision | null> {
const { ctx, updatedInput, suggestions, permissionMode } = params
try {
// 1. Try permission hooks first (fast, local)
const hookResult = await ctx.runHooks(
permissionMode,
suggestions,
updatedInput,
)
if (hookResult) return hookResult
// 2. Try classifier (slow, inference -- bash only)
const classifierResult = feature('BASH_CLASSIFIER')
? await ctx.tryClassifier?.(params.pendingClassifierCheck, updatedInput)
: null
if (classifierResult) {
return classifierResult
}
} catch (error) {
// If automated checks fail unexpectedly, fall through to show the dialog
// so the user can decide manually. Non-Error throws get a context prefix
// so the log is traceable — intentionally NOT toError(), which would drop
// the prefix.
if (error instanceof Error) {
logError(error)
} else {
logError(new Error(`Automated permission check failed: ${String(error)}`))
}
}
// 3. Neither resolved (or checks failed) -- fall through to dialog below.
// Hooks already ran, classifier already consumed.
return null
}
export { handleCoordinatorPermission }
export type { CoordinatorPermissionParams }
|