Hooks

Hooks allow you to run custom scripts at specific points during Tabnine CLI's agent loop, enabling you to intercept and customize behavior without modifying the CLI itself.

What are hooks?

Hooks run synchronously as part of the agent loop — when a hook event fires, Tabnine CLI waits for all matching hooks to complete before continuing.

With hooks, you can:

  • Add context: Inject relevant information (like git history or project state) before the model processes a request.

  • Validate actions: Review tool arguments and block potentially dangerous operations.

  • Enforce policies: Implement security scanners and compliance checks.

  • Modify inputs: Rewrite tool arguments before execution (e.g., enforcing file path restrictions).

  • Log interactions: Track tool usage and model responses for auditing.

Quick start

Add two files to any git-initialized project:

.tabnine/agent/settings.json

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node ./hooks/announce.js",
            "name": "announce"
          }
        ]
      }
    ]
  }
}

hooks/announce.js

Start Tabnine CLI in that project — you'll see 🪝 Hooks are working! Session started. printed in the terminal.

Communication protocol

Hooks communicate with Tabnine CLI via JSON on standard I/O:

  • Input: JSON is written to the hook's stdin.

  • Output: The hook writes JSON to stdout.

  • Logging: Use stderr for all debug output. Tabnine CLI never parses stderr as JSON.

Exit codes

Exit Code
Label
Behavior

0

Success

stdout is parsed as JSON. Preferred for all logic, including intentional blocks (use "decision": "deny" in JSON).

2

System Block

The action is blocked. stderr is used as the rejection reason.

Other

Warning

Non-fatal failure. A warning is shown, but execution proceeds normally.

Base input schema

All hooks receive these common fields via stdin:

Common output fields

Field
Type
Description

decision

string

"allow" or "deny" (alias "block"). Impact depends on the event.

reason

string

Feedback message when decision is "deny".

systemMessage

string

Displayed immediately to the user in the terminal.

continue

boolean

If false, stops the entire agent loop immediately.

stopReason

string

Displayed to the user when continue is false.

suppressOutput

boolean

If true, hides internal hook metadata from logs/telemetry.

Environment variables

Hooks are executed with a sanitized environment. The following variables are always available:

Variable
Description

TABNINE_PROJECT_DIR

Absolute path to the project root.

CLAUDE_PROJECT_DIR

Alias of TABNINE_PROJECT_DIR (compatibility).

Additionally, these variables are expanded in the command string before execution:

  • $TABNINE_PROJECT_DIR

  • $GEMINI_PROJECT_DIR (expanded to the same value)

  • $CLAUDE_PROJECT_DIR (expanded to the same value)

Custom environment variables can be added per-hook using the env field in hook configuration.

Hook events

Tabnine CLI supports 11 hook events:

Event
When it fires
Can block?
Common use cases

SessionStart

When a session begins (startup, resume, clear)

No

Initialize resources, inject context

SessionEnd

When a session ends (exit, clear)

No

Clean up, save state

BeforeAgent

After user submits prompt, before planning

Yes

Add context, validate prompts

AfterAgent

After the model responds

Yes

Review output, force retry

BeforeModel

Before sending request to the LLM

Yes

Modify prompts, mock responses

AfterModel

After receiving LLM response

Yes

Filter/redact responses

BeforeToolSelection

Before the LLM selects tools

No

Filter available tools

BeforeTool

Before a tool executes

Yes

Validate arguments, block dangerous ops

AfterTool

After a tool executes

Yes

Process results, inject context

PreCompress

Before context compression

No

Save state, notify user

Notification

When a system notification occurs

No

Forward alerts, logging

Next steps

Last updated

Was this helpful?