mkv-episode-matcher 0.4.1__tar.gz → 1.1.4__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 (146) hide show
  1. mkv_episode_matcher-1.1.4/.claude/settings.local.json +13 -0
  2. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.coverage +0 -0
  3. mkv_episode_matcher-1.1.4/.github/workflows/build_release.yml +222 -0
  4. mkv_episode_matcher-1.1.4/.github/workflows/claude-code-review.yml +78 -0
  5. mkv_episode_matcher-1.1.4/.github/workflows/claude.yml +64 -0
  6. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.github/workflows/documentation.yml +9 -5
  7. mkv_episode_matcher-1.1.4/.github/workflows/install-test.yml +115 -0
  8. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.github/workflows/python-publish.yml +2 -2
  9. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.github/workflows/tests.yml +10 -19
  10. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.gitignore +2 -0
  11. mkv_episode_matcher-1.1.4/.python-version +1 -0
  12. mkv_episode_matcher-1.1.4/CHANGELOG.md +180 -0
  13. mkv_episode_matcher-1.1.4/CLAUDE.md +148 -0
  14. mkv_episode_matcher-1.1.4/LICENSE +21 -0
  15. mkv_episode_matcher-1.1.4/PKG-INFO +219 -0
  16. mkv_episode_matcher-1.1.4/README.md +168 -0
  17. mkv_episode_matcher-1.1.4/build_executables.py +102 -0
  18. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/docs/api/index.md +16 -9
  19. mkv_episode_matcher-1.1.4/docs/changelog.md +92 -0
  20. mkv_episode_matcher-1.1.4/docs/cli.md +142 -0
  21. mkv_episode_matcher-1.1.4/docs/configuration.md +203 -0
  22. mkv_episode_matcher-1.1.4/docs/images/dashboard_initializing.png +0 -0
  23. mkv_episode_matcher-1.1.4/docs/images/dashboard_ready.png +0 -0
  24. mkv_episode_matcher-1.1.4/docs/images/folder_selection.png +0 -0
  25. mkv_episode_matcher-1.1.4/docs/images/review_selection.png +0 -0
  26. mkv_episode_matcher-1.1.4/docs/images/scan_results.png +0 -0
  27. mkv_episode_matcher-1.1.4/docs/images/web_ui_dashboard.png +0 -0
  28. mkv_episode_matcher-1.1.4/docs/images/web_ui_help.png +0 -0
  29. mkv_episode_matcher-1.1.4/docs/images/web_ui_settings.png +0 -0
  30. mkv_episode_matcher-1.1.4/docs/installation.md +311 -0
  31. mkv_episode_matcher-1.1.4/docs/quickstart.md +201 -0
  32. mkv_episode_matcher-1.1.4/docs/tips.md +319 -0
  33. mkv_episode_matcher-1.1.4/main.py +13 -0
  34. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/mkv_episode_matcher/__init__.py +2 -2
  35. mkv_episode_matcher-1.1.4/mkv_episode_matcher/__main__.py +10 -0
  36. mkv_episode_matcher-1.1.4/mkv_episode_matcher/asr_models.py +512 -0
  37. mkv_episode_matcher-1.1.4/mkv_episode_matcher/backend/dependencies.py +40 -0
  38. mkv_episode_matcher-1.1.4/mkv_episode_matcher/backend/main.py +87 -0
  39. mkv_episode_matcher-1.1.4/mkv_episode_matcher/backend/routers/match.py +122 -0
  40. mkv_episode_matcher-1.1.4/mkv_episode_matcher/backend/routers/scan.py +99 -0
  41. mkv_episode_matcher-1.1.4/mkv_episode_matcher/backend/routers/system.py +43 -0
  42. mkv_episode_matcher-1.1.4/mkv_episode_matcher/backend/routers/websocket.py +18 -0
  43. mkv_episode_matcher-1.1.4/mkv_episode_matcher/backend/socket_manager.py +27 -0
  44. mkv_episode_matcher-1.1.4/mkv_episode_matcher/cli.py +694 -0
  45. mkv_episode_matcher-1.1.4/mkv_episode_matcher/core/config_manager.py +101 -0
  46. mkv_episode_matcher-1.1.4/mkv_episode_matcher/core/engine.py +605 -0
  47. mkv_episode_matcher-1.1.4/mkv_episode_matcher/core/matcher.py +214 -0
  48. mkv_episode_matcher-1.1.4/mkv_episode_matcher/core/model_registry.py +192 -0
  49. mkv_episode_matcher-1.1.4/mkv_episode_matcher/core/models.py +131 -0
  50. mkv_episode_matcher-1.1.4/mkv_episode_matcher/core/providers/asr.py +85 -0
  51. mkv_episode_matcher-1.1.4/mkv_episode_matcher/core/providers/subtitles.py +398 -0
  52. mkv_episode_matcher-1.1.4/mkv_episode_matcher/core/utils.py +197 -0
  53. mkv_episode_matcher-1.1.4/mkv_episode_matcher/episode_identification.py +582 -0
  54. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/.gitignore +24 -0
  55. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/README.md +73 -0
  56. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/dist/assets/index-BXSjswp-.js +14 -0
  57. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/dist/assets/index-BwmmBsFA.css +1 -0
  58. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/dist/index.html +14 -0
  59. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/dist/vite.svg +1 -0
  60. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/eslint.config.js +23 -0
  61. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/index.html +13 -0
  62. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/package-lock.json +3864 -0
  63. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/package.json +32 -0
  64. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/public/vite.svg +1 -0
  65. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/App.css +42 -0
  66. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/App.tsx +400 -0
  67. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/assets/react.svg +1 -0
  68. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/components/FileBrowser.tsx +173 -0
  69. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/components/FileReviewGrid.tsx +81 -0
  70. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/components/Layout.tsx +44 -0
  71. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/components/SettingsView.tsx +193 -0
  72. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/components/Sidebar.tsx +81 -0
  73. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/index.css +201 -0
  74. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/src/main.tsx +10 -0
  75. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/tsconfig.app.json +28 -0
  76. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/tsconfig.json +7 -0
  77. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/tsconfig.node.json +26 -0
  78. mkv_episode_matcher-1.1.4/mkv_episode_matcher/frontend/vite.config.ts +20 -0
  79. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/mkv_episode_matcher/subtitle_utils.py +28 -28
  80. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/mkv_episode_matcher/tmdb_client.py +84 -14
  81. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/mkv_episode_matcher/utils.py +227 -114
  82. mkv_episode_matcher-1.1.4/mkv_episode_matcher.egg-info/PKG-INFO +219 -0
  83. mkv_episode_matcher-1.1.4/mkv_episode_matcher.egg-info/SOURCES.txt +116 -0
  84. mkv_episode_matcher-1.1.4/mkv_episode_matcher.egg-info/entry_points.txt +2 -0
  85. mkv_episode_matcher-1.1.4/mkv_episode_matcher.egg-info/requires.txt +33 -0
  86. mkv_episode_matcher-1.1.4/mkv_match.spec +91 -0
  87. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/pyproject.toml +59 -55
  88. mkv_episode_matcher-1.1.4/scripts/e2e_rename_test.py +35 -0
  89. mkv_episode_matcher-1.1.4/scripts/measure_asr_baseline.py +72 -0
  90. mkv_episode_matcher-1.1.4/scripts/test_ffmpeg_install.py +94 -0
  91. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/setup.cfg +1 -1
  92. mkv_episode_matcher-1.1.4/test_functionality.py +161 -0
  93. mkv_episode_matcher-1.1.4/tests/debug_picker.py +24 -0
  94. mkv_episode_matcher-1.1.4/tests/test_backend_singleton.py +37 -0
  95. mkv_episode_matcher-1.1.4/tests/test_config_special_characters.py +101 -0
  96. mkv_episode_matcher-1.1.4/tests/test_core_utils_windows_paths.py +347 -0
  97. mkv_episode_matcher-1.1.4/tests/test_engine_v2.py +503 -0
  98. mkv_episode_matcher-1.1.4/tests/test_episode_identification.py +287 -0
  99. mkv_episode_matcher-1.1.4/tests/test_error_handling.py +250 -0
  100. mkv_episode_matcher-1.1.4/tests/test_main.py +183 -0
  101. mkv_episode_matcher-1.1.4/tests/test_model_registry.py +126 -0
  102. mkv_episode_matcher-1.1.4/tests/test_path_handling.py +123 -0
  103. mkv_episode_matcher-1.1.4/tests/test_path_spaces_quotes.py +334 -0
  104. mkv_episode_matcher-1.1.4/tests/test_tmdb_id_feature.py +372 -0
  105. mkv_episode_matcher-1.1.4/tests/test_trailing_slash.py +84 -0
  106. mkv_episode_matcher-1.1.4/uv.lock +5206 -0
  107. mkv_episode_matcher-0.4.1/.python-version +0 -1
  108. mkv_episode_matcher-0.4.1/PKG-INFO +0 -137
  109. mkv_episode_matcher-0.4.1/README.md +0 -97
  110. mkv_episode_matcher-0.4.1/docs/cli.md +0 -73
  111. mkv_episode_matcher-0.4.1/docs/configuration.md +0 -109
  112. mkv_episode_matcher-0.4.1/docs/installation.md +0 -102
  113. mkv_episode_matcher-0.4.1/docs/quickstart.md +0 -76
  114. mkv_episode_matcher-0.4.1/docs/tips.md +0 -152
  115. mkv_episode_matcher-0.4.1/mkv_episode_matcher/__main__.py +0 -202
  116. mkv_episode_matcher-0.4.1/mkv_episode_matcher/config.py +0 -82
  117. mkv_episode_matcher-0.4.1/mkv_episode_matcher/episode_identification.py +0 -282
  118. mkv_episode_matcher-0.4.1/mkv_episode_matcher/episode_matcher.py +0 -108
  119. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/.gitignore +0 -2
  120. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/Libraries/SubZero/SubZero.py +0 -321
  121. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/Libraries/SubZero/dictionaries/data.py +0 -16700
  122. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/Libraries/SubZero/post_processing.py +0 -260
  123. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/README.md +0 -26
  124. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/imagemaker.py +0 -89
  125. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/pgs2srt.py +0 -150
  126. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/pgsreader.py +0 -225
  127. mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt/requirements.txt +0 -4
  128. mkv_episode_matcher-0.4.1/mkv_episode_matcher/mkv_to_srt.py +0 -302
  129. mkv_episode_matcher-0.4.1/mkv_episode_matcher/speech_to_text.py +0 -96
  130. mkv_episode_matcher-0.4.1/mkv_episode_matcher.egg-info/PKG-INFO +0 -137
  131. mkv_episode_matcher-0.4.1/mkv_episode_matcher.egg-info/SOURCES.txt +0 -51
  132. mkv_episode_matcher-0.4.1/mkv_episode_matcher.egg-info/entry_points.txt +0 -2
  133. mkv_episode_matcher-0.4.1/mkv_episode_matcher.egg-info/requires.txt +0 -23
  134. mkv_episode_matcher-0.4.1/tests/test_main.py +0 -167
  135. mkv_episode_matcher-0.4.1/uv.lock +0 -1923
  136. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.gitattributes +0 -0
  137. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.github/funding.yml +0 -0
  138. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.gitmodules +0 -0
  139. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/.vscode/settings.json +0 -0
  140. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/mkdocs.yml +0 -0
  141. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/mkv_episode_matcher/.gitattributes +0 -0
  142. {mkv_episode_matcher-0.4.1/mkv_episode_matcher/libraries/pgs2srt → mkv_episode_matcher-1.1.4/mkv_episode_matcher/backend/routers}/__init__.py +0 -0
  143. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/mkv_episode_matcher.egg-info/dependency_links.txt +0 -0
  144. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/mkv_episode_matcher.egg-info/top_level.txt +0 -0
  145. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/setup.py +0 -0
  146. {mkv_episode_matcher-0.4.1 → mkv_episode_matcher-1.1.4}/tests/__init__.py +0 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "WebFetch(domain:github.com)",
5
+ "WebFetch(domain:raw.githubusercontent.com)",
6
+ "Bash(uv run --help:*)",
7
+ "Bash(gh run view:*)",
8
+ "Bash(git -C \"D:\\\\mkv-episode-matcher\" log -1 --format=\"%H %s\" .github/workflows/flet-builds.yml)",
9
+ "Bash(git -C \"D:\\\\mkv-episode-matcher\" log --all --oneline -n 20)",
10
+ "Bash(ls:*)"
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,222 @@
1
+ name: Build and Release
2
+
3
+ on:
4
+ # Uncomment to trigger on tags:
5
+ # push:
6
+ # tags:
7
+ # - 'v*'
8
+ workflow_dispatch:
9
+ inputs:
10
+ build_cuda:
11
+ description: 'Build CUDA version (requires self-hosted runner)'
12
+ required: false
13
+ default: false
14
+ type: boolean
15
+
16
+ env:
17
+ # Increase disk space awareness
18
+ PYTHONDONTWRITEBYTECODE: 1
19
+ UV_NO_CACHE: 1
20
+
21
+ jobs:
22
+ # CPU builds on GitHub-hosted runners
23
+ build-cpu:
24
+ name: Build CPU (${{ matrix.os }})
25
+ runs-on: ${{ matrix.os }}
26
+ timeout-minutes: 60
27
+ strategy:
28
+ fail-fast: false
29
+ matrix:
30
+ include:
31
+ - os: windows-latest
32
+ output_name: MKVMatch-Windows-CPU
33
+ archive_ext: zip
34
+ - os: ubuntu-latest
35
+ output_name: MKVMatch-Linux-CPU
36
+ archive_ext: tar.gz
37
+
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+
41
+ # Free up disk space on Linux runners
42
+ - name: Free Disk Space (Linux)
43
+ if: runner.os == 'Linux'
44
+ run: |
45
+ echo "Disk space before cleanup:"
46
+ df -h
47
+ sudo rm -rf /usr/share/dotnet
48
+ sudo rm -rf /usr/local/lib/android
49
+ sudo rm -rf /opt/ghc
50
+ sudo rm -rf /opt/hostedtoolcache/CodeQL
51
+ echo "Disk space after cleanup:"
52
+ df -h
53
+
54
+ - name: Setup Node.js
55
+ uses: actions/setup-node@v4
56
+ with:
57
+ node-version: '20'
58
+ cache: 'npm'
59
+ cache-dependency-path: mkv_episode_matcher/frontend/package-lock.json
60
+
61
+ - name: Build Frontend
62
+ working-directory: mkv_episode_matcher/frontend
63
+ run: |
64
+ npm ci
65
+ npm run build
66
+
67
+ - name: Install uv
68
+ uses: astral-sh/setup-uv@v5
69
+ with:
70
+ enable-cache: true
71
+ cache-dependency-glob: "uv.lock"
72
+
73
+ - name: Set up Python
74
+ run: uv python install 3.12
75
+
76
+ - name: Install Dependencies (CPU)
77
+ run: |
78
+ uv sync --frozen
79
+
80
+ - name: Install PyInstaller
81
+ run: |
82
+ uv pip install pyinstaller
83
+
84
+ - name: Build Executable
85
+ run: |
86
+ uv run pyinstaller mkv_match.spec --clean
87
+
88
+ - name: Check build output
89
+ shell: bash
90
+ run: |
91
+ echo "Build output:"
92
+ ls -la dist/
93
+ if [ -d "dist/mkv-match" ]; then
94
+ echo "Contents of mkv-match folder:"
95
+ ls -la dist/mkv-match/ | head -50
96
+ echo "Total size:"
97
+ du -sh dist/mkv-match/
98
+ fi
99
+
100
+ - name: Create Archive (Windows)
101
+ if: runner.os == 'Windows'
102
+ shell: pwsh
103
+ run: |
104
+ cd dist
105
+ Compress-Archive -Path "mkv-match" -DestinationPath "${{ matrix.output_name }}.zip"
106
+
107
+ - name: Create Archive (Linux)
108
+ if: runner.os == 'Linux'
109
+ run: |
110
+ cd dist
111
+ tar -czf "${{ matrix.output_name }}.tar.gz" mkv-match
112
+
113
+ - name: Upload Artifact
114
+ uses: actions/upload-artifact@v4
115
+ with:
116
+ name: ${{ matrix.output_name }}
117
+ path: |
118
+ dist/${{ matrix.output_name }}.${{ matrix.archive_ext }}
119
+ retention-days: 30
120
+
121
+ # CUDA builds on self-hosted runners (optional)
122
+ build-cuda:
123
+ name: Build CUDA (${{ matrix.os }})
124
+ if: ${{ github.event.inputs.build_cuda == 'true' }}
125
+ runs-on: ${{ matrix.runner }}
126
+ timeout-minutes: 90
127
+ strategy:
128
+ fail-fast: false
129
+ matrix:
130
+ include:
131
+ - os: windows
132
+ runner: [self-hosted, windows, cuda]
133
+ output_name: MKVMatch-Windows-CUDA
134
+ archive_ext: zip
135
+ - os: linux
136
+ runner: [self-hosted, linux, cuda]
137
+ output_name: MKVMatch-Linux-CUDA
138
+ archive_ext: tar.gz
139
+
140
+ steps:
141
+ - uses: actions/checkout@v4
142
+
143
+ - name: Setup Node.js
144
+ uses: actions/setup-node@v4
145
+ with:
146
+ node-version: '20'
147
+
148
+ - name: Build Frontend
149
+ working-directory: mkv_episode_matcher/frontend
150
+ run: |
151
+ npm ci
152
+ npm run build
153
+
154
+ - name: Install uv
155
+ uses: astral-sh/setup-uv@v5
156
+
157
+ - name: Set up Python
158
+ run: uv python install 3.12
159
+
160
+ - name: Install Dependencies (CUDA)
161
+ run: |
162
+ uv sync --extra cu128 --frozen
163
+
164
+ - name: Verify CUDA availability
165
+ run: |
166
+ uv run python -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}'); print(f'CUDA device: {torch.cuda.get_device_name(0) if torch.cuda.is_available() else \"N/A\"}')"
167
+
168
+ - name: Install PyInstaller
169
+ run: |
170
+ uv pip install pyinstaller
171
+
172
+ - name: Build Executable
173
+ run: |
174
+ uv run pyinstaller mkv_match.spec --clean
175
+
176
+ - name: Create Archive (Windows)
177
+ if: matrix.os == 'windows'
178
+ shell: pwsh
179
+ run: |
180
+ cd dist
181
+ Compress-Archive -Path "mkv-match" -DestinationPath "${{ matrix.output_name }}.zip"
182
+
183
+ - name: Create Archive (Linux)
184
+ if: matrix.os == 'linux'
185
+ run: |
186
+ cd dist
187
+ tar -czf "${{ matrix.output_name }}.tar.gz" mkv-match
188
+
189
+ - name: Upload Artifact
190
+ uses: actions/upload-artifact@v4
191
+ with:
192
+ name: ${{ matrix.output_name }}
193
+ path: |
194
+ dist/${{ matrix.output_name }}.${{ matrix.archive_ext }}
195
+ retention-days: 30
196
+
197
+ # Create release when triggered by a tag
198
+ release:
199
+ needs: [build-cpu]
200
+ runs-on: ubuntu-latest
201
+ if: startsWith(github.ref, 'refs/tags/')
202
+ permissions:
203
+ contents: write
204
+
205
+ steps:
206
+ - name: Download All Artifacts
207
+ uses: actions/download-artifact@v4
208
+ with:
209
+ path: artifacts
210
+
211
+ - name: Display structure of downloaded files
212
+ run: ls -R artifacts
213
+
214
+ - name: Create Release
215
+ uses: softprops/action-gh-release@v2
216
+ with:
217
+ files: |
218
+ artifacts/**/*.zip
219
+ artifacts/**/*.tar.gz
220
+ generate_release_notes: true
221
+ draft: false
222
+ prerelease: ${{ contains(github.ref, '-') }}
@@ -0,0 +1,78 @@
1
+ name: Claude Code Review
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize]
6
+ # Optional: Only run on specific file changes
7
+ # paths:
8
+ # - "src/**/*.ts"
9
+ # - "src/**/*.tsx"
10
+ # - "src/**/*.js"
11
+ # - "src/**/*.jsx"
12
+
13
+ jobs:
14
+ claude-review:
15
+ # Optional: Filter by PR author
16
+ # if: |
17
+ # github.event.pull_request.user.login == 'external-contributor' ||
18
+ # github.event.pull_request.user.login == 'new-developer' ||
19
+ # github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20
+
21
+ runs-on: ubuntu-latest
22
+ permissions:
23
+ contents: read
24
+ pull-requests: read
25
+ issues: read
26
+ id-token: write
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@v4
31
+ with:
32
+ fetch-depth: 1
33
+
34
+ - name: Run Claude Code Review
35
+ id: claude-review
36
+ uses: anthropics/claude-code-action@beta
37
+ with:
38
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39
+
40
+ # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
41
+ # model: "claude-opus-4-20250514"
42
+
43
+ # Direct prompt for automated review (no @claude mention needed)
44
+ direct_prompt: |
45
+ Please review this pull request and provide feedback on:
46
+ - Code quality and best practices
47
+ - Potential bugs or issues
48
+ - Performance considerations
49
+ - Security concerns
50
+ - Test coverage
51
+
52
+ Be constructive and helpful in your feedback.
53
+
54
+ # Optional: Use sticky comments to make Claude reuse the same comment on subsequent pushes to the same PR
55
+ # use_sticky_comment: true
56
+
57
+ # Optional: Customize review based on file types
58
+ # direct_prompt: |
59
+ # Review this PR focusing on:
60
+ # - For TypeScript files: Type safety and proper interface usage
61
+ # - For API endpoints: Security, input validation, and error handling
62
+ # - For React components: Performance, accessibility, and best practices
63
+ # - For tests: Coverage, edge cases, and test quality
64
+
65
+ # Optional: Different prompts for different authors
66
+ # direct_prompt: |
67
+ # ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
68
+ # 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
69
+ # 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
70
+
71
+ # Optional: Add specific tools for running tests or linting
72
+ # allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
73
+
74
+ # Optional: Skip review for certain conditions
75
+ # if: |
76
+ # !contains(github.event.pull_request.title, '[skip-review]') &&
77
+ # !contains(github.event.pull_request.title, '[WIP]')
78
+
@@ -0,0 +1,64 @@
1
+ name: Claude Code
2
+
3
+ on:
4
+ issue_comment:
5
+ types: [created]
6
+ pull_request_review_comment:
7
+ types: [created]
8
+ issues:
9
+ types: [opened, assigned]
10
+ pull_request_review:
11
+ types: [submitted]
12
+
13
+ jobs:
14
+ claude:
15
+ if: |
16
+ (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17
+ (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18
+ (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19
+ (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ contents: read
23
+ pull-requests: read
24
+ issues: read
25
+ id-token: write
26
+ actions: read # Required for Claude to read CI results on PRs
27
+ steps:
28
+ - name: Checkout repository
29
+ uses: actions/checkout@v4
30
+ with:
31
+ fetch-depth: 1
32
+
33
+ - name: Run Claude Code
34
+ id: claude
35
+ uses: anthropics/claude-code-action@beta
36
+ with:
37
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
38
+
39
+ # This is an optional setting that allows Claude to read CI results on PRs
40
+ additional_permissions: |
41
+ actions: read
42
+
43
+ # Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4)
44
+ # model: "claude-opus-4-20250514"
45
+
46
+ # Optional: Customize the trigger phrase (default: @claude)
47
+ # trigger_phrase: "/claude"
48
+
49
+ # Optional: Trigger when specific user is assigned to an issue
50
+ # assignee_trigger: "claude-bot"
51
+
52
+ # Optional: Allow Claude to run specific commands
53
+ # allowed_tools: "Bash(npm install),Bash(npm run build),Bash(npm run test:*),Bash(npm run lint:*)"
54
+
55
+ # Optional: Add custom instructions for Claude to customize its behavior for your project
56
+ # custom_instructions: |
57
+ # Follow our coding standards
58
+ # Ensure all new code has tests
59
+ # Use TypeScript for new files
60
+
61
+ # Optional: Custom environment variables for Claude
62
+ # claude_env: |
63
+ # NODE_ENV: test
64
+
@@ -25,17 +25,21 @@ jobs:
25
25
  uses: actions/setup-python@v4
26
26
  with:
27
27
  python-version: "3.12"
28
-
28
+ - name: Install uv
29
+ uses: astral-sh/setup-uv@v5
30
+ with:
31
+ enable-cache: true
32
+ cache-dependency-glob: "uv.lock"
29
33
  - name: Install dependencies
30
34
  run: |
31
- pip install mkdocs-material
32
- pip install mkdocstrings[python]
33
- pip install .
35
+ uv sync --group dev --no-install-project
36
+ uv pip install -e .
34
37
 
35
38
  - name: Setup docs directory
36
39
  run: |
37
40
  cd docs
38
41
  ln -sf ../README.md .
42
+ ln -sf ../CHANGELOG.md .
39
43
 
40
44
  - name: Deploy documentation
41
- run: mkdocs gh-deploy --force
45
+ run: uv run mkdocs gh-deploy --force
@@ -0,0 +1,115 @@
1
+ name: Installation Test
2
+
3
+ on:
4
+ push:
5
+ branches: [main, master]
6
+ pull_request:
7
+ branches: [main, master]
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ install-cpu:
12
+ name: Install (CPU) - ${{ matrix.os }} / Python ${{ matrix.python-version }}
13
+ runs-on: ${{ matrix.os }}
14
+ timeout-minutes: 30
15
+ strategy:
16
+ fail-fast: false
17
+ matrix:
18
+ os: [ubuntu-latest, windows-latest, macos-latest]
19
+ python-version: ["3.10", "3.11", "3.12"]
20
+
21
+ steps:
22
+ - uses: actions/checkout@v4
23
+
24
+ - name: Install uv and set Python version
25
+ uses: astral-sh/setup-uv@v5
26
+ with:
27
+ enable-cache: true
28
+ cache-dependency-glob: "uv.lock"
29
+ python-version: ${{ matrix.python-version }}
30
+
31
+ - name: Install package (CPU mode - no CUDA extras)
32
+ run: uv sync --frozen
33
+ continue-on-error: false
34
+
35
+ - name: Verify CLI entrypoint
36
+ run: uv run mkv-match --help
37
+
38
+ - name: Verify PyTorch imports (CPU)
39
+ run: |
40
+ uv run python -c "
41
+ import torch
42
+ print(f'PyTorch version: {torch.__version__}')
43
+ print(f'CUDA available: {torch.cuda.is_available()}')
44
+
45
+ import torchaudio
46
+ print(f'Torchaudio version: {torchaudio.__version__}')
47
+
48
+ import torchvision
49
+ print(f'Torchvision version: {torchvision.__version__}')
50
+ "
51
+
52
+ - name: Verify NeMo ASR imports
53
+ run: |
54
+ uv run python -c "
55
+ import os
56
+ if os.name == 'nt':
57
+ import signal
58
+ if not hasattr(signal, 'SIGKILL'):
59
+ signal.SIGKILL = 9
60
+ if not hasattr(signal, 'SIGTERM'):
61
+ signal.SIGTERM = 15
62
+ from nemo.collections.asr.models import ASRModel
63
+ print('NeMo ASR module loaded successfully')
64
+ "
65
+
66
+ - name: Verify core application imports
67
+ run: |
68
+ uv run python -c "
69
+ from mkv_episode_matcher.core.models import Config
70
+ from mkv_episode_matcher.core.engine import MatchEngine
71
+ from mkv_episode_matcher.tmdb_client import fetch_show_id
72
+ print('Core application modules loaded successfully')
73
+ "
74
+
75
+ # Test pip install from wheel (simulates end-user experience)
76
+ pip-install-test:
77
+ name: Pip Install Test - ${{ matrix.os }} / Python ${{ matrix.python-version }}
78
+ runs-on: ${{ matrix.os }}
79
+ timeout-minutes: 30
80
+ strategy:
81
+ fail-fast: false
82
+ matrix:
83
+ os: [ubuntu-latest, windows-latest]
84
+ python-version: ["3.11", "3.12"]
85
+
86
+ steps:
87
+ - uses: actions/checkout@v4
88
+
89
+ - name: Set up Python
90
+ uses: actions/setup-python@v5
91
+ with:
92
+ python-version: ${{ matrix.python-version }}
93
+
94
+ - name: Install build tools
95
+ run: pip install build
96
+
97
+ - name: Build wheel
98
+ run: python -m build
99
+
100
+ - name: Install from wheel
101
+ shell: bash
102
+ run: |
103
+ pip install dist/*.whl
104
+
105
+ - name: Verify CLI works
106
+ run: mkv-match --help
107
+
108
+ - name: Verify imports work
109
+ run: |
110
+ python -c "
111
+ import torch
112
+ print(f'PyTorch: {torch.__version__}')
113
+ from mkv_episode_matcher.cli import app
114
+ print('CLI module loaded successfully')
115
+ "
@@ -22,7 +22,7 @@ jobs:
22
22
  - name: Build a binary wheel and a source tarball
23
23
  run: python3 -m build
24
24
  - name: Store the distribution packages
25
- uses: actions/upload-artifact@v3
25
+ uses: actions/upload-artifact@v4
26
26
  with:
27
27
  name: python-package-distributions
28
28
  path: dist/
@@ -42,7 +42,7 @@ jobs:
42
42
 
43
43
  steps:
44
44
  - name: Download all the dists
45
- uses: actions/download-artifact@v3
45
+ uses: actions/download-artifact@v4
46
46
  with:
47
47
  name: python-package-distributions
48
48
  path: dist/
@@ -1,40 +1,31 @@
1
1
  name: Tests
2
-
3
2
  on:
4
3
  push:
5
4
  branches: [main, master]
6
5
  pull_request:
7
6
  branches: [main, master]
8
-
9
7
  jobs:
10
8
  test:
11
- runs-on: ubuntu-latest
9
+ runs-on: ${{ matrix.os }}
12
10
  strategy:
13
11
  matrix:
14
- python-version:
15
- - "3.9"
16
- - "3.10"
17
- - "3.11"
18
- - "3.12"
19
-
12
+ os: [ubuntu-latest, windows-latest, macos-latest]
13
+ python-version: ["3.10", "3.11", "3.12"]
14
+ fail-fast: false
20
15
  steps:
21
16
  - uses: actions/checkout@v4
22
-
23
17
  - name: Install uv and set the python version
24
- uses: astral-sh/setup-uv@v4
18
+ uses: astral-sh/setup-uv@v5
25
19
  with:
20
+ enable-cache: true
21
+ cache-dependency-glob: "uv.lock"
26
22
  python-version: ${{ matrix.python-version }}
27
-
28
- - name: Install dependencies
29
- run: |
30
- uv venv
31
- uv pip install -e .
32
-
23
+ - name: Install the project
24
+ run: uv sync --all-extras --dev
33
25
  - name: Run tests with pytest and coverage
34
26
  run: |
35
27
  uv run --dev pytest --cov-branch --cov-report=xml
36
-
37
28
  - name: Upload coverage reports to Codecov
38
29
  uses: codecov/codecov-action@v5
39
30
  with:
40
- token: ${{ secrets.CODECOV_TOKEN }}
31
+ token: ${{ secrets.CODECOV_TOKEN }}
@@ -6,3 +6,5 @@
6
6
  build/
7
7
  dist/
8
8
  mkv_episode_matcher.egg-info
9
+ *.mkv
10
+ /perf-test/*
@@ -0,0 +1 @@
1
+ 3.11