Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ python src/main.py

The app **must** be run from the project root. `python src/main.py` adds `src/` to `sys.path`, so all imports use bare module names (e.g., `from config import *`, not `from src.config import *`).

After activating the venv, `python` resolves to 3.12; outside it, prefer `python3` (this is what `AGENTS.md` and `scripts/` use).

For a non-interactive YouTube upload, `bash scripts/upload_video.sh` runs the upload flow directly (must also be invoked from the repo root).

## Architecture

### Entry Points
Expand All @@ -45,7 +49,7 @@ Two service categories use a string-based dispatch pattern configured in `config
|---|---|---|
| LLM | `ollama_model` | Ollama (via `ollama` Python SDK). If empty, user picks from available models at startup. |
| Image gen | β€” | `nanobanana2` (Gemini image API) |
| STT | `stt_provider` | `local_whisper`, `third_party_assemblyai` |
| STT | `stt_provider` | `local_whisper` (configurable via `whisper_model`, `whisper_device`, `whisper_compute_type`), `third_party_assemblyai` |

LLM always uses the local Ollama server. Image generation always uses Nano Banana 2.

Expand All @@ -54,11 +58,12 @@ LLM always uses the local Ollama server. Image generation always uses Nano Banan
- **`src/config.py`** β€” 30+ getter functions, each re-reads `config.json` on every call (no caching). `ROOT_DIR` = project root, computed as `os.path.dirname(sys.path[0])`
- **`src/cache.py`** β€” JSON file persistence in `.mp/` directory (accounts, videos, posts, products)
- **`src/constants.py`** β€” menu strings, Selenium selectors (YouTube Studio, X.com, Amazon)
- **`src/status.py`** β€” colored logger (`info`, `success`, `error`, `warning`) imported by every module; prefer this over `print`
- **`src/classes/YouTube.py`** β€” most complex class; full pipeline: topic β†’ script β†’ metadata β†’ image prompts β†’ images β†’ TTS β†’ subtitles β†’ MoviePy combine β†’ Selenium upload
- **`src/classes/Twitter.py`** β€” Selenium automation against x.com
- **`src/classes/AFM.py`** β€” Amazon scraping + LLM pitch generation
- **`src/classes/Outreach.py`** β€” Google Maps scraper (requires Go) + email sending via yagmail
- **`src/classes/Tts.py`** β€” KittenTTS wrapper
- **`src/classes/Tts.py`** β€” KittenTTS wrapper; available voices: `Bella`, `Jasper` (default), `Luna`, `Bruno`, `Rosie`, `Hugo`, `Kiki`, `Leo`

### Data Storage
All persistent state lives in `.mp/` at the project root as JSON files (`youtube.json`, `twitter.json`, `afm.json`). This directory also serves as scratch space for temporary WAV, PNG, SRT, and MP4 files β€” non-JSON files are cleaned on each run by `rem_temp_files()`.
Expand All @@ -71,13 +76,15 @@ Uses Python's `schedule` library (in-process, not OS cron). The scheduled job sp

## Configuration

All config lives in `config.json` at the project root. See `config.example.json` for the full template and `docs/Configuration.md` for reference. Key external dependencies to configure:
All config lives in `config.json` at the project root. See `config.example.json` for the full template and `docs/Configuration.md` for reference. Per-feature docs live alongside it: `docs/YouTube.md`, `docs/TwitterBot.md`, `docs/AffiliateMarketing.md`, `docs/Roadmap.md` β€” check there before re-deriving feature behavior. Key external dependencies to configure:
- **ImageMagick** β€” required for MoviePy subtitle rendering (`imagemagick_path`)
- **Firefox profile** β€” must be pre-logged-in to target platforms (`firefox_profile`)
- **Ollama** β€” for LLM text generation (via `ollama` Python SDK)
- **Ollama** β€” for LLM text generation (via `ollama` Python SDK); server URL via `ollama_base_url` (default: `http://127.0.0.1:11434`)
- **Nano Banana 2** β€” for image generation (Gemini image API)
- **Go** β€” only needed for Outreach (Google Maps scraper)

## Contributing

PRs go against `main`. One feature/fix per PR. Open an issue first. Use `WIP` label for in-progress PRs.

Commit messages use imperative summaries (`Fix ...`, `Update ...`, `Switch ...`) with an optional issue ref in parens (e.g., `Fix critical supply chain poisoning vulnerability in song archive download (#133)`).