Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
5.7 kB · 170 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171/** * Auto mode subcommand handlers — dump default/merged classifier rules and * critique user-written rules. Dynamically imported when `claude auto-mode ...` runs. */
import { errorMessage } from '../../utils/errors.js'import { getMainLoopModel, parseUserSpecifiedModel,} from '../../utils/model/model.js'import { type AutoModeRules, buildDefaultExternalSystemPrompt, getDefaultExternalAutoModeRules,} from '../../utils/permissions/yoloClassifier.js'import { getAutoModeConfig } from '../../utils/settings/settings.js'import { sideQuery } from '../../utils/sideQuery.js'import { jsonStringify } from '../../utils/slowOperations.js'
function writeRules(rules: AutoModeRules): void { process.stdout.write(jsonStringify(rules, null, 2) + '\n')}
export function autoModeDefaultsHandler(): void { writeRules(getDefaultExternalAutoModeRules())}
/** * Dump the effective auto mode config: user settings where provided, external * defaults otherwise. Per-section REPLACE semantics — matches how * buildYoloSystemPrompt resolves the external template (a non-empty user * section replaces that section's defaults entirely; an empty/absent section * falls through to defaults). */export function autoModeConfigHandler(): void { const config = getAutoModeConfig() const defaults = getDefaultExternalAutoModeRules() writeRules({ allow: config?.allow?.length ? config.allow : defaults.allow, soft_deny: config?.soft_deny?.length ? config.soft_deny : defaults.soft_deny, environment: config?.environment?.length ? config.environment : defaults.environment, })}
const CRITIQUE_SYSTEM_PROMPT = 'You are an expert reviewer of auto mode classifier rules for Claude Code.\n' + '\n' + 'Claude Code has an "auto mode" that uses an AI classifier to decide whether ' + 'tool calls should be auto-approved or require user confirmation. Users can ' + 'write custom rules in three categories:\n' + '\n' + '- **allow**: Actions the classifier should auto-approve\n' + '- **soft_deny**: Actions the classifier should block (require user confirmation)\n' + "- **environment**: Context about the user's setup that helps the classifier make decisions\n" + '\n' + "Your job is to critique the user's custom rules for clarity, completeness, " + 'and potential issues. The classifier is an LLM that reads these rules as ' + 'part of its system prompt.\n' + '\n' + 'For each rule, evaluate:\n' + '1. **Clarity**: Is the rule unambiguous? Could the classifier misinterpret it?\n' + "2. **Completeness**: Are there gaps or edge cases the rule doesn't cover?\n" + '3. **Conflicts**: Do any of the rules conflict with each other?\n' + '4. **Actionability**: Is the rule specific enough for the classifier to act on?\n' + '\n' + 'Be concise and constructive. Only comment on rules that could be improved. ' + 'If all rules look good, say so.'
export async function autoModeCritiqueHandler(options: { model?: string}): Promise<void> { const config = getAutoModeConfig() const hasCustomRules = (config?.allow?.length ?? 0) > 0 || (config?.soft_deny?.length ?? 0) > 0 || (config?.environment?.length ?? 0) > 0
if (!hasCustomRules) { process.stdout.write( 'No custom auto mode rules found.\n\n' + 'Add rules to your settings file under autoMode.{allow, soft_deny, environment}.\n' + 'Run `claude auto-mode defaults` to see the default rules for reference.\n', ) return }
const model = options.model ? parseUserSpecifiedModel(options.model) : getMainLoopModel()
const defaults = getDefaultExternalAutoModeRules() const classifierPrompt = buildDefaultExternalSystemPrompt()
const userRulesSummary = formatRulesForCritique('allow', config?.allow ?? [], defaults.allow) + formatRulesForCritique( 'soft_deny', config?.soft_deny ?? [], defaults.soft_deny, ) + formatRulesForCritique( 'environment', config?.environment ?? [], defaults.environment, )
process.stdout.write('Analyzing your auto mode rules…\n\n')
let response try { response = await sideQuery({ querySource: 'auto_mode_critique', model, system: CRITIQUE_SYSTEM_PROMPT, skipSystemPromptPrefix: true, max_tokens: 4096, messages: [ { role: 'user', content: 'Here is the full classifier system prompt that the auto mode classifier receives:\n\n' + '<classifier_system_prompt>\n' + classifierPrompt + '\n</classifier_system_prompt>\n\n' + "Here are the user's custom rules that REPLACE the corresponding default sections:\n\n" + userRulesSummary + '\nPlease critique these custom rules.', }, ], }) } catch (error) { process.stderr.write( 'Failed to analyze rules: ' + errorMessage(error) + '\n', ) process.exitCode = 1 return }
const textBlock = response.content.find(block => block.type === 'text') if (textBlock?.type === 'text') { process.stdout.write(textBlock.text + '\n') } else { process.stdout.write('No critique was generated. Please try again.\n') }}
function formatRulesForCritique( section: string, userRules: string[], defaultRules: string[],): string { if (userRules.length === 0) return '' const customLines = userRules.map(r => '- ' + r).join('\n') const defaultLines = defaultRules.map(r => '- ' + r).join('\n') return ( '## ' + section + ' (custom rules replacing defaults)\n' + 'Custom:\n' + customLines + '\n\n' + 'Defaults being replaced:\n' + defaultLines + '\n\n' )}