plex-tui 0.2.0__tar.gz → 0.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. plex_tui-0.3.0/.github/workflows/aur.yml +52 -0
  2. plex_tui-0.3.0/.github/workflows/bump.yml +108 -0
  3. plex_tui-0.3.0/.github/workflows/ci.yml +36 -0
  4. plex_tui-0.3.0/.github/workflows/publish-pypi.yml +48 -0
  5. plex_tui-0.3.0/.github/workflows/publish-testpypi.yml +41 -0
  6. {plex_tui-0.2.0 → plex_tui-0.3.0}/.gitignore +1 -0
  7. {plex_tui-0.2.0 → plex_tui-0.3.0}/AGENTS.md +21 -0
  8. plex_tui-0.3.0/CHANGELOG.md +69 -0
  9. {plex_tui-0.2.0 → plex_tui-0.3.0}/Makefile +5 -2
  10. plex_tui-0.3.0/PACKAGING.md +102 -0
  11. {plex_tui-0.2.0 → plex_tui-0.3.0}/PKG-INFO +90 -22
  12. {plex_tui-0.2.0 → plex_tui-0.3.0}/README.md +89 -21
  13. plex_tui-0.3.0/RELEASE.md +152 -0
  14. plex_tui-0.3.0/ROADMAP.md +39 -0
  15. {plex_tui-0.2.0 → plex_tui-0.3.0}/config.example.toml +4 -1
  16. plex_tui-0.3.0/packaging/aur/.SRCINFO +23 -0
  17. plex_tui-0.3.0/packaging/aur/PKGBUILD +43 -0
  18. plex_tui-0.3.0/packaging/aur/README.md +41 -0
  19. plex_tui-0.3.0/packaging/homebrew/README.md +33 -0
  20. {plex_tui-0.2.0 → plex_tui-0.3.0}/pyproject.toml +1 -1
  21. plex_tui-0.3.0/scripts/check_release.py +172 -0
  22. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/__init__.py +1 -1
  23. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/__main__.py +6 -1
  24. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/app.py +1152 -133
  25. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/artwork.py +61 -21
  26. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/auth.py +1 -0
  27. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/config.py +14 -0
  28. {plex_tui-0.2.0 → plex_tui-0.3.0}/tests/test_app_helpers.py +292 -6
  29. plex_tui-0.3.0/tests/test_app_navigation.py +1549 -0
  30. plex_tui-0.3.0/tests/test_artwork.py +153 -0
  31. {plex_tui-0.2.0 → plex_tui-0.3.0}/tests/test_cli.py +16 -0
  32. {plex_tui-0.2.0 → plex_tui-0.3.0}/tests/test_config.py +15 -1
  33. plex_tui-0.3.0/tests/test_release_checks.py +109 -0
  34. plex_tui-0.2.0/CHANGELOG.md +0 -34
  35. plex_tui-0.2.0/PACKAGING.md +0 -108
  36. plex_tui-0.2.0/RELEASE.md +0 -67
  37. plex_tui-0.2.0/ROADMAP.md +0 -34
  38. plex_tui-0.2.0/tests/test_app_navigation.py +0 -609
  39. plex_tui-0.2.0/tests/test_artwork.py +0 -84
  40. {plex_tui-0.2.0 → plex_tui-0.3.0}/LICENSE +0 -0
  41. {plex_tui-0.2.0 → plex_tui-0.3.0}/docs/assets/grid-view.png +0 -0
  42. {plex_tui-0.2.0 → plex_tui-0.3.0}/docs/assets/list-view.png +0 -0
  43. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/models.py +0 -0
  44. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/player.py +0 -0
  45. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/plex_service.py +0 -0
  46. {plex_tui-0.2.0 → plex_tui-0.3.0}/src/plextui/smoke.py +0 -0
  47. {plex_tui-0.2.0 → plex_tui-0.3.0}/tests/test_auth.py +0 -0
  48. {plex_tui-0.2.0 → plex_tui-0.3.0}/tests/test_player.py +0 -0
  49. {plex_tui-0.2.0 → plex_tui-0.3.0}/tests/test_plex_service.py +0 -0
@@ -0,0 +1,52 @@
1
+ name: AUR Package
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ paths:
7
+ - ".github/workflows/aur.yml"
8
+ - "packaging/aur/**"
9
+ pull_request:
10
+ branches: ["main"]
11
+ paths:
12
+ - ".github/workflows/aur.yml"
13
+ - "packaging/aur/**"
14
+ workflow_dispatch:
15
+
16
+ env:
17
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
18
+
19
+ jobs:
20
+ makepkg:
21
+ runs-on: ubuntu-latest
22
+ container: archlinux:base-devel
23
+
24
+ steps:
25
+ - name: Install runner dependencies
26
+ run: |
27
+ pacman -Syu --noconfirm git namcap sudo
28
+
29
+ - name: Check out repository
30
+ uses: actions/checkout@v5
31
+
32
+ - name: Create build user
33
+ run: |
34
+ useradd --create-home --shell /bin/bash builder
35
+ echo "builder ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/builder
36
+ chown -R builder:builder "$GITHUB_WORKSPACE"
37
+
38
+ - name: Build and check package
39
+ working-directory: packaging/aur
40
+ run: |
41
+ sudo -u builder makepkg --clean --syncdeps --noconfirm --check
42
+
43
+ - name: Generate .SRCINFO
44
+ working-directory: packaging/aur
45
+ run: |
46
+ sudo -u builder makepkg --printsrcinfo > .SRCINFO.generated
47
+ diff -u .SRCINFO .SRCINFO.generated
48
+
49
+ - name: Run namcap
50
+ working-directory: packaging/aur
51
+ run: |
52
+ namcap PKGBUILD ./*.pkg.tar.*
@@ -0,0 +1,108 @@
1
+ name: Version Bump and Release
2
+
3
+ on:
4
+ pull_request:
5
+ types: ["closed"]
6
+ branches: ["main"]
7
+
8
+ env:
9
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
10
+
11
+ jobs:
12
+ bump-version:
13
+ if: |
14
+ github.event.pull_request.merged == true &&
15
+ (
16
+ contains(github.event.pull_request.title, '#patch') ||
17
+ contains(github.event.pull_request.title, '#minor') ||
18
+ contains(github.event.pull_request.title, '#major') ||
19
+ contains(github.event.pull_request.body, '#patch') ||
20
+ contains(github.event.pull_request.body, '#minor') ||
21
+ contains(github.event.pull_request.body, '#major')
22
+ )
23
+ runs-on: ubuntu-latest
24
+ permissions:
25
+ contents: write
26
+ outputs:
27
+ new_tag: ${{ steps.bump.outputs.new_version }}
28
+ previous_tag: ${{ steps.bump.outputs.previous_version }}
29
+ skipped: ${{ steps.bump.outputs.skipped }}
30
+ release_requested: ${{ steps.bump.outputs.should_release }}
31
+
32
+ steps:
33
+ - name: Check out repository
34
+ uses: actions/checkout@v5
35
+ with:
36
+ fetch-depth: 0
37
+
38
+ - name: Bump version tag
39
+ id: bump
40
+ uses: so1omon563/custom-semver-bumper@v1
41
+ with:
42
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43
+ branch_name: ${{ github.event.pull_request.head.ref }}
44
+ # Floating pointer tags are owned by release-creator so they only move
45
+ # when a GitHub Release is intentionally published.
46
+
47
+ create-release:
48
+ name: Create GitHub Release
49
+ needs: bump-version
50
+ if: |
51
+ needs.bump-version.outputs.release_requested == 'true' &&
52
+ needs.bump-version.outputs.skipped != 'true'
53
+ runs-on: ubuntu-latest
54
+ permissions:
55
+ contents: write
56
+
57
+ steps:
58
+ - name: Check out repository
59
+ uses: actions/checkout@v5
60
+ with:
61
+ fetch-depth: 0
62
+
63
+ - name: Create release
64
+ uses: so1omon563/release-creator@v1
65
+ with:
66
+ token: ${{ secrets.GITHUB_TOKEN }}
67
+ tag: ${{ needs.bump-version.outputs.new_tag }}
68
+ from-tag: ${{ needs.bump-version.outputs.previous_tag }}
69
+ tag-prefix: v
70
+ notes-format: grouped
71
+ move-major-tag: "true"
72
+ move-minor-tag: "true"
73
+
74
+ publish-pypi:
75
+ name: Publish to PyPI
76
+ needs:
77
+ - bump-version
78
+ - create-release
79
+ runs-on: ubuntu-latest
80
+ environment: pypi
81
+ permissions:
82
+ contents: read
83
+ id-token: write
84
+
85
+ steps:
86
+ - name: Check out release tag
87
+ uses: actions/checkout@v5
88
+ with:
89
+ ref: ${{ needs.bump-version.outputs.new_tag }}
90
+
91
+ - name: Set up Python
92
+ uses: actions/setup-python@v6
93
+ with:
94
+ python-version: "3.13"
95
+
96
+ - name: Install build tools
97
+ run: |
98
+ python -m pip install --upgrade pip
99
+ python -m pip install build twine
100
+
101
+ - name: Build package
102
+ run: python -m build
103
+
104
+ - name: Check package metadata
105
+ run: python -m twine check dist/*
106
+
107
+ - name: Publish package
108
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,36 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ branches: ["main"]
8
+
9
+ env:
10
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
11
+
12
+ jobs:
13
+ check:
14
+ name: Python ${{ matrix.python-version }}
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ python-version: ["3.11", "3.13"]
20
+
21
+ steps:
22
+ - name: Check out repository
23
+ uses: actions/checkout@v5
24
+
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v6
27
+ with:
28
+ python-version: ${{ matrix.python-version }}
29
+
30
+ - name: Install package and test dependencies
31
+ run: |
32
+ python -m pip install --upgrade pip
33
+ python -m pip install -e ".[dev]"
34
+
35
+ - name: Run checks
36
+ run: make PYTHON=python check
@@ -0,0 +1,48 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ ref:
7
+ description: "Git ref to publish, such as v0.2.0"
8
+ required: true
9
+ type: string
10
+ release:
11
+ types: ["published"]
12
+
13
+ permissions:
14
+ contents: read
15
+ id-token: write
16
+
17
+ env:
18
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
19
+
20
+ jobs:
21
+ publish:
22
+ runs-on: ubuntu-latest
23
+ environment: pypi
24
+
25
+ steps:
26
+ - name: Check out repository
27
+ uses: actions/checkout@v5
28
+ with:
29
+ ref: ${{ github.event.release.tag_name || inputs.ref }}
30
+
31
+ - name: Set up Python
32
+ uses: actions/setup-python@v6
33
+ with:
34
+ python-version: "3.13"
35
+
36
+ - name: Install build tools
37
+ run: |
38
+ python -m pip install --upgrade pip
39
+ python -m pip install build twine
40
+
41
+ - name: Build package
42
+ run: python -m build
43
+
44
+ - name: Check package metadata
45
+ run: python -m twine check dist/*
46
+
47
+ - name: Publish package
48
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,41 @@
1
+ name: Publish to TestPyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+ id-token: write
9
+
10
+ env:
11
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
12
+
13
+ jobs:
14
+ publish:
15
+ runs-on: ubuntu-latest
16
+ environment: testpypi
17
+
18
+ steps:
19
+ - name: Check out repository
20
+ uses: actions/checkout@v5
21
+
22
+ - name: Set up Python
23
+ uses: actions/setup-python@v6
24
+ with:
25
+ python-version: "3.13"
26
+
27
+ - name: Install build tools
28
+ run: |
29
+ python -m pip install --upgrade pip
30
+ python -m pip install build twine
31
+
32
+ - name: Build package
33
+ run: python -m build
34
+
35
+ - name: Check package metadata
36
+ run: python -m twine check dist/*
37
+
38
+ - name: Publish package to TestPyPI
39
+ uses: pypa/gh-action-pypi-publish@release/v1
40
+ with:
41
+ repository-url: https://test.pypi.org/legacy/
@@ -1,4 +1,5 @@
1
1
  .venv/
2
+ .venv*/
2
3
  __pycache__/
3
4
  *.py[cod]
4
5
  .pytest_cache/
@@ -11,6 +11,9 @@ through `mpv`.
11
11
  - `player.py`: `mpv` launch, stream selection, and playback diagnostics.
12
12
  - `config.py`, `auth.py`, `artwork.py`, `models.py`: supporting modules.
13
13
  - `tests/`: pytest suite, split by app helpers/navigation and service modules.
14
+ - `.github/workflows/`: CI plus PyPI/TestPyPI/AUR validation workflows.
15
+ - `packaging/`: Homebrew and AUR maintenance notes; `packaging/aur/` contains
16
+ the source copy of `PKGBUILD` and `.SRCINFO`.
14
17
  - `README.md`, `PACKAGING.md`, `RELEASE.md`, `ROADMAP.md`: user and release docs.
15
18
  - `config.example.toml`: example user configuration.
16
19
 
@@ -59,6 +62,8 @@ make smoke
59
62
  ```
60
63
 
61
64
  For packaging or metadata changes, also run `make check-package` or `make check`.
65
+ For AUR package changes, run the `AUR Package` workflow or validate with
66
+ `makepkg` on Arch.
62
67
 
63
68
  ## Commit & Pull Request Guidelines
64
69
 
@@ -73,6 +78,22 @@ Pull requests should include:
73
78
  - Screenshots or terminal notes for TUI changes when useful.
74
79
  - Any config, packaging, or migration impact.
75
80
 
81
+ Use PRs for repository changes. When publishing local commits, branch from
82
+ `main` with a scoped name such as `codex/release-prep`, push that branch, and
83
+ open a draft PR instead of pushing directly to `main`. Treat `main` as a
84
+ protected branch even before GitHub branch protection or rulesets are enabled.
85
+
86
+ GitHub CLI notes:
87
+
88
+ - `gh auth status` may fail inside the sandbox even when the user is logged in
89
+ via the macOS keyring. Re-run `gh` auth, PR, and push operations outside the
90
+ sandbox when keyring access is required.
91
+ - Prefer the GitHub connector for PR creation when it has access. If it returns
92
+ `403 Resource not accessible by integration`, fall back to
93
+ `gh pr create --draft` using the authenticated CLI session.
94
+ - Keep PR bodies explicit about validation, especially `make check` results and
95
+ release workflow checks such as `actionlint`.
96
+
76
97
  ## Security & Configuration Tips
77
98
 
78
99
  Never commit real Plex tokens, account tokens, debug logs, or local config files.
@@ -0,0 +1,69 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ ## 0.3.0 - 2026-06-12
6
+
7
+ - Added `plex-tui --diagnostics` for collecting environment and playback setup details.
8
+ - Added PR-merge version tagging, GitHub Release creation, and PyPI publishing workflow automation.
9
+ - Added a local release workflow and version metadata verification target.
10
+ - Added targeted playback troubleshooting hints for common `mpv` and Plex stream failures.
11
+ - Added a compact active-playback footer while media is playing.
12
+ - Simplified Settings rows into inline controls for numeric values, toggles, and option cycling.
13
+ - Tuned grid density geometry and stabilized unloaded poster placeholders.
14
+ - Added explicit Kitty renderer fallback diagnostics while native images remain disabled inside Textual.
15
+
16
+ ## 0.2.1 - 2026-06-11
17
+
18
+ - Added GitHub Actions CI and PyPI Trusted Publishing workflow scaffolding.
19
+ - Added a manual TestPyPI Trusted Publishing workflow.
20
+ - Published `plex-tui` to PyPI and updated install documentation.
21
+ - Published the Homebrew tap and updated install documentation.
22
+ - Added Arch package validation workflow scaffolding.
23
+ - Published the Arch AUR package and updated install documentation.
24
+ - Added Arch AUR packaging files and Homebrew packaging notes.
25
+ - Refreshed documentation for current install, packaging, and release workflows.
26
+ - Added a Settings diagnostics action for recent `debug.log` output and playback error details with log context.
27
+ - Clarified Settings rows with action-type tags and per-row detail-pane guidance.
28
+ - Improved grid browsing smoothness by debouncing detail reloads, throttling artwork prefetch, and avoiding cached-artwork rendering during selection redraws.
29
+ - Made grid detail reloads idle-aware so rapid selection movement no longer starts stale Plex reload workers.
30
+ - Made grid artwork appear progressively as each card renders and added stronger focused-pane styling.
31
+ - Added an explicit `[FOCUS]` marker to the active pane title.
32
+ - Kept focus markers in sync when using Tab navigation and refocused the visible browser after list/grid view changes.
33
+ - Made Tab navigation cycle explicitly through Libraries, Media, and Details panes.
34
+ - Added a short idle debounce for list detail reloads to reduce detail-pane churn during fast row movement.
35
+ - Increased the list detail debounce to further reduce repeated artwork loads during row navigation.
36
+ - Split detail text refresh from detail artwork loading so artwork waits for a longer stable selection window.
37
+
38
+ ## 0.2.0 - 2026-06-11
39
+
40
+ - Improved README structure and expanded the post-0.1.0 roadmap.
41
+ - Grouped the Settings screen into account, stream, playback, artwork, browsing, and diagnostics sections.
42
+ - Added direct Settings input for custom `mpv` window sizes.
43
+ - Added direct Settings input for custom page size and auto-load threshold values.
44
+ - Added confirmation for destructive Settings preference clears.
45
+ - Replaced the heavy selected grid-card border with a quieter marker/footer treatment.
46
+ - Added configurable compact, comfortable, and large grid density modes.
47
+ - Kept Settings open after value changes and added clearer changed-value feedback.
48
+ - Preserved Settings row highlighting after opening Settings and changing values.
49
+ - Added README screenshots for grid and list views.
50
+ - Clarified README install instructions for `main` versus tagged releases.
51
+ - Improved active playback status, details-pane playback context, and abnormal `mpv` exit diagnostics.
52
+
53
+ ## 0.1.0 - 2026-06-11
54
+
55
+ - Added Plex PIN login and server selection.
56
+ - Added library browsing with paged loading and automatic loading near the end of the list.
57
+ - Added current-library search with paged results and bounded global search.
58
+ - Added playback through `mpv` with Plex resume and progress reporting.
59
+ - Added audio and subtitle pickers with saved language preferences.
60
+ - Added support for external subtitles and embedded PGS/VOBSUB subtitle playback.
61
+ - Added media details for metadata, audio tracks, subtitle tracks, and saved stream preferences.
62
+ - Added settings actions for reload, relogin, and audio/subtitle preference management.
63
+ - Added settings actions for page size, auto-load threshold, mpv window sizing, and debug log visibility.
64
+ - Added playback diagnostics with token-redacted `debug.log` output.
65
+ - Added development workflow targets, smoke checks, and Linux/macOS setup documentation.
66
+ - Added release checklist and packaging option documentation.
67
+ - Added CLI flags for version, config/debug paths, and smoke checks.
68
+ - Added configurable page size and auto-load threshold for browsing performance.
69
+ - Added grid page navigation, richer grid status text, and adjacent-page artwork prefetching.
@@ -1,4 +1,4 @@
1
- .PHONY: install-dev run test compile smoke build check-package check clean
1
+ .PHONY: install-dev run test compile smoke build check-package check-release check clean
2
2
 
3
3
  PYTHON ?= .venv/bin/python
4
4
 
@@ -23,7 +23,10 @@ build:
23
23
  check-package: build
24
24
  $(PYTHON) -m twine check dist/*
25
25
 
26
- check: smoke test compile check-package
26
+ check-release:
27
+ $(PYTHON) scripts/check_release.py
28
+
29
+ check: smoke test compile check-release check-package
27
30
 
28
31
  clean:
29
32
  rm -rf build dist *.egg-info src/*.egg-info
@@ -0,0 +1,102 @@
1
+ # Packaging
2
+
3
+ plex-tui is distributed through PyPI, a Homebrew tap, and the Arch AUR. The
4
+ source repository remains the canonical place for versioning, release notes,
5
+ and validation.
6
+
7
+ ## Supported Channels
8
+
9
+ ### PyPI
10
+
11
+ Recommended cross-platform install:
12
+
13
+ ```bash
14
+ pipx install plex-tui
15
+ ```
16
+
17
+ PyPI publishing uses GitHub Actions Trusted Publishing:
18
+
19
+ - Workflow: `.github/workflows/publish-pypi.yml`
20
+ - PyPI environment: `pypi`
21
+ - Trigger: GitHub Release publication, or manual workflow dispatch with a ref
22
+
23
+ TestPyPI uses a separate manual workflow:
24
+
25
+ - Workflow: `.github/workflows/publish-testpypi.yml`
26
+ - TestPyPI environment: `testpypi`
27
+
28
+ Install tests from TestPyPI need PyPI as a dependency fallback:
29
+
30
+ ```bash
31
+ python -m pip install \
32
+ --index-url https://test.pypi.org/simple/ \
33
+ --extra-index-url https://pypi.org/simple/ \
34
+ plex-tui
35
+ ```
36
+
37
+ ### Homebrew
38
+
39
+ Tap repository:
40
+
41
+ ```text
42
+ https://github.com/so1omon563/homebrew-plex-tui
43
+ ```
44
+
45
+ User install:
46
+
47
+ ```bash
48
+ brew tap so1omon563/plex-tui
49
+ brew install plex-tui
50
+ ```
51
+
52
+ The formula depends on `mpv` and `python@3.13`, then installs the Python app in
53
+ a Homebrew-managed virtualenv. The first install can take several minutes
54
+ because native Python resources such as `pillow` are built from source.
55
+
56
+ Validation commands:
57
+
58
+ ```bash
59
+ brew test so1omon563/plex-tui/plex-tui
60
+ brew audit --strict --online so1omon563/plex-tui/plex-tui
61
+ ```
62
+
63
+ ### Arch AUR
64
+
65
+ AUR package:
66
+
67
+ ```text
68
+ https://aur.archlinux.org/packages/plex-tui
69
+ ```
70
+
71
+ User install:
72
+
73
+ ```bash
74
+ paru -S plex-tui
75
+ ```
76
+
77
+ The source copy for AUR metadata lives in `packaging/aur/`. The package uses
78
+ Arch system dependencies, including `mpv`, `python-textual`, `python-pillow`,
79
+ `python-plexapi`, `python-platformdirs`, and `python-rich`.
80
+
81
+ Validation is handled by `.github/workflows/aur.yml`, which runs inside
82
+ `archlinux:base-devel` and checks:
83
+
84
+ - `makepkg --clean --syncdeps --noconfirm --check`
85
+ - `.SRCINFO` is in sync with `PKGBUILD`
86
+ - `namcap PKGBUILD ./*.pkg.tar.*`
87
+
88
+ ## Release Maintenance
89
+
90
+ For each new app release:
91
+
92
+ 1. Publish and validate PyPI.
93
+ 2. Update the Homebrew tap formula URL/hash and Python resources.
94
+ 3. Update `packaging/aur/PKGBUILD` and `packaging/aur/.SRCINFO`.
95
+ 4. Run packaging validation workflows.
96
+ 5. Push the AUR package repo update after the workflow passes.
97
+
98
+ ## Known Follow-Up
99
+
100
+ - Automate Homebrew tap updates after PyPI publishing.
101
+ - Investigate faster Homebrew installs without compromising formula quality.
102
+ - Consider standalone artifacts only after the app behavior stabilizes.