summaryrefslogtreecommitdiffstats
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md73
1 files changed, 73 insertions, 0 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..952aac6
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,73 @@
+# 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.