Metadata-Version: 2.4
Name: cursebench
Version: 0.1.0
Summary: A local benchmark for abuse aimed at coding-agent harnesses and models.
Author: Sid Manale
License: MIT
Requires-Python: >=3.11
Description-Content-Type: text/markdown

# CurseBench

CurseBench scans local coding-agent chats and counts how many times users used abusive terms. It is local only. It does not send chat text anywhere.

Harnesses, models, and terms are ranked by the total number of uses. There is no attempt to decide who or what the abuse targets.

## Run it

CurseBench uses Python 3.11 or newer and has no runtime dependencies.

```sh
uv run cursebench
```

Write the full machine-readable report to a file:

```sh
uv run cursebench --json cursebench-report.json
```

Print only JSON:

```sh
uv run cursebench --json
```

Scan selected harnesses or limit a quick validation run:

```sh
uv run cursebench --provider codex --provider claude
uv run cursebench --limit-sessions 25
```

Message excerpts are private and are not shown by default. Use `--examples` when you want to inspect why messages were classified:

```sh
uv run cursebench --examples 5
```

## Supported stores

| Harness | Default local store |
| --- | --- |
| Claude Code | `~/.claude/projects/**/*.jsonl` |
| Codex | `~/.codex/sessions/**/*.jsonl` |
| OpenCode | `~/.local/share/opencode/opencode.db` |
| Antigravity | `~/.gemini/antigravity/brain/*/.system_generated/logs/transcript.jsonl` |
| Cursor | `~/.cursor/projects/**/agent-transcripts/**/*.jsonl` |
| Grok Build | `~/.grok/sessions/*/*/chat_history.jsonl` |

Override a location with `--root HARNESS=PATH`. OpenCode expects a database path. The other harnesses expect a directory.

```sh
uv run cursebench --provider grok --root grok=/Volumes/archive/grok-sessions
```

Every adapter is read only. Parser health is included in both terminal and JSON reports. This makes a missing store or an incompatible format visible instead of quietly treating it as zero abuse.

## What is counted

The built-in vocabulary covers common English profanity, insults, direct abuse, and several explicit slurs that are used as abuse. Slur labels are masked in reports. Matches inside fenced code and inline code are ignored. Overlapping terms count once. Common technical phrases such as “garbage collection” and “dumb terminal” are excluded.

A private newline-delimited file can extend the vocabulary when your research requires a different list:

```sh
uv run cursebench --custom-terms ~/.config/cursebench/private-terms.txt
```

Each report uses these measures:

- `abuse_uses` is the total number of abusive terms found. This is the main benchmark score.
- `messages_with_abuse` is the number of user messages containing at least one abusive term.
- `affected_sessions` is the number of sessions containing at least one abusive term.
- `message_rate_percent` is the percentage of user messages containing abuse.
- `uses_per_message` is the average number of abusive terms in each matching message.

Model names come from provider metadata. Cursor and Antigravity do not always store the model in their chat transcript, so those messages can appear under `unknown`.

## Limits

CurseBench matches a fixed word list. It does not claim to understand the user’s intent, mood, or target. Use private examples to check edge cases, and use a custom terms file when your definition differs from the built-in one.
