ESLint Plugin

Package: eslint-plugin-mima

The ESLint plugin catches AI library calls that are not wrapped with mima.attest() at lint time — before the guard can detect them at runtime, and before the TypeScript SDK can wrap them.

It answers the question: “Do I have unattested AI calls in my TypeScript/JavaScript code?”


Install

$npm install --save-dev eslint-plugin-mima

Configure

1// eslint.config.js
2import mima from 'eslint-plugin-mima';
3
4export default [
5 {
6 plugins: { mima },
7 rules: {
8 'mima/no-unattested-ai-call': 'error',
9 },
10 },
11];

Legacy .eslintrc

1{
2 "plugins": ["mima"],
3 "rules": {
4 "mima/no-unattested-ai-call": "error"
5 }
6}

Rule: no-unattested-ai-call

Flags direct calls to AI library methods that are not inside a mima.wrap() or mima.push() call.

What it detects

1// Error — unattested OpenAI call
2const response = await openai.chat.completions.create({ ... });
3
4// Error — unattested Anthropic call
5const msg = await anthropic.messages.create({ ... });

What it allows

1// OK — wrapped with mima
2const generate = mima.wrap('generate', async (prompt: string) => {
3 return await openai.chat.completions.create({ ... });
4});
5
6// OK — explicit push handles attestation separately
7const result = await pipeline.run(input);
8await mima.push('pipeline', inputHash, outputHash);

AI libraries detected

LibraryMethods flagged
openaichat.completions.create, completions.create
@anthropic-ai/sdkmessages.create, messages.stream
@google/generative-aigenerateContent, generateContentStream
@azure/openaigetChatCompletions
ai (Vercel AI SDK)generateText, streamText, generateObject
langchaininvoke, stream, call on LLM/Chain classes

Severity levels

1// Warn in development, error in CI:
2'mima/no-unattested-ai-call': process.env.CI ? 'error' : 'warn'

Inline disable

When you intentionally make an unattested call (e.g. a health-check ping):

1// eslint-disable-next-line mima/no-unattested-ai-call
2const ping = await openai.models.list();

CI integration

Add to your CI pipeline to block merges with unattested AI calls:

1# .github/workflows/lint.yml
2- name: Lint
3 run: npx eslint src --ext .ts,.tsx

The rule reports a non-zero exit code on violations, blocking the merge.


Relationship to the runtime guard

LayerWhen it runsWhat it catches
ESLint pluginAt lint time / in editorStatically detectable unattested calls
Python OTEL guardAt runtimeAll unattested calls, including dynamic ones
TypeScript mima.wrap()At the call siteForces wrapping at the source

Use all three for defence-in-depth. The ESLint plugin is the earliest signal; the runtime guard catches what static analysis misses.