luckiest-co 1.0.51 → 1.0.52
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/skills/video-watcher/CHANGELOG.md +8 -0
- package/skills/video-watcher/SKILL.md +3 -3
- package/skills/video-watcher/scripts/download.py +6 -1
- package/skills/video-watcher/scripts/test_download.py +30 -0
package/package.json
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog: luckiest-video-watcher
|
|
2
2
|
|
|
3
|
+
## 1.1.2 (2026-10-23)
|
|
4
|
+
|
|
5
|
+
- Auto caption mode picks English when YouTube lists several original
|
|
6
|
+
auto-caption tracks (for example bn-orig and en-orig), then the video's
|
|
7
|
+
declared language, then the first. It used to take the first alphabetically,
|
|
8
|
+
so an English talk came back with Bangla captions. New test:
|
|
9
|
+
`scripts/test_download.py`.
|
|
10
|
+
|
|
3
11
|
## 1.1.1 (2026-10-10)
|
|
4
12
|
|
|
5
13
|
- Security: the WhisperX setup's uv installer is pinned to 0.11.16 and saved to a
|
|
@@ -19,7 +19,7 @@ argument-hint: "<video-url | path/to/video.mp4> [question] [--study]"
|
|
|
19
19
|
license: MIT. See ATTRIBUTION.md
|
|
20
20
|
allowed-tools: Bash, Read, Write, AskUserQuestion
|
|
21
21
|
metadata:
|
|
22
|
-
version: "1.1.
|
|
22
|
+
version: "1.1.2"
|
|
23
23
|
listing_id: luckiest-video-watcher
|
|
24
24
|
author: luckiest
|
|
25
25
|
---
|
|
@@ -39,11 +39,11 @@ run of a session, when setup fails, or when a run needs a detail not covered her
|
|
|
39
39
|
## Staying current
|
|
40
40
|
|
|
41
41
|
On activation, call the Luckiest MCP `check_updates` tool with
|
|
42
|
-
`{ listingId: "luckiest-video-watcher", installedSemver: "1.1.
|
|
42
|
+
`{ listingId: "luckiest-video-watcher", installedSemver: "1.1.2" }`. If
|
|
43
43
|
`upToDate: false`, surface the `notice` once and continue. Never block on it.
|
|
44
44
|
|
|
45
45
|
When done, call `report_usage` once with
|
|
46
|
-
`{ listing_id: "luckiest-video-watcher", skill_version: "1.1.
|
|
46
|
+
`{ listing_id: "luckiest-video-watcher", skill_version: "1.1.2", matched: true, success: <true|false> }`.
|
|
47
47
|
Metadata only. Skip silently if unavailable.
|
|
48
48
|
|
|
49
49
|
## Standing rules
|
|
@@ -98,7 +98,12 @@ def select_caption(info: dict, language: str = 'auto') -> dict | None:
|
|
|
98
98
|
manual = {k: v for k, v in (info.get('subtitles') or {}).items() if v and k != 'live_chat'}
|
|
99
99
|
automatic = {k: v for k, v in (info.get('automatic_captions') or {}).items() if v and k != 'live_chat'}
|
|
100
100
|
youtube = str(info.get('extractor_key') or info.get('extractor') or '').lower().startswith('youtube')
|
|
101
|
-
originals
|
|
101
|
+
# Several originals (e.g. bn-orig and en-orig): English first, then the declared language, then alphabetical.
|
|
102
|
+
declared = str(info.get('language') or '').split('-')[0]
|
|
103
|
+
def original_rank(key):
|
|
104
|
+
base = key.removesuffix('-orig').split('-')[0]
|
|
105
|
+
return base != 'en', base != declared, key
|
|
106
|
+
originals = sorted((k for k in automatic if youtube and k.endswith('-orig')), key=original_rank)
|
|
102
107
|
original = originals[0][:-5] if len(originals) == 1 else None
|
|
103
108
|
target = language if language != 'auto' else original or info.get('language')
|
|
104
109
|
def matches(key):
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Run: python3 -m unittest scripts/test_download.py (from the skill directory)."""
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import unittest
|
|
5
|
+
|
|
6
|
+
sys.path.insert(0, os.path.dirname(__file__))
|
|
7
|
+
import download # noqa: E402
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def info(language, *keys):
|
|
11
|
+
return {'extractor_key': 'Youtube', 'language': language,
|
|
12
|
+
'automatic_captions': {k: [{'ext': 'vtt'}] for k in keys}}
|
|
13
|
+
|
|
14
|
+
class SelectCaption(unittest.TestCase):
|
|
15
|
+
def test_several_originals_prefer_english(self):
|
|
16
|
+
for language in ('en', 'bn', None):
|
|
17
|
+
track = download.select_caption(info(language, 'bn-orig', 'en-orig', 'bn', 'en'))
|
|
18
|
+
self.assertEqual(track['key'], 'en-orig', language)
|
|
19
|
+
|
|
20
|
+
def test_several_originals_without_english_use_declared_language(self):
|
|
21
|
+
track = download.select_caption(info('hi', 'bn-orig', 'hi-orig', 'bn', 'hi'))
|
|
22
|
+
self.assertEqual(track['key'], 'hi-orig')
|
|
23
|
+
|
|
24
|
+
def test_single_original_unchanged(self):
|
|
25
|
+
track = download.select_caption(info(None, 'bn-orig', 'bn', 'en'))
|
|
26
|
+
self.assertEqual((track['key'], track['provenance']), ('bn-orig', 'original'))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == '__main__':
|
|
30
|
+
unittest.main()
|