karaoke-gen 0.75.53__py3-none-any.whl → 0.81.1__py3-none-any.whl

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 (50) hide show
  1. karaoke_gen/audio_fetcher.py +218 -0
  2. karaoke_gen/instrumental_review/static/index.html +179 -16
  3. karaoke_gen/karaoke_gen.py +191 -25
  4. karaoke_gen/lyrics_processor.py +39 -31
  5. karaoke_gen/utils/__init__.py +26 -0
  6. karaoke_gen/utils/cli_args.py +9 -1
  7. karaoke_gen/utils/gen_cli.py +1 -1
  8. karaoke_gen/utils/remote_cli.py +33 -6
  9. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/METADATA +80 -4
  10. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/RECORD +50 -43
  11. lyrics_transcriber/core/config.py +8 -0
  12. lyrics_transcriber/core/controller.py +43 -1
  13. lyrics_transcriber/correction/agentic/providers/config.py +6 -0
  14. lyrics_transcriber/correction/agentic/providers/model_factory.py +24 -1
  15. lyrics_transcriber/correction/agentic/router.py +17 -13
  16. lyrics_transcriber/frontend/.gitignore +1 -0
  17. lyrics_transcriber/frontend/e2e/agentic-corrections.spec.ts +207 -0
  18. lyrics_transcriber/frontend/e2e/fixtures/agentic-correction-data.json +226 -0
  19. lyrics_transcriber/frontend/index.html +5 -1
  20. lyrics_transcriber/frontend/package-lock.json +4553 -0
  21. lyrics_transcriber/frontend/package.json +7 -1
  22. lyrics_transcriber/frontend/playwright.config.ts +69 -0
  23. lyrics_transcriber/frontend/public/nomad-karaoke-logo.svg +5 -0
  24. lyrics_transcriber/frontend/src/App.tsx +88 -59
  25. lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +55 -21
  26. lyrics_transcriber/frontend/src/components/AppHeader.tsx +65 -0
  27. lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +39 -35
  28. lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx +9 -9
  29. lyrics_transcriber/frontend/src/components/EditModal.tsx +1 -1
  30. lyrics_transcriber/frontend/src/components/EditWordList.tsx +1 -1
  31. lyrics_transcriber/frontend/src/components/Header.tsx +96 -3
  32. lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +120 -3
  33. lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +22 -21
  34. lyrics_transcriber/frontend/src/components/ReferenceView.tsx +1 -1
  35. lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +12 -2
  36. lyrics_transcriber/frontend/src/components/WordDivider.tsx +3 -3
  37. lyrics_transcriber/frontend/src/components/shared/components/HighlightedText.tsx +122 -35
  38. lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +2 -2
  39. lyrics_transcriber/frontend/src/components/shared/constants.ts +15 -5
  40. lyrics_transcriber/frontend/src/components/shared/types.ts +6 -0
  41. lyrics_transcriber/frontend/src/main.tsx +1 -7
  42. lyrics_transcriber/frontend/src/theme.ts +337 -135
  43. lyrics_transcriber/frontend/vite.config.ts +5 -0
  44. lyrics_transcriber/frontend/yarn.lock +1005 -1046
  45. lyrics_transcriber/output/generator.py +50 -3
  46. lyrics_transcriber/review/server.py +1 -1
  47. lyrics_transcriber/transcribers/local_whisper.py +260 -0
  48. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/WHEEL +0 -0
  49. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/entry_points.txt +0 -0
  50. {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.81.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,177 +1,379 @@
1
- import { createTheme } from '@mui/material/styles';
1
+ import { createTheme, Theme } from '@mui/material/styles';
2
2
 
3
- // Create a theme with smaller typography and spacing
4
- const theme = createTheme({
5
- typography: {
6
- // Scale down all typography by about 20%
7
- fontSize: 14, // Default is 16
8
- h1: {
9
- fontSize: '2.5rem', // Default is ~3rem
10
- },
11
- h2: {
12
- fontSize: '2rem', // Default is ~2.5rem
13
- },
14
- h3: {
15
- fontSize: '1.5rem', // Default is ~1.75rem
16
- },
17
- h4: {
18
- fontSize: '1.2rem', // Default is ~1.5rem
19
- marginBottom: '0.5rem',
20
- },
21
- h5: {
22
- fontSize: '1rem', // Default is ~1.25rem
23
- },
24
- h6: {
25
- fontSize: '0.9rem', // Default is ~1.1rem
26
- marginBottom: '0.5rem',
27
- },
28
- body1: {
29
- fontSize: '0.85rem', // Default is ~1rem
30
- },
31
- body2: {
32
- fontSize: '0.75rem', // Default is ~0.875rem
33
- },
34
- button: {
35
- fontSize: '0.8rem', // Default is ~0.875rem
3
+ // Dark theme colors (matching karaoke-gen's globals.css)
4
+ const darkColors = {
5
+ background: {
6
+ default: '#0f0f0f',
7
+ paper: '#1a1a1a',
8
+ elevated: '#252525',
9
+ },
10
+ text: {
11
+ primary: '#f8fafc',
12
+ secondary: '#94a3b8',
13
+ disabled: '#64748b',
14
+ },
15
+ divider: '#2a2a2a',
16
+ action: {
17
+ active: '#f8fafc',
18
+ hover: 'rgba(248, 250, 252, 0.08)',
19
+ selected: 'rgba(249, 115, 22, 0.16)',
20
+ disabled: '#64748b',
21
+ disabledBackground: 'rgba(100, 116, 139, 0.12)',
22
+ },
23
+ };
24
+
25
+ // Light theme colors
26
+ const lightColors = {
27
+ background: {
28
+ default: '#f8fafc',
29
+ paper: '#ffffff',
30
+ elevated: '#f1f5f9',
31
+ },
32
+ text: {
33
+ primary: '#1e293b',
34
+ secondary: '#64748b',
35
+ disabled: '#94a3b8',
36
+ },
37
+ divider: '#e2e8f0',
38
+ action: {
39
+ active: '#1e293b',
40
+ hover: 'rgba(30, 41, 59, 0.08)',
41
+ selected: 'rgba(249, 115, 22, 0.16)',
42
+ disabled: '#94a3b8',
43
+ disabledBackground: 'rgba(148, 163, 184, 0.12)',
44
+ },
45
+ };
46
+
47
+ // Shared colors
48
+ const sharedColors = {
49
+ primary: {
50
+ main: '#f97316',
51
+ light: '#fb923c',
52
+ dark: '#ea580c',
53
+ contrastText: '#ffffff',
54
+ },
55
+ secondary: {
56
+ main: '#6366f1',
57
+ light: '#818cf8',
58
+ dark: '#4f46e5',
59
+ contrastText: '#ffffff',
60
+ },
61
+ error: {
62
+ main: '#ef4444',
63
+ light: '#f87171',
64
+ dark: '#dc2626',
65
+ },
66
+ warning: {
67
+ main: '#f59e0b',
68
+ light: '#fbbf24',
69
+ dark: '#d97706',
70
+ },
71
+ success: {
72
+ main: '#22c55e',
73
+ light: '#4ade80',
74
+ dark: '#16a34a',
75
+ },
76
+ info: {
77
+ main: '#3b82f6',
78
+ light: '#60a5fa',
79
+ dark: '#2563eb',
80
+ },
81
+ };
82
+
83
+ // Create theme based on mode
84
+ export function createAppTheme(mode: 'dark' | 'light'): Theme {
85
+ const colors = mode === 'dark' ? darkColors : lightColors;
86
+
87
+ return createTheme({
88
+ palette: {
89
+ mode,
90
+ background: colors.background,
91
+ text: colors.text,
92
+ primary: sharedColors.primary,
93
+ secondary: sharedColors.secondary,
94
+ error: sharedColors.error,
95
+ warning: sharedColors.warning,
96
+ success: sharedColors.success,
97
+ info: sharedColors.info,
98
+ divider: colors.divider,
99
+ action: colors.action,
36
100
  },
37
- caption: {
38
- fontSize: '0.7rem', // Default is ~0.75rem
101
+ typography: {
102
+ fontFamily: '"Inter", "system-ui", "sans-serif"',
103
+ fontSize: 14,
104
+ h1: { fontSize: '2.5rem', fontWeight: 600, color: colors.text.primary },
105
+ h2: { fontSize: '2rem', fontWeight: 600, color: colors.text.primary },
106
+ h3: { fontSize: '1.5rem', fontWeight: 600, color: colors.text.primary },
107
+ h4: { fontSize: '1.2rem', fontWeight: 600, marginBottom: '0.5rem', color: colors.text.primary },
108
+ h5: { fontSize: '1rem', fontWeight: 600, color: colors.text.primary },
109
+ h6: { fontSize: '0.9rem', fontWeight: 600, marginBottom: '0.5rem', color: colors.text.primary },
110
+ body1: { fontSize: '0.85rem', color: colors.text.primary },
111
+ body2: { fontSize: '0.75rem', color: colors.text.secondary },
112
+ button: { fontSize: '0.8rem', fontWeight: 500, textTransform: 'none' },
113
+ caption: { fontSize: '0.7rem', color: colors.text.secondary },
39
114
  },
40
- },
41
- components: {
42
- MuiButton: {
43
- styleOverrides: {
44
- root: {
45
- padding: '3px 10px', // Further reduced from 4px 12px
46
- minHeight: '30px', // Further reduced from 32px
115
+ shape: { borderRadius: 8 },
116
+ components: {
117
+ MuiCssBaseline: {
118
+ styleOverrides: {
119
+ body: {
120
+ backgroundColor: colors.background.default,
121
+ color: colors.text.primary,
122
+ scrollbarColor: `${colors.background.elevated} ${colors.background.default}`,
123
+ '&::-webkit-scrollbar': { width: '8px', height: '8px' },
124
+ '&::-webkit-scrollbar-track': { background: colors.background.default },
125
+ '&::-webkit-scrollbar-thumb': { background: colors.background.elevated, borderRadius: '4px' },
126
+ '&::-webkit-scrollbar-thumb:hover': { background: mode === 'dark' ? '#475569' : '#94a3b8' },
127
+ },
47
128
  },
48
- sizeSmall: {
49
- padding: '1px 6px', // Further reduced from 2px 8px
50
- minHeight: '24px', // Further reduced from 28px
129
+ },
130
+ MuiButton: {
131
+ styleOverrides: {
132
+ root: { padding: '3px 10px', minHeight: '30px', borderRadius: '6px' },
133
+ sizeSmall: { padding: '1px 6px', minHeight: '24px' },
134
+ contained: { boxShadow: 'none', '&:hover': { boxShadow: 'none' } },
135
+ containedPrimary: {
136
+ backgroundColor: sharedColors.primary.main,
137
+ '&:hover': { backgroundColor: sharedColors.primary.dark },
138
+ },
139
+ outlined: {
140
+ borderColor: colors.divider,
141
+ '&:hover': {
142
+ borderColor: sharedColors.primary.main,
143
+ backgroundColor: 'rgba(249, 115, 22, 0.08)',
144
+ },
145
+ },
51
146
  },
52
147
  },
53
- },
54
- MuiIconButton: {
55
- styleOverrides: {
56
- root: {
57
- padding: '4px', // Further reduced from 6px
148
+ MuiIconButton: {
149
+ styleOverrides: {
150
+ root: {
151
+ padding: '4px',
152
+ color: colors.text.secondary,
153
+ '&:hover': { backgroundColor: colors.action.hover, color: colors.text.primary },
154
+ },
155
+ sizeSmall: { padding: '2px' },
58
156
  },
59
- sizeSmall: {
60
- padding: '2px', // Further reduced from 4px
157
+ },
158
+ MuiTextField: {
159
+ styleOverrides: {
160
+ root: {
161
+ '& .MuiInputBase-root': { minHeight: '32px', backgroundColor: colors.background.default },
162
+ '& .MuiOutlinedInput-root': {
163
+ '& fieldset': { borderColor: colors.divider },
164
+ '&:hover fieldset': { borderColor: colors.text.secondary },
165
+ '&.Mui-focused fieldset': { borderColor: sharedColors.primary.main },
166
+ },
167
+ },
61
168
  },
62
169
  },
63
- },
64
- MuiTextField: {
65
- styleOverrides: {
66
- root: {
67
- '& .MuiInputBase-root': {
68
- minHeight: '32px', // Further reduced from 36px
170
+ MuiInputBase: {
171
+ styleOverrides: {
172
+ root: { color: colors.text.primary },
173
+ input: { '&::placeholder': { color: colors.text.disabled, opacity: 1 } },
174
+ },
175
+ },
176
+ MuiDialog: {
177
+ styleOverrides: {
178
+ paper: {
179
+ padding: '8px',
180
+ backgroundColor: colors.background.paper,
181
+ backgroundImage: 'none',
182
+ border: `1px solid ${colors.divider}`,
69
183
  },
70
184
  },
71
185
  },
72
- },
73
- MuiDialog: {
74
- styleOverrides: {
75
- paper: {
76
- padding: '8px', // Further reduced from 12px
186
+ MuiDialogTitle: {
187
+ styleOverrides: { root: { padding: '8px 12px', color: colors.text.primary } },
188
+ },
189
+ MuiDialogContent: {
190
+ styleOverrides: { root: { padding: '6px 12px' } },
191
+ },
192
+ MuiDialogActions: {
193
+ styleOverrides: { root: { padding: '6px 12px' } },
194
+ },
195
+ MuiPaper: {
196
+ styleOverrides: {
197
+ root: { padding: '8px', backgroundColor: colors.background.paper, backgroundImage: 'none' },
198
+ outlined: { borderColor: colors.divider },
77
199
  },
78
200
  },
79
- },
80
- MuiDialogTitle: {
81
- styleOverrides: {
82
- root: {
83
- padding: '8px 12px', // Further reduced from 12px 16px
201
+ MuiList: {
202
+ styleOverrides: { root: { padding: '2px 0' } },
203
+ },
204
+ MuiListItem: {
205
+ styleOverrides: { root: { padding: '2px 8px' } },
206
+ },
207
+ MuiListItemButton: {
208
+ styleOverrides: {
209
+ root: {
210
+ '&:hover': { backgroundColor: colors.action.hover },
211
+ '&.Mui-selected': {
212
+ backgroundColor: colors.action.selected,
213
+ '&:hover': { backgroundColor: 'rgba(249, 115, 22, 0.24)' },
214
+ },
215
+ },
84
216
  },
85
217
  },
86
- },
87
- MuiDialogContent: {
88
- styleOverrides: {
89
- root: {
90
- padding: '6px 12px', // Further reduced from 8px 16px
218
+ MuiTableCell: {
219
+ styleOverrides: {
220
+ root: { padding: '4px 8px', borderBottomColor: colors.divider },
221
+ head: { backgroundColor: colors.background.elevated, color: colors.text.primary, fontWeight: 600 },
91
222
  },
92
223
  },
93
- },
94
- MuiDialogActions: {
95
- styleOverrides: {
96
- root: {
97
- padding: '6px 12px', // Further reduced from 8px 16px
224
+ MuiTableRow: {
225
+ styleOverrides: {
226
+ root: { '&:hover': { backgroundColor: mode === 'dark' ? 'rgba(248, 250, 252, 0.04)' : 'rgba(30, 41, 59, 0.04)' } },
98
227
  },
99
228
  },
100
- },
101
- MuiPaper: {
102
- styleOverrides: {
103
- root: {
104
- padding: '8px', // Further reduced from 12px
229
+ MuiCard: {
230
+ styleOverrides: {
231
+ root: {
232
+ padding: '8px',
233
+ backgroundColor: colors.background.paper,
234
+ backgroundImage: 'none',
235
+ border: `1px solid ${colors.divider}`,
236
+ },
105
237
  },
106
238
  },
107
- },
108
- MuiList: {
109
- styleOverrides: {
110
- root: {
111
- padding: '2px 0', // Further reduced from 4px 0
239
+ MuiCardContent: {
240
+ styleOverrides: { root: { padding: '8px', '&:last-child': { paddingBottom: '8px' } } },
241
+ },
242
+ MuiCardHeader: {
243
+ styleOverrides: {
244
+ root: { padding: '8px' },
245
+ title: { color: colors.text.primary },
246
+ subheader: { color: colors.text.secondary },
112
247
  },
113
248
  },
114
- },
115
- MuiListItem: {
116
- styleOverrides: {
117
- root: {
118
- padding: '2px 8px', // Further reduced from 4px 12px
249
+ MuiCardActions: {
250
+ styleOverrides: { root: { padding: '4px 8px' } },
251
+ },
252
+ MuiChip: {
253
+ styleOverrides: {
254
+ root: { backgroundColor: colors.background.elevated, color: colors.text.primary, borderColor: colors.divider },
255
+ filled: {
256
+ '&.MuiChip-colorPrimary': { backgroundColor: sharedColors.primary.main, color: sharedColors.primary.contrastText },
257
+ },
119
258
  },
120
259
  },
121
- },
122
- MuiTableCell: {
123
- styleOverrides: {
124
- root: {
125
- padding: '4px 8px', // Further reduced from 8px 12px
260
+ MuiAlert: {
261
+ styleOverrides: {
262
+ root: { borderRadius: '8px' },
263
+ standardError: { backgroundColor: 'rgba(239, 68, 68, 0.15)', color: sharedColors.error.light },
264
+ standardWarning: { backgroundColor: 'rgba(245, 158, 11, 0.15)', color: sharedColors.warning.light },
265
+ standardSuccess: { backgroundColor: 'rgba(34, 197, 94, 0.15)', color: sharedColors.success.light },
266
+ standardInfo: { backgroundColor: 'rgba(59, 130, 246, 0.15)', color: sharedColors.info.light },
126
267
  },
127
268
  },
128
- },
129
- MuiCard: {
130
- styleOverrides: {
131
- root: {
132
- padding: '8px',
269
+ MuiTooltip: {
270
+ styleOverrides: {
271
+ tooltip: {
272
+ backgroundColor: colors.background.elevated,
273
+ color: colors.text.primary,
274
+ border: `1px solid ${colors.divider}`,
275
+ fontSize: '0.75rem',
276
+ },
277
+ arrow: { color: colors.background.elevated },
133
278
  },
134
279
  },
135
- },
136
- MuiCardContent: {
137
- styleOverrides: {
138
- root: {
139
- padding: '8px',
140
- '&:last-child': {
141
- paddingBottom: '8px',
280
+ MuiMenu: {
281
+ styleOverrides: {
282
+ paper: { backgroundColor: colors.background.paper, border: `1px solid ${colors.divider}` },
283
+ },
284
+ },
285
+ MuiMenuItem: {
286
+ styleOverrides: {
287
+ root: {
288
+ '&:hover': { backgroundColor: colors.action.hover },
289
+ '&.Mui-selected': {
290
+ backgroundColor: colors.action.selected,
291
+ '&:hover': { backgroundColor: 'rgba(249, 115, 22, 0.24)' },
292
+ },
142
293
  },
143
294
  },
144
295
  },
145
- },
146
- MuiCardHeader: {
147
- styleOverrides: {
148
- root: {
149
- padding: '8px',
296
+ MuiDivider: {
297
+ styleOverrides: { root: { borderColor: colors.divider } },
298
+ },
299
+ MuiTabs: {
300
+ styleOverrides: { indicator: { backgroundColor: sharedColors.primary.main } },
301
+ },
302
+ MuiTab: {
303
+ styleOverrides: {
304
+ root: { color: colors.text.secondary, '&.Mui-selected': { color: sharedColors.primary.main } },
150
305
  },
151
306
  },
152
- },
153
- MuiCardActions: {
154
- styleOverrides: {
155
- root: {
156
- padding: '4px 8px',
307
+ MuiSlider: {
308
+ styleOverrides: {
309
+ root: { color: sharedColors.primary.main },
310
+ track: { backgroundColor: sharedColors.primary.main },
311
+ rail: { backgroundColor: colors.background.elevated },
312
+ thumb: { backgroundColor: sharedColors.primary.main },
157
313
  },
158
314
  },
159
- },
160
- MuiGrid: {
161
- styleOverrides: {
162
- container: {
163
- marginTop: '-4px',
164
- marginLeft: '-4px',
165
- width: 'calc(100% + 8px)',
315
+ MuiSwitch: {
316
+ styleOverrides: {
317
+ root: {
318
+ '& .MuiSwitch-switchBase.Mui-checked': {
319
+ color: sharedColors.primary.main,
320
+ '& + .MuiSwitch-track': { backgroundColor: sharedColors.primary.main },
321
+ },
322
+ },
323
+ track: { backgroundColor: colors.background.elevated },
324
+ },
325
+ },
326
+ MuiCheckbox: {
327
+ styleOverrides: {
328
+ root: { color: colors.text.secondary, '&.Mui-checked': { color: sharedColors.primary.main } },
329
+ },
330
+ },
331
+ MuiRadio: {
332
+ styleOverrides: {
333
+ root: { color: colors.text.secondary, '&.Mui-checked': { color: sharedColors.primary.main } },
334
+ },
335
+ },
336
+ MuiLinearProgress: {
337
+ styleOverrides: {
338
+ root: { backgroundColor: colors.background.elevated, borderRadius: '4px' },
339
+ bar: { backgroundColor: sharedColors.primary.main, borderRadius: '4px' },
340
+ },
341
+ },
342
+ MuiCircularProgress: {
343
+ styleOverrides: { root: { color: sharedColors.primary.main } },
344
+ },
345
+ MuiSelect: {
346
+ styleOverrides: {
347
+ select: { backgroundColor: colors.background.default },
348
+ icon: { color: colors.text.secondary },
349
+ },
350
+ },
351
+ MuiAccordion: {
352
+ styleOverrides: {
353
+ root: { backgroundColor: colors.background.paper, '&:before': { backgroundColor: colors.divider } },
354
+ },
355
+ },
356
+ MuiAccordionSummary: {
357
+ styleOverrides: { root: { '&:hover': { backgroundColor: colors.action.hover } } },
358
+ },
359
+ MuiBadge: {
360
+ styleOverrides: { colorPrimary: { backgroundColor: sharedColors.primary.main } },
361
+ },
362
+ MuiAppBar: {
363
+ styleOverrides: {
364
+ root: { backgroundColor: colors.background.paper, backgroundImage: 'none', borderBottom: `1px solid ${colors.divider}` },
166
365
  },
167
- item: {
168
- paddingTop: '4px',
169
- paddingLeft: '4px',
366
+ },
367
+ MuiDrawer: {
368
+ styleOverrides: {
369
+ paper: { backgroundColor: colors.background.paper, backgroundImage: 'none', borderColor: colors.divider },
170
370
  },
171
371
  },
172
372
  },
173
- },
174
- spacing: (factor: number) => `${0.6 * factor}rem`, // Further reduced from 0.8 * factor
175
- });
373
+ spacing: (factor: number) => `${0.6 * factor}rem`,
374
+ });
375
+ }
176
376
 
177
- export default theme;
377
+ // Default dark theme for backwards compatibility
378
+ const theme = createAppTheme('dark');
379
+ export default theme;
@@ -4,6 +4,11 @@ import react from '@vitejs/plugin-react'
4
4
  // https://vite.dev/config/
5
5
  export default defineConfig({
6
6
  plugins: [react()],
7
+ server: {
8
+ port: 5173,
9
+ // Enable CORS for local development
10
+ cors: true,
11
+ },
7
12
  build: {
8
13
  minify: false,
9
14
  sourcemap: true,