Supervertaler - AI Agent Documentation (Compact)
Purpose: Fast, reliable handoff when context is low or chats reset.
Last Updated: February 15, 2026 | Version: v1.9.267
⚡ 60-Second Resume Checklist
- Read
CHANGELOG.md top entry (latest release context).
- Check
git status --short (do not revert unrelated user changes).
- Confirm version in
pyproject.toml.
- Confirm unified settings in
settings/settings.json.
- If deeper context is needed, open:
docs/agent-archive/AGENTS_FULL_REFERENCE_v1.9.240_2026-02-08.md
🎯 Current State
- Current version:
v1.9.267
- Main app:
Supervertaler.py (large monolithic PyQt6 file)
- Latest major completed work:
- Standalone SDLXLIFF import/export without Trados package (v1.9.267)
- TXT/MD sentence segmentation with "Split lines into sentences" checkbox (v1.9.265)
- Markdown-aware segmenter (
modules/simple_segmenter.py::MarkdownSegmenter) (v1.9.265)
- Empty line handling: always preserved for export, hidden in grid (v1.9.265–266)
- Export regroups segments by
paragraph_id via itertools.groupby (v1.9.265)
- Direct Markdown (.md) export support (v1.9.264)
- Voice command AHK v2 syntax fix, AutoFingers support (v1.9.263)
- Claude Opus 4.6 model + Anthropic /v1/models API discovery (v1.9.262)
- Cross-platform support: macOS/Linux via
modules/platform_helpers.py (v1.9.246)
- Native global hotkey system replacing AHK-only approach (v1.9.246)
- Unified settings system in
settings/settings.json
- Custom OpenAI-compatible provider (
custom_openai)
📁 Key Paths (Source of Truth)
- Main app:
Supervertaler.py
- Modules:
modules/
- Sentence segmenter:
modules/simple_segmenter.py (SimpleSegmenter, MarkdownSegmenter)
- Platform helpers:
modules/platform_helpers.py
- Tests:
tests/
- Changelog:
CHANGELOG.md
- Version source:
pyproject.toml
- Dependencies:
requirements.txt (includes pynput>=1.7.6)
- Website version mention:
docs/index.html
- Unified settings:
settings/settings.json
- AHK hotkey script (Windows fallback):
supervertaler_hotkeys.ahk
- Archived full agent reference:
docs/agent-archive/AGENTS_FULL_REFERENCE_v1.9.240_2026-02-08.md
🏗️ Settings Architecture (v1.9.240+)
Primary config:
Top-level sections:
api_keys
general
ui
features
Satellite files under settings/:
themes.json
shortcuts.json
recent_projects.json
find_replace_history.json
superlookup_history.json
voice_commands.json
model_version_cache.json
Migration behavior:
- Legacy settings files are migrated at startup and renamed to
.migrated.
🔑 API Keys
Primary storage:
settings/settings.json under api_keys
Compatibility:
- Legacy
api_keys.txt remains supported as fallback input.
Common key names:
openai, claude, google, gemini, custom_openai, deepl, google_translate, ollama_endpoint
Notes:
google and gemini are aliases.
custom_openai supports OpenAI-compatible endpoints (endpoint/model configured in Settings > AI Settings).
🌐 Cross-Platform Architecture (v1.9.246+)
Central module: modules/platform_helpers.py
Constants:
IS_WINDOWS, IS_MACOS, IS_LINUX
Utilities:
open_file(path) / open_folder(path) — replaces os.startfile()
get_hidden_subprocess_flags() — CREATE_NO_WINDOW on Windows, empty dict elsewhere
Global hotkeys (GlobalHotkeyManager):
- Windows:
RegisterHotKey API (background thread with GetMessageW loop)
- macOS/Linux: pynput
GlobalHotKeys (requires Accessibility permission on macOS)
- Callbacks do zero work in the background thread — only signal Qt main thread via
QMetaObject.invokeMethod
- Main thread handles: send Cmd/Ctrl+C → wait 250ms → read clipboard → dispatch
Keystroke injection (CrossPlatformKeySender):
- Windows: AHK subprocess (
Send "^c" via temp .ahk file), PowerShell SendKeys fallback
- macOS:
osascript (tell application "System Events" to keystroke "c" using command down)
- Linux: pynput
Controller
Hotkey callback flow:
pynput/WinAPI thread → QMetaObject.invokeMethod (QueuedConnection)
→ @pyqtSlot _handle_superlookup_hotkey (main thread)
→ CrossPlatformKeySender.send_copy()
→ QTimer.singleShot(250ms) → read clipboard → on_ahk_capture(text)
🍎 macOS Hotkey Status — Pending Fixes
Working:
- pynput
GlobalHotKeys registers successfully (shows "Active via PYNPUT")
- Accessibility permission grant flow works
- Crash fixed (was caused by doing pyperclip/pynput work in background thread)
Known issues:
osascript Cmd+C deletes selected text in source app (likely stray modifier keys from hotkey)
- Cmd+C doesn't actually copy selections — only reads existing clipboard content
- Reliability: sometimes works, sometimes doesn't
Planned fixes:
- Debug
osascript keystroke injection (may need modifier release delay before sending)
- Consider using
pbcopy via AppleScript instead of keystroke simulation
- Change macOS shortcuts: ⌃⌥L/M → ⌃⌘L/M (Ctrl+Cmd, user-requested — easier to reach)
🔌 LLM Providers
Supported providers:
openai
claude
gemini
ollama
custom_openai
Relevant implementation files:
modules/llm_clients.py
Supervertaler.py (settings UI and provider wiring)
🧪 Testing Quick Start
Run:
pytest tests/
Manual smoke test checklist:
- Import DOCX, translate, export
- Save/load
.svproj
- TM and termbase behavior
- AI translation with configured keys
- SDLPPX round-trip
📦 Release Checklist
- Update version in
pyproject.toml.
- Update release notes in
CHANGELOG.md.
- Update version mention in
docs/index.html.
- Validate main workflows.
- Build and upload:
python -m build
python -m twine upload dist/supervertaler-<version>*
Windows EXE packaging:
build_windows_release.ps1 (core/full)
⚠️ High-Value Pitfalls
Supervertaler.py is large: read/edit by line range, not full-file stream.
- Qt table access: use
cellWidget() for editors and item() for plain items.
- Block signals during programmatic text updates to avoid cascades.
- Style issues can be timing-related (hidden widgets, deferred visibility).
- XML namespace formats (SDLXLIFF): always use namespace dicts.
📝 TXT/MD Import Architecture (v1.9.265+)
- Import dialog offers "Split lines into sentences" checkbox (persisted in
general_settings.json as last_import_sentence_segment)
- TXT files use
SimpleSegmenter, MD files use MarkdownSegmenter (protects links, code, URLs via placeholder pattern)
- Multiple sentences from one line share the same
paragraph_id
- Export regroups by
paragraph_id using itertools.groupby, joining sentences with spaces
- Empty lines are imported as empty segments (hidden in grid, preserved for export round-trip)
- Empty segments are hidden by
_apply_pagination_to_grid() and all filter/visibility functions
- Language settings:
general_settings.json stores last_import_source_lang/last_import_target_lang (shared across DOCX, TXT/MD, multi-file dialogs)
📌 Active Priorities
- Fix macOS global hotkey Cmd+C issues (deletes selection, doesn't copy).
- Make macOS shortcuts configurable (⌃⌘L/M instead of ⌃⌥L/M).
- Test Linux global hotkeys (pynput backend, untested).
- Continue reducing monolith pressure in
Supervertaler.py.
- Maintain release reliability (PyPI + Windows core/full artifacts).
- Keep this file short and operationally focused.
📚 Archived Reference
The full historical/long-form agent document is preserved at:
docs/agent-archive/AGENTS_FULL_REFERENCE_v1.9.240_2026-02-08.md
When context is limited, use this compact file first and open the archive only when needed.
1---2name: 028-agents-6b1b272e3description: Supervertaler - AI Agent Documentation (Compact)4---5# Supervertaler - AI Agent Documentation (Compact)67> **Purpose:** Fast, reliable handoff when context is low or chats reset.8> **Last Updated:** February 15, 2026 | **Version:** v1.9.267910---1112## ⚡ 60-Second Resume Checklist13141. Read `CHANGELOG.md` top entry (latest release context).152. Check `git status --short` (do not revert unrelated user changes).163. Confirm version in `pyproject.toml`.174. Confirm unified settings in `settings/settings.json`.185. If deeper context is needed, open:19 - `docs/agent-archive/AGENTS_FULL_REFERENCE_v1.9.240_2026-02-08.md`2021---2223## 🎯 Current State2425- **Current version:** `v1.9.267`26- **Main app:** `Supervertaler.py` (large monolithic PyQt6 file)27- **Latest major completed work:**28 - Standalone SDLXLIFF import/export without Trados package (v1.9.267)29 - TXT/MD sentence segmentation with "Split lines into sentences" checkbox (v1.9.265)30 - Markdown-aware segmenter (`modules/simple_segmenter.py::MarkdownSegmenter`) (v1.9.265)31 - Empty line handling: always preserved for export, hidden in grid (v1.9.265–266)32 - Export regroups segments by `paragraph_id` via `itertools.groupby` (v1.9.265)33 - Direct Markdown (.md) export support (v1.9.264)34 - Voice command AHK v2 syntax fix, AutoFingers support (v1.9.263)35 - Claude Opus 4.6 model + Anthropic /v1/models API discovery (v1.9.262)36 - Cross-platform support: macOS/Linux via `modules/platform_helpers.py` (v1.9.246)37 - Native global hotkey system replacing AHK-only approach (v1.9.246)38 - Unified settings system in `settings/settings.json`39 - Custom OpenAI-compatible provider (`custom_openai`)4041---4243## 📁 Key Paths (Source of Truth)4445- Main app: `Supervertaler.py`46- Modules: `modules/`47- Sentence segmenter: `modules/simple_segmenter.py` (`SimpleSegmenter`, `MarkdownSegmenter`)48- Platform helpers: `modules/platform_helpers.py`49- Tests: `tests/`50- Changelog: `CHANGELOG.md`51- Version source: `pyproject.toml`52- Dependencies: `requirements.txt` (includes `pynput>=1.7.6`)53- Website version mention: `docs/index.html`54- Unified settings: `settings/settings.json`55- AHK hotkey script (Windows fallback): `supervertaler_hotkeys.ahk`56- Archived full agent reference:57 - `docs/agent-archive/AGENTS_FULL_REFERENCE_v1.9.240_2026-02-08.md`5859---6061## 🏗️ Settings Architecture (v1.9.240+)6263Primary config:64- `settings/settings.json`6566Top-level sections:67- `api_keys`68- `general`69- `ui`70- `features`7172Satellite files under `settings/`:73- `themes.json`74- `shortcuts.json`75- `recent_projects.json`76- `find_replace_history.json`77- `superlookup_history.json`78- `voice_commands.json`79- `model_version_cache.json`8081Migration behavior:82- Legacy settings files are migrated at startup and renamed to `.migrated`.8384---8586## 🔑 API Keys8788Primary storage:89- `settings/settings.json` under `api_keys`9091Compatibility:92- Legacy `api_keys.txt` remains supported as fallback input.9394Common key names:95- `openai`, `claude`, `google`, `gemini`, `custom_openai`, `deepl`, `google_translate`, `ollama_endpoint`9697Notes:98- `google` and `gemini` are aliases.99- `custom_openai` supports OpenAI-compatible endpoints (endpoint/model configured in Settings > AI Settings).100101---102103## 🌐 Cross-Platform Architecture (v1.9.246+)104105Central module: `modules/platform_helpers.py`106107Constants:108- `IS_WINDOWS`, `IS_MACOS`, `IS_LINUX`109110Utilities:111- `open_file(path)` / `open_folder(path)` — replaces `os.startfile()`112- `get_hidden_subprocess_flags()` — `CREATE_NO_WINDOW` on Windows, empty dict elsewhere113114Global hotkeys (`GlobalHotkeyManager`):115- Windows: `RegisterHotKey` API (background thread with `GetMessageW` loop)116- macOS/Linux: pynput `GlobalHotKeys` (requires Accessibility permission on macOS)117- Callbacks do **zero work** in the background thread — only signal Qt main thread via `QMetaObject.invokeMethod`118- Main thread handles: send Cmd/Ctrl+C → wait 250ms → read clipboard → dispatch119120Keystroke injection (`CrossPlatformKeySender`):121- Windows: AHK subprocess (`Send "^c"` via temp `.ahk` file), PowerShell `SendKeys` fallback122- macOS: `osascript` (`tell application "System Events" to keystroke "c" using command down`)123- Linux: pynput `Controller`124125Hotkey callback flow:126```127pynput/WinAPI thread → QMetaObject.invokeMethod (QueuedConnection)128 → @pyqtSlot _handle_superlookup_hotkey (main thread)129 → CrossPlatformKeySender.send_copy()130 → QTimer.singleShot(250ms) → read clipboard → on_ahk_capture(text)131```132133---134135## 🍎 macOS Hotkey Status — Pending Fixes136137**Working:**138- pynput `GlobalHotKeys` registers successfully (shows "Active via PYNPUT")139- Accessibility permission grant flow works140- Crash fixed (was caused by doing pyperclip/pynput work in background thread)141142**Known issues:**1431. `osascript` Cmd+C deletes selected text in source app (likely stray modifier keys from hotkey)1442. Cmd+C doesn't actually copy selections — only reads existing clipboard content1453. Reliability: sometimes works, sometimes doesn't146147**Planned fixes:**148- Debug `osascript` keystroke injection (may need modifier release delay before sending)149- Consider using `pbcopy` via AppleScript instead of keystroke simulation150- Change macOS shortcuts: ⌃⌥L/M → **⌃⌘L/M** (Ctrl+Cmd, user-requested — easier to reach)151152---153154## 🔌 LLM Providers155156Supported providers:157- `openai`158- `claude`159- `gemini`160- `ollama`161- `custom_openai`162163Relevant implementation files:164- `modules/llm_clients.py`165- `Supervertaler.py` (settings UI and provider wiring)166167---168169## 🧪 Testing Quick Start170171Run:172```bash173pytest tests/174```175176Manual smoke test checklist:177- Import DOCX, translate, export178- Save/load `.svproj`179- TM and termbase behavior180- AI translation with configured keys181- SDLPPX round-trip182183---184185## 📦 Release Checklist1861871. Update version in `pyproject.toml`.1882. Update release notes in `CHANGELOG.md`.1893. Update version mention in `docs/index.html`.1904. Validate main workflows.1915. Build and upload:192193```bash194python -m build195python -m twine upload dist/supervertaler-<version>*196```197198Windows EXE packaging:199- `build_windows_release.ps1` (core/full)200201---202203## ⚠️ High-Value Pitfalls2042051. `Supervertaler.py` is large: read/edit by line range, not full-file stream.2062. Qt table access: use `cellWidget()` for editors and `item()` for plain items.2073. Block signals during programmatic text updates to avoid cascades.2084. Style issues can be timing-related (hidden widgets, deferred visibility).2095. XML namespace formats (SDLXLIFF): always use namespace dicts.210211---212213## 📝 TXT/MD Import Architecture (v1.9.265+)214215- Import dialog offers "Split lines into sentences" checkbox (persisted in `general_settings.json` as `last_import_sentence_segment`)216- TXT files use `SimpleSegmenter`, MD files use `MarkdownSegmenter` (protects links, code, URLs via placeholder pattern)217- Multiple sentences from one line share the same `paragraph_id`218- Export regroups by `paragraph_id` using `itertools.groupby`, joining sentences with spaces219- Empty lines are imported as empty segments (hidden in grid, preserved for export round-trip)220- Empty segments are hidden by `_apply_pagination_to_grid()` and all filter/visibility functions221- Language settings: `general_settings.json` stores `last_import_source_lang`/`last_import_target_lang` (shared across DOCX, TXT/MD, multi-file dialogs)222223---224225## 📌 Active Priorities2262271. **Fix macOS global hotkey Cmd+C issues** (deletes selection, doesn't copy).2282. **Make macOS shortcuts configurable** (⌃⌘L/M instead of ⌃⌥L/M).2293. **Test Linux global hotkeys** (pynput backend, untested).2304. Continue reducing monolith pressure in `Supervertaler.py`.2315. Maintain release reliability (PyPI + Windows core/full artifacts).2326. Keep this file short and operationally focused.233234---235236## 📚 Archived Reference237238The full historical/long-form agent document is preserved at:239- `docs/agent-archive/AGENTS_FULL_REFERENCE_v1.9.240_2026-02-08.md`240241When context is limited, use this compact file first and open the archive only when needed.