wordprint
v0.1.3
Published
WordPrint — AI content detector CLI + web UI (Grok, Claude, or OpenAI). Scores how LLM-generated a passage looks.
Maintainers
Readme
WordPrint
AI content detector that scores how likely a passage was written by a large language model.
Paste text → a chosen judge model analyzes stylistic red flags → you get:
- Confidence score (0–100)
- Traffic light — green (likely human), yellow (uncertain), red (likely AI)
- Findings list — concrete red flags with severity, category, and quoted evidence
- Human signals — aspects that look authentically human
npm package: wordprint
CLI: wordprint
npm install -g wordprint
wordprint analyze -p xai "your text here…"Privacy
Analyzed text is sent to a third-party model provider. WordPrint does not run a local judge model: the passage you paste or pipe is transmitted to whichever backend you select (xAI / Grok, Anthropic / Claude, or OpenAI) so that provider can score it.
That matters if you are checking client documents, unpublished manuscripts, or other confidential material. Prefer a provider and account whose data policies you accept; do not paste secrets or private drafts unless you are comfortable with that provider receiving them. Credentials stay local (~/.wordprint, env vars, or grok login); only the text under analysis is sent for scoring.
Stack
- Next.js (App Router)
- Vercel AI SDK with multi-provider backends:
- xAI / Grok (
@ai-sdk/xai) — default (grok-4.5) - Anthropic / Claude (
@ai-sdk/anthropic) - OpenAI (
@ai-sdk/openai)
- xAI / Grok (
- Local SQLite credentials store (
~/.wordprint/credentials.db) via Settings panel or CLI - SpaceXAI OAuth for Grok (same session as
grok login/ X Premium+ / SuperGrok) - Zod structured output
- Tailwind CSS
Prerequisites
- Node.js 22.5+ (uses built-in
node:sqlite) - At least one model backend:
| Provider | How to authenticate |
|----------|---------------------|
| Grok (default) | Settings / wordprint config, or grok login, or XAI_API_KEY |
| Claude | Settings / wordprint config, or ANTHROPIC_API_KEY |
| OpenAI | Settings / wordprint config, or OPENAI_API_KEY |
Claude Code / Claude.ai subscription login is not reused — use an API key (or the Settings panel).
Install
Option A — npm global CLI (recommended for day-to-day use)
npm install -g wordprintCommands available:
| Command | Purpose |
|---------|---------|
| wordprint / wordprint | CLI entry (same binary) |
| wordprint analyze … | Score text (no server needed) |
| wordprint status | Auth + model catalog (no server needed) |
| wordprint dev | Start web UI at http://localhost:3000 |
| wordprint start | Production web UI (builds if needed) |
| wordprint open | Open the UI in a browser |
One-shot without a global install:
npx wordprint analyze -p anthropic "In today's rapidly evolving landscape…"
npx wordprint status
npx wordprint devOption B — from source (development)
git clone <repo-url> wordprint
cd wordprint
npm installConfigure credentials
Keys can live in three places (highest priority first):
- Environment —
XAI_API_KEY,ANTHROPIC_API_KEY,OPENAI_API_KEY(or.env.localfor the web app) - Local SQLite —
~/.wordprint/credentials.db(Settings panel orwordprint config) - Grok OAuth only —
grok login→~/.grok/auth.json
Web UI (Settings panel)
- Start the app:
wordprint devornpm run dev - Open http://localhost:3000
- Click API keys in the header
- xAI OAuth: click Import from Grok login (after
grok login), or paste a token - Optionally paste xAI / Anthropic / OpenAI API keys → Save keys
- Toggle Prefer OAuth over xAI API key when you want SuperGrok OAuth first
Secrets are written to SQLite on disk (~/.wordprint/credentials.db, mode 0600). The API never returns full keys — only a masked hint.
CLI config (same SQLite store)
wordprint config # keys + OAuth status
wordprint config oauth import # from `grok login` → SQLite
wordprint config oauth refresh
wordprint config oauth prefer on # use OAuth before API key
wordprint config oauth clear
wordprint config set --xai xai-...
wordprint config set --anthropic sk-ant-...
wordprint config set --openai sk-...
wordprint config clear --openai
wordprint config clear --allEnvironment / .env.local
cp .env.example .env.local# XAI_API_KEY=xai-...
# ANTHROPIC_API_KEY=sk-ant-...
# OPENAI_API_KEY=sk-...
# WORDPRINT_PROVIDER=xai
# WORDPRINT_MODEL=grok-4.5
# WORDPRINT_DATA_DIR=~/.wordprintOr Grok OAuth only:
grok loginHow to run
CLI only (no web server)
# Auth check
wordprint status
# Analyze (standalone — talks to the model provider directly)
wordprint analyze "paste at least 40 characters of text here…"
wordprint analyze -p anthropic -m claude-opus-5 "…"
wordprint analyze -p xai notes.txt
echo "…" | wordprint analyze -p anthropic -JSON is printed to stdout (pipe to jq if you like).
Web UI (development)
# from a global install
wordprint dev
# or from a source checkout
npm run dev
# or
./bin/wordprint devOpen http://localhost:3000.
- Choose Provider and Model under the text box
- Paste text (or use sample buttons)
- Click Analyze
Production web UI
wordprint build
wordprint start
# or: npm run build && npm run startOverride port: PORT=4000 wordprint dev.
Inside Claude Code or Grok
# after: npm install -g wordprint
# and credentials in the environment / grok login
wordprint status
wordprint analyze -p xai "text of at least 40 characters…"
wordprint analyze -p anthropic "…"
wordprint dev # optional web UIProviders & model switch
| Provider | Default model | Auth |
|----------|---------------|------|
| xai | grok-4.5 | env → SQLite Settings → grok login OAuth |
| anthropic | claude-opus-5 | env → SQLite Settings |
| openai | gpt-4.1 | env → SQLite Settings |
- Catalog:
config/providers.ts - Forensic prompt / thresholds:
config/analysis.ts
On each Grok analysis the server/CLI:
- Loads the OAuth access token from
~/.grok/auth.json - Silently refreshes via
https://auth.x.ai/oauth2/tokenwhen near expiry - Retries once on
401after a forced refresh - Falls back to
XAI_API_KEYonly if no OAuth session exists
Publish to npm (maintainers)
Package name is wordprint (unscoped, public).
# 1. Log in (once)
npm login
# 2. Sanity-check the tarball
npm run pack:check
# or: npm pack --dry-run
# 3. Bump version when ready
npm version patch # or minor / major
# 4. Publish
npm publishAfter publish, anyone can:
npm install -g wordprint
wordprint --helpNotes
- Update
repository/homepage/bugsinpackage.jsonto your real GitHub URL before publishing. - CLI binary name is
wordprint. - Do not commit secrets;
.env*is gitignored (.env.exampleis safe to ship).
How scoring works
The checker prompt lives in config/analysis.ts (analysisConfig.systemPrompt). The same forensic instructions are sent to whichever provider/model you select.
Default bias: skeptical toward “human” — structural patterns and absence of human traits outweigh single-word markers (which vary by language and model).
Seven forensic dimensions:
| # | Dimension | What it catches | |---|-----------|-----------------| | 1 | Lexical predictability | Generic collocations, institutional lexicon, prompt-shaped phrasing (language-adapted) | | 2 | Rhythm / burstiness | Simulated vs authentic sentence variation | | 3 | Structure / symmetry | Intro→N points→outro, tricolons, masked completism | | 4 | Tone / voice | Hedging, false assertiveness, missing lived experience | | 5 | Openings / closings | Over-polished hooks, punchlines, packing-peanut transitions | | 6 | Terminological density | Decorative vs functional jargon | | 7 | Perfection | Frictionless prose with zero micro-imperfections |
Verdicts: ai_generated · human_written · human_edited_ai
Thresholds:
| Score | Light | Meaning | |------:|:-----:|---------| | 0–34 | Green | Likely human | | 35–64 | Yellow | Uncertain / mixed / hybrid | | 65–100 | Red | Likely AI-generated |
This is a heuristic, not a watermark detector or proof of authorship. Short, technical, or heavily edited text is often ambiguous.
API (web server mode)
Base URL when running locally: http://localhost:3000.
GET /api/auth/status
Returns per-provider auth status and the model catalog.
POST /api/analyze
curl -s http://localhost:3000/api/analyze \
-H "Content-Type: application/json" \
-d '{
"text": "Your passage here (min 40 characters)…",
"provider": "anthropic",
"model": "claude-opus-5"
}' | jqprovider and model are optional (fall back to WORDPRINT_* env or catalog defaults).
Success shape:
{
"analysis": {
"confidenceScore": 82,
"riskLevel": "red",
"verdict": "ai_generated",
"summary": "…",
"humanSignals": [],
"findings": []
},
"provider": "anthropic",
"model": "claude-opus-5",
"auth": {
"provider": "anthropic",
"source": "api_key",
"email": null
}
}Troubleshooting
| Symptom | Fix |
|---------|-----|
| “No xAI credentials” | Run grok login or set XAI_API_KEY, then retry |
| “No Anthropic credentials” | Export ANTHROPIC_API_KEY (or put it in .env.local for the web app) |
| CLI works, web UI does not see keys | Web app reads .env.local in the project/package root; restart after editing |
| Port 3000 in use | PORT=3001 wordprint dev |
| Global install cannot write | Use npx wordprint … or fix npm global prefix permissions |
New installs use ~/.wordprint only. If you previously used this tool under an older name and still have credentials under ~/.deslopper, WordPrint will fall back to that directory when ~/.wordprint does not exist yet (or set WORDPRINT_DATA_DIR).
License
MIT
