Skip to content

tailtest for Cursor

tailtest fires a test cycle at the end of every Cursor agent turn -- automatically, with no prompting.

How the cycle works:

  1. While the agent is working, the afterFileEdit hook records every file it writes
  2. When the turn ends, the stop hook sends a tailtest: run tests for: message
  3. Cursor re-enters the agent with that message -- the agent generates scenarios, writes test code, runs it, and reports only failures

Pass = completely silent. Fail = the agent surfaces the failure before moving on.


Requirements

  • Cursor 0.40 or later (hooks support required)
  • Python 3.8+ in your PATH
python3 --version   # must be 3.8+

Install

From the Cursor Marketplace (recommended):

Search for Tailtest in the Cursor plugin marketplace and click Install. Restart Cursor.

Manual:

git clone https://github.com/avansaber/tailtest-cursor \
  ~/.cursor/plugins/local/tailtest-cursor

Restart Cursor after cloning.


Verify it's active

Open a Cursor composer session and type:

what plugins do you have active?

Or just start a project session, let the agent write a file, and watch for a tailtest: run tests for: message at the end of the turn.


Complexity scoring

tailtest scores every queued file before generating scenarios. Path signals (auth, billing, payment, checkout) and content patterns (HTTP calls, database queries, branch count, public functions) contribute to a score. Files scoring 10 or above get thorough-depth testing (10-15 scenarios) regardless of the session-level depth setting, and the agent sees a reasoning note like "billing: +4 billing +3 HTTP = 12 scenarios". Low-complexity files get 2-3 scenarios. This happens automatically on every file write with no configuration needed.

Scenario tracking

At turn end, tailtest logs the outcome for each tested file: passed, fixed (failed but resolved within the turn), unresolved, or deferred. This log feeds cross-session history so recurring failures are surfaced at the start of future sessions. See the History page and Advanced for details.


Configuration

Create .tailtest/config.json in your project root (optional):

{
  "depth": "standard"
}

See Configuration for all options.


Session state

Session state is stored at .cursor/hooks/state/tailtest.json. Add this path to your .gitignore:

echo '.cursor/hooks/state/' >> .gitignore

Commands

Command What it does
/tailtest off Pause test generation for the current session
/tailtest on Resume after pausing
/summary Show session summary
/tailtest <file> Force-run tests for a specific file

Troubleshooting

Hooks not firing: Verify Cursor version supports hooks (0.40+). Check that python3 is available in your PATH.

run tests for: appears but no test is generated: The file was filtered (config file, template, test file). This is expected -- see rules/tailtest.mdc for the filter rules.

Wrong runner detected: Check .cursor/hooks/state/tailtest.json to see what runners were found. If the runner is wrong, your manifest (pyproject.toml, package.json) may be missing the test dependency.

Performance: The afterFileEdit hook runs in < 100ms. The stop hook runs in < 200ms. Neither makes network requests.