# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## What This Is PyQt6 desktop GUI for Linux that centralizes the danix.xyz Hugo blog publishing workflow. Centralizes: article management, translations (IT↔EN via RunPod), git operations, hugo server, media uploads, and taxonomy management. Blog repo: `/home/danix/Programming/GIT/danix.xyz-hacker-theme` Translation script: `/home/danix/bin/transart.py` (TranslateGemma 27b on RunPod) Config file: `~/.config/my-publisher/config.toml` ## Commands ```bash # Run app python main.py # Run all tests pytest tests/ -v # Run single test file pytest tests/test_config.py -v # Run single test pytest tests/test_config.py::test_config_round_trips -v # Install deps pip install -r requirements.txt ``` ## Architecture Single Python process. Three layers: **`core/`** — UI-agnostic business logic: - `config.py` — load/save `~/.config/my-publisher/config.toml` via tomlkit - `models.py` — `Article` dataclass + `ARTICLE_TYPES = ["Life", "Photo", "Link", "Quote", "Tech"]` - `article_scanner.py` — scans `content/it/` and `content/en/`, builds `list[Article]`, detects translation pairs by matching slugs across languages - `frontmatter.py` — parse/write Hugo TOML frontmatter (delimited by `+++`, not YAML `---`) - `taxonomy.py` — load/save `docs/tags-it.txt` + `docs/tags-en.txt` (line-aligned pairs) **`workers/`** — async operations via Qt signals: - `git_worker.py` — `QThread` for pull, push master/production, `git rm`, restore deleted - `hugo_worker.py` — `QProcess` for `hugo server -D`, streams stdout line by line - `translation_worker.py` — `QProcess` for `transart.py`, streams stdout for progress display Workers emit `output(str)`, `error(str)`, `finished(bool)` signals. UI connects to these — never blocks the main thread. **`ui/`** — PyQt6 widgets: - `main_window.py` — `QMainWindow` with sidebar + `QStackedWidget`. Sidebar has groups: CONTENUTO / WORKFLOW / DEPLOY. Uses `QFileSystemWatcher` on `content/it/` and `content/en/` to auto-refresh on external changes (e.g. Typora edits). - Each sidebar section maps to a widget in the stack. ## Key Conventions **Hugo frontmatter is TOML, not YAML.** Delimited by `+++`. Always use `tomlkit` (not `tomllib`) to preserve key ordering and comments when writing back. **Translation pairs are matched by slug.** An IT article at `content/it/articles/my-post/index.md` and EN at `content/en/articles/my-post/index.md` share slug `my-post`. `article_scanner.py` builds the pairing. **Git branches:** `master` = staging (hugo server testing), `production` = live deploy (post-receive hook on server). **Media path convention:** Files upload to `static/uppies/YYYY/MM/filename`. Web path served as `/uppies/YYYY/MM/filename`. **Tests are UI-free.** `core/` and `workers/` are tested with pytest + tmp_path fixtures. Qt UI components are not unit-tested — verify manually by running the app. **Config path override in tests:** Pass `path` explicitly to `Config.load(path)` / `Config.save(path)` rather than monkeypatching the module-level constant. ## Spec and Plan Full design spec: `docs/superpowers/specs/2026-05-01-my-publisher-design.md` Implementation plan (20 tasks): `docs/superpowers/plans/2026-05-01-my-publisher.md` Implementation is in progress — tasks 1–4 complete (scaffold, config, models, frontmatter parser). Tasks 5–20 pending.