CI + config hardening + autostart & system-tray cat#43
Merged
Conversation
- New mycat/secret_store.py: secure_file() restricts config.ini to the owner (0600), and get/set/delete_secret() back the OS keyring with a graceful no-op fallback when keyring (or a backend) is unavailable. - Every config writer (llm_prompt, reminder, main) now chmod 600 the file. - The OpenAI key is read from the keyring first, then the env var. - keyring is an optional dependency (`pip install mycat[secure]`).
- mycat/autostart.py: cross-platform "start on login" (Linux XDG .desktop, Windows HKCU Run key), no-op elsewhere. - A persistent cat icon in the system tray with a quick menu (Chat, Reminder…, LLM…, Start on login, Quit); double-click raises the cat. - "Start on login" is also available from the right-click context menu.
- .github/workflows/ci.yml: on push/PR, run `ruff check .` and the test suite (headless Qt via offscreen) on Python 3.10 and 3.12. - Apply ruff autofixes repo-wide (import sorting, modern typing, etc.) and wrap the remaining long log lines so `ruff check .` passes.
6 tasks
yumiaura
added a commit
that referenced
this pull request
Jun 12, 2026
Resolve mycat/main.py in favor of the in-memory pipeline: the conflicts were our QBuffer-based loading versus the pre-refactor temp-file code re-applied by the #43 squash merge; main brought no other changes.
yumiaura
added a commit
that referenced
this pull request
Jun 12, 2026
Bring in the #43 (CI, secret_store, autostart, tray) and #44 (in-memory skins) squash merges. Resolutions: - llm.py: keep the multi-vendor initialize(); drop the superseded two-backend version re-applied by the squash. - llm_openai.py: keep this branch's deletion (replaced by the dependency-free llm_openai_compat adapter). - llm_ui.py: keep the json import for one-line error serialization; drop the unused html import flagged by the now-enforced ruff CI. - CHANGELOG.md: combine both Unreleased sections.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements 3 of the 4 prioritised "right now" items (shop excluded as requested). Item 2 (in-memory skin loading) is deliberately left for its own focused PR — see the note at the bottom.
✅ Included
1. CI with tests + ruff
.github/workflows/ci.yml— on push/PR, runsruff check .and the pytest suite (headless Qt via the offscreen platform) on Python 3.10 and 3.12.3. Config hardening: chmod 600 + keyring
mycat/secret_store.py:secure_file()restrictsconfig.inito the owner (0600);get/set/delete_secret()back the OS keyring with a graceful no-op fallback when keyring (or a backend) is missing.llm_prompt,reminder,main) now chmod 600 the file.keyringis an optional dependency:pip install mycat[secure].4. Autostart + system-tray cat
mycat/autostart.py: cross-platform "start on login" (Linux XDG.desktop, WindowsHKCU\…\Run), no-op elsewhere.⏭️ Deferred — item 2 (eliminate /tmp/mycat → in-memory skins)
This refactors the core image pipeline (
load_packaged_images, the per-frameQMovie/QPixmaprecreation, skin switching) away fromtempfile.gettempdir()/mycat/{static.png,animation.gif}to an in-memoryQMoviefed by aQBuffer. It's the right fix (closes the predictable-shared-temp security issue + a bug class) but touches global state and every animation path, so it deserves its own change with thorough live testing rather than being rushed. Plan:QMoviefrom a parentedQBuffer(gif_bytes), derive the first frame viajumpToFrame(0).currentPixmap(), store the gif bytes on the window for restarts, drop the temp files entirely.Test plan
python -m pytestpasses locally (29 tests).