Skip to content

CI + config hardening + autostart & system-tray cat#43

Merged
yumiaura merged 3 commits into
mainfrom
feat/ci-hardening-autostart
Jun 12, 2026
Merged

CI + config hardening + autostart & system-tray cat#43
yumiaura merged 3 commits into
mainfrom
feat/ci-hardening-autostart

Conversation

@yumiaura

Copy link
Copy Markdown
Owner

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, runs ruff check . and the pytest suite (headless Qt via the offscreen platform) on Python 3.10 and 3.12.
  • Made the repo ruff-clean: applied autofixes (import sorting, modern typing, comprehensions) and wrapped the remaining long log lines.

3. Config hardening: chmod 600 + keyring

  • New mycat/secret_store.py: secure_file() restricts config.ini to the owner (0600); get/set/delete_secret() back the OS keyring with a graceful no-op fallback when keyring (or a backend) is missing.
  • 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].

4. Autostart + system-tray cat

  • New mycat/autostart.py: cross-platform "start on login" (Linux XDG .desktop, Windows HKCU\…\Run), 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 in the right-click context menu.

⏭️ Deferred — item 2 (eliminate /tmp/mycat → in-memory skins)

This refactors the core image pipeline (load_packaged_images, the per-frame QMovie/QPixmap recreation, skin switching) away from tempfile.gettempdir()/mycat/{static.png,animation.gif} to an in-memory QMovie fed by a QBuffer. 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: QMovie from a parented QBuffer(gif_bytes), derive the first frame via jumpToFrame(0).currentPixmap(), store the gif bytes on the window for restarts, drop the temp files entirely.

Test plan

  • CI is green (ruff + pytest, 3.10/3.12).
  • Config files are written with mode 600.
  • Tray icon appears; menu actions work; "Start on login" toggles the autostart entry.
  • python -m pytest passes locally (29 tests).

yumiaura added 3 commits June 11, 2026 19:04
- 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.

@yumiaura yumiaura left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yumiaura yumiaura merged commit 2cf53f9 into main Jun 12, 2026
3 checks passed
@yumiaura yumiaura deleted the feat/ci-hardening-autostart branch June 12, 2026 09:34
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant