Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 16x 16x | export const filename = 'eslint-hook.ts';
export const content = `/**
* ESLint Validation Hook
*
* Usage: Attach as 'after' hook to 'create_file', 'overwrite_file', 'patch'.
*
* With native tool calling, errors should be returned in the result object
* instead of pushing to validationErrors. This hook is kept for reference
* but may need adjustment based on your use case.
*/
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
// Redefining types locally since this runs in a standalone VM context
export interface HookContext {
action: {
tool_name: string;
args: { file_path?: string; [key: string]: any };
result?: {
status: 'SUCCESS' | 'FAILURE';
output?: string;
error?: string;
};
};
plan_context: {
flags: {
should_halt: boolean;
halt_reason?: string;
};
};
}
export default async function(context: HookContext) {
const filePath = context.action.args.file_path;
if (!filePath) return;
console.log(\`[Hook] Running ESLint on \${filePath}\`);
try {
// Adjust command as needed for your project structure
// We use --no-color to keep error message clean for AI
await execAsync(\`npx eslint "\${filePath}" --no-color\`);
console.log(\`[Hook] ESLint passed for \${filePath}\`);
} catch (e: any) {
const errorOutput = e.stdout || e.stderr || e.message;
console.log(\`[Hook] ESLint failed for \${filePath}\`);
// Log the error - it will be captured in execution logs
// The AI will see this in the tool result via native tool calling
console.error(\`ESLint check failed:\\n\${errorOutput}\`);
// Optionally halt the plan if ESLint fails critically
// context.plan_context.flags.should_halt = true;
// context.plan_context.flags.halt_reason = \`ESLint failed: \${errorOutput}\`;
}
}
`;
|