Skip to content

Latest commit

 

History

History
80 lines (66 loc) · 4.68 KB

File metadata and controls

80 lines (66 loc) · 4.68 KB

AGENTS.md — review and contribution guidance

What this project is

A PII anonymizer with consistent, reversible labels (<人名_1> / <Name_1>, <Nombre_1>, <Tên_1>, …). Two cores that must stay in behavioural parity:

  • Python: src/prompt_anonymizer/ (Presidio + spaCy) — PyPI package + CLI
  • TypeScript: web/packages/core/ (regex + transformers.js NER) — browser app, Chrome extension, Tauri desktop, Node CLI (web/packages/cli), embeddable web component (web/packages/element), React/Vue bindings (web/packages/{react,vue}), OpenAI-compatible anonymizing proxy + admin GUI (web/packages/proxy, web/apps/proxy-admin), MCP server (web/packages/mcp; the mapping stays server-side behind a mapping_id — never returned to the model unless explicitly requested, P0)

Both CLIs also expose a commit-time / CI gate (scan subcommand; exit codes 0 = clean, 1 = PII found, 2 = error) consumed via .pre-commit-hooks.yaml. scan must never print the matched text — only file:line:col and the entity type (P0).

The parity contract is the golden set in tests/golden/ (regenerated by uv run python -m prompt_anonymizer.evals).

Supported languages have a single source of truth per core (src/prompt_anonymizer/languages.py / web/packages/core/src/languages.ts); never hardcode language lists elsewhere. To add a language, follow docs/ADDING_A_LANGUAGE.md — CI consistency tests fail on half-added states.

Review priorities

  • P0 — PII leak risk. Any change that could cause PII to leave the device (new network calls, telemetry, logging of input text or mappings, persisting mappings) or that weakens detection (score threshold changes, recognizer removal) must be treated as blocking and called out explicitly.
  • P1 — ReDoS. Recognizer regexes run on untrusted input. Flag patterns with nested quantifiers or overlapping alternations. Prefer bounded quantifiers and lookarounds as used in the existing recognizers.
  • Offset handling requires tests. Any change to span merging, label assignment, or replacement (labeling.py / labeling.ts) must come with matching tests in BOTH cores, plus a round-trip (anonymize → deanonymize identity) assertion.
  • Label format changes are breaking changes: they invalidate stored mappings and demo assets. Require a CHANGELOG entry and demo regeneration.

Limit review comments to the priorities above plus clear correctness bugs; avoid style nits (ruff/tsc enforce style mechanically).

Commands

  • Python: uv run pytest -m "not slow", uv run ruff check ., uv run mypy src
  • Web: cd web && pnpm test && pnpm lint && pnpm build
  • Docs (README etc.): pnpm -C web docs:check validates relative links and #anchors in every tracked *.md (github-slugger, same algorithm as GitHub) and guards user-facing docs against release drift (registry SSOT, install paths, MCP coverage, pre-commit rev pins); runs in PR CI
  • Web e2e (after build): cd web && pnpm e2e (offline, PR CI); pnpm e2e:ner runs the full NER pipeline (model download, weekly CI)
  • Demo assets are script-generated only: demo/README.md

Cursor Cloud specific instructions

Dependencies are refreshed automatically on startup (Python via uv sync --all-extras --group models, web via pnpm -C web install --frozen-lockfile). Standard lint/test/build/run commands live in ## Commands above and CONTRIBUTING.md. Non-obvious notes:

  • uv installs to ~/.local/bin; it is sourced for login shells via ~/.bashrc. uv auto-creates a Python 3.13 venv from .python-version, so pytest runs on 3.13 even though the base image ships 3.12.
  • The web workspace uses pnpm 11.10.0 (pinned via corepack + the packageManager field); the base image's global pnpm is older, so run pnpm from inside web/ (or via pnpm -C web) to get the pinned version.
  • Before running the web app / extension / desktop, the shared core must be built (pnpm --filter @prompt-anonymizer/core build) because its main points at dist/index.js; dist/ is not committed. pnpm lint and the full pnpm build already build core first.
  • Browser dev server: pnpm --filter @prompt-anonymizer/web dev on port 5173. The first "Anonymize" click downloads a transformers.js NER model from the Hugging Face CDN (needs network); untick the "NER model" checkbox for a fully offline regex-only run (masks emails/phones but not names).
  • Chrome is preinstalled at google-chrome; there is no extension dev server — build it and load unpacked from web/apps/extension/dist/.
  • Desktop (pnpm --filter @prompt-anonymizer/desktop dev) additionally needs the Rust/Tauri system libraries (see .github/workflows/release-apps.yml) which are not installed by default.