Project structure
What each directory in the Bun workspace does, the shared algorithm modules, and the conventions to follow when you change the code.
| Directory | Role |
|---|---|
cli/ | fpd command line tool (Bun + Ink), published as the npm package lmfpd |
web/ | Detection website and read-only reference library (React, shadcn/ui, Tailwind CSS) |
shared/ | Challenge, parsing, scoring, and tokenizer probe algorithms shared by the website and the CLI |
data/ | Reference data, derived bank, frozen detector, fixed challenges, and tokenizer bank. See Data files |
docs/ | These docs (Fumadocs + React Router, all pages prerendered) |
offline/ | Offline retraining and calibration (Python, run with uv) |
worker/ | Single-file Cloudflare Worker API proxy, also used by the same-origin proxy entry points |
functions/ | Cloudflare Pages Functions entry point |
api/ | Vercel Functions entry point |
Shared algorithms
shared/ does not depend on React, browser storage, or the outer research directory:
| Module | Role |
|---|---|
challenge-browser.js | Detection challenge generation |
completion-request.ts, completion.ts, detection.ts | Request bodies, response parsing, and the detection flow |
fingerprint-core.js | Number features and base scoring |
shared-detector.ts | Frozen ranker and confidence calibration |
detector-codec.ts | Decodes the binary detector file shared_detector.bin. Shared by the CLI, the website, and the evaluators |
sample-distribution.ts | Flags anomalous samples whose smallest valid number is at least 200. Used only for interface hints, not for scoring |
builder.ts | Builds the bank offline from reference samples. Rejects samples with an evaluation mark |
tokenizer-bank.ts, tokenizer-usage.ts | Tokenizer bank types and validation, and reading usage from JSON or SSE responses |
tokenizer-posterior.ts, tokenizer-probe.ts | Tokenizer posterior, probe selection, and the probe flow |
privacy.ts, types.ts | Redaction and shared types |
The official data and frozen parameters are in data/. The website calls only the detection modules and does not bundle the bank-building entry point.
Detection website
web/src/ contains the detection pages, the read-only sample library, and the interface copy (Simplified Chinese, Traditional Chinese, English, Japanese, and French). Routing uses the HashRouter of React Router. The interface uses shadcn/ui (Base UI), Tailwind CSS v4, and Framer Motion. The design spec defines the visual primitives and interaction constraints. Colors and brand fonts are in web/src/tokens.css, and these docs use the same file.
src/i18n/messages.tscontains the Simplified Chinese and English copy and defines theMessagestype that all languages share.zh-hant.ts,ja.ts, andfr.tshold the other languages.LOCALESinsrc/i18n/index.tsxlists the available languages, and the file provides the language preference, interpolation, and date and number formatting. Add or change copy in all five files together. Switching the language does not change the algorithm prompts or user answers. The docs exist in Chinese and English only: Traditional Chinese links to the Chinese docs, and Japanese and French link to the English docs.- The website has no enrollment feature. It does not merge or rebuild reference data.
- Before the build,
scripts/sync-data.tsvalidates and redacts the official data, compresses the reference bank, derived bank, and detector into static zstd chunks, and generates the data manifest. - The production build injects the Koitoyu and Recorder scripts from
telemetry.json. Local development does not load them. Recorder replays mask the API configuration area and error details, and input fields are masked by default. Each API-mode detection sends adetectevent, and a result that shows the celebration also sendsdetect-genuine; both carry only the model name asmodel, written as in the reference bank (no provider prefix, andclaude-opus-5-5becomesclaude-opus-5.5). Their ratio permodelis the genuine rate of each model.
These docs
docs/ is a React Router SPA. It declares its content collections with the macro API of Fumadocs MDX. Pages are stored in pairs, as page.mdx (Chinese) and page.en.mdx (English). A page without an English file falls back to Chinese on the English site. Links in pages are written as relative paths to content files (for example ../cli/detect.mdx#options), and the build resolves them to URLs in the current language.
Run bun run dev:docs for local development. vite.config.ts scans shared component dependencies from app/root.tsx and pre-bundles Fumadocs' internal client dependencies through optimizeDeps.include. After upgrading Fumadocs or adding an internal client dependency, check page interactions on a cold start. Add any missed dependency to this list: a second pre-bundling pass at runtime can mix React runtime exports and prevent hydration.
| File | Purpose |
|---|---|
site.config.ts | Path prefix DOCS_BASE (/docs by default) and public origin SITE_ORIGIN (https://lm.ikale.io by default) |
source.config.ts | Global MDX plugins: math, Mermaid, file trees, and steps |
app/lib/source.ts | Content collections, page tree, and llms.txt |
app/routes/*.ts(x) | Pages, search index, Markdown versions, and Open Graph images |
scripts/generate-openapi.ts | Generates the Proxy API pages from worker/openapi.json |
Conventions
- Use Bun to manage dependencies and run TypeScript. The product build does not depend on files outside the repository. Configuration, lock files, and deployment entry points are all in the root directory.
web/provides only the detection and read-only reference library pages. Sampling is incli/, algorithms are inshared/, and data is indata/.- Do not add test files. After a change, run
bun run typecheckandbun run build. - Numeric versions in reference bank model labels use a decimal point (for example
claude-opus-5.5). The display and reference label ofclaude-haiku-4-5-20251001is alwaysclaude-haiku-4.5. API request models and raw sampling evidence keep the original upstream values. - Do not call model APIs automatically. Send requests only when the user asks to collect samples from an upstream or to detect it.
- Evaluation samples must not enter the reference bank, the model centroids, or the calibration. Sampling records keep failures and earlier attempts.
Last updated on