# 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.

## System Theme (Kvantum + qt6ct)

App uses system Qt theme via two symlinks into PyQt6's plugin bundle. These are required for Kvantum-dark + qt6ct to work and are **not** tracked in git.

```bash
PYQT6=$(python3 -c "import os,PyQt6; print(os.path.join(os.path.dirname(PyQt6.__file__),'Qt6','plugins'))")
mkdir -p "$PYQT6/styles"
ln -sf /usr/lib64/qt6/plugins/styles/libkvantum.so "$PYQT6/styles/libkvantum.so"
ln -sf /usr/lib64/qt6/plugins/platformthemes/libqt6ct.so "$PYQT6/platformthemes/libqt6ct.so"
```

**Recreate after every `pip install --upgrade PyQt6`** — pip wipes the bundle, symlinks are lost.

PyQt6 is pinned to `>=6.10.0,<6.11.0` in `requirements.txt` to match system Qt6 (6.10.3). Kvantum uses Qt private API — upgrading PyQt6 beyond the system Qt minor version causes segfault.

## 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`

All 20 tasks complete. v1.0 shipped with full functionality: scaffold, config, models, frontmatter parser, article scanner, taxonomy, git worker, hugo worker, translation worker, and all UI components.
