11 Commits

Author SHA1 Message Date
bradautomates 83da59fa78 Fix WATCH_DETAIL silently falling back to default
An inline comment on the WATCH_DETAIL value line (e.g.
`WATCH_DETAIL=balanced  # ...`) parsed as the literal "balanced  # ..."
value, failed validation, and silently reverted to the default mode.

- setup.py: move the allowed-values list off the value line in the env
  template so the wizard no longer models a trailing inline comment.
- config.py: strip a whitespace-preceded inline comment from unquoted
  values so a stray comment can't silently break selection again
  (preserves '#' inside quotes / API keys).
- SKILL.md: note to write the bare key with no trailing comment.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
v0.2.0
2026-06-30 17:20:07 +10:00
bradautomates a1e7c4128b Document 0.2.0 and tighten README
Add the 0.2.0 changelog entry (--detail dial, frame dedup, Whisper
auto-chunking, --timestamps/--no-whisper, self-contained skill restructure).

README: drop the "Why this exists" section, trim two speculative use cases,
and condense the frame-dedup and detail-modes sections to state the facts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 23:43:11 +10:00
bradautomates 242ba568ed Bump version to 0.2.0
Frame dedup and Whisper auto-chunking are user-facing feature additions, so
bump the minor version across the three in-sync version files (SKILL.md
frontmatter, .claude-plugin/plugin.json, .codex-plugin/plugin.json).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 23:19:16 +10:00
bradautomates 304b639b4d Add frame dedup and Whisper auto-chunking
Frame extraction now runs a perceptual dedup pass (default on, --no-dedup
to disable) that drops near-identical frames before the budget cap, so the
budget goes to distinct content instead of held slides/static recordings.
The Frames report line notes how many near-duplicates were dropped.

Whisper transcription splits audio over the 25 MB upload cap into evenly
sized chunks, transcribes each, shifts segment timestamps back into source
time, and tolerates partial failures (only fails if every chunk fails) —
length alone no longer fails transcription.

token-burner is exempt from the long-video sparse-scan warning since it
keeps every scene-change frame. README/SKILL.md updated. Adds test_dedup.py and test_whisper.py.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 23:16:17 +10:00
bradautomates 429f3143e5 Restructure as a self-contained Agent Skills package (fix Codex install)
Move the skill into skills/watch/ so SKILL.md and its scripts/ runtime are
siblings inside one folder. `npx skills add` (Codex/Cursor/Copilot/agents) now
copies a working skill as a unit; previously it grabbed the root SKILL.md alone
and left scripts/ behind, so the skill was dead on arrival on every non-Claude
host. Mirrors the layout last30days-skill adopted for the same reason.

- skills/watch/{SKILL.md,scripts/}: self-contained skill folder
- SKILL.md: resolve a harness-agnostic $SKILL_DIR (the dir it was Read from)
  instead of the Claude-Code-only ${CLAUDE_SKILL_DIR}; guard + 19 call sites
- drop commands/watch.md: /watch derives from frontmatter (name + user-invocable)
- .codex-plugin/plugin.json: full manifest with "skills": "./skills/" + interface
- add .agents/plugins/marketplace.json, AGENTS.md, CLAUDE.md, .skillignore
- build-skill.sh: archive the skills/watch subtree (one SKILL.md, no zip -d)
- fix paths in tests, hooks hint, .gitattributes, release.yml
- relocate dev-sync.sh to repo root and fix REPO_ROOT
- README: content-ideas structure, npx skills install, star history

Verified: 37/37 tests pass; npx skills add bundles the full scripts/ runtime;
manifests valid; versions synced at 0.1.3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-29 22:12:54 +10:00
bradautomates c333c2289e Release v0.1.3
- #2: harden subprocess argv against option injection
- #4: read/write config files as UTF-8 on Windows

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.1.3
2026-05-09 08:41:59 +10:00
bradautomates 205af96c19 Read/write config files as UTF-8 on Windows (#4)
Path.read_text()/write_text() default to the platform encoding (cp1252
on Windows), which mangles or crashes on UTF-8 files. yt-dlp's
video.info.json is UTF-8 and routinely contains non-ASCII bytes, so on
Windows the parse raised UnicodeDecodeError, was swallowed by a bare
except, and the /watch report came back missing Title/Uploader.

- download.py: read video.info.json as UTF-8; log parse failures to
  stderr instead of swallowing them silently.
- whisper.py, setup.py: same UTF-8 fix on .env reads and writes for
  symmetry across platforms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 08:21:39 +10:00
bradautomates 3c488688d1 Harden subprocess argv against option injection (#2)
- download.py: insert `--` before URL in yt-dlp argv so a `-`-prefixed
  string can never be parsed as a flag (e.g. --exec, --config-location).
  Tighten is_url to reject `-`-prefixed sources and require non-empty
  netloc.
- frames.py, whisper.py: resolve video/audio paths to absolute via
  Path.resolve() before passing to ffmpeg/ffprobe (which don't honor
  `--` as end-of-options), so a relative path starting with `-` can
  never be misinterpreted as a flag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 08:13:32 +10:00
bradautomates 755c157466 Fix Windows compatibility: encoding, installer hints, interpreter name
- watch.py: drop the ⚠️ emoji from the long-video warning; cp1252
  consoles on Windows couldn't encode it and the script crashed.
- setup.py: add a Windows branch that prints winget / pip install
  commands, matching what the README already promised.
- SKILL.md: note that Windows users must invoke the scripts with
  `python`, not `python3` (which is the Microsoft Store stub).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.1.2
2026-04-24 17:22:51 +10:00
bradautomates 26cfa5ca34 Add commands/watch.md so /watch is callable via Claude Code plugin
Claude Code plugins expose slash commands from commands/*.md; the root
SKILL.md alone isn't discovered. Thin shim delegates to the existing
skill contract. Strip commands/ from the claude.ai .skill bundle since
that surface uses SKILL.md directly. Bumped to 0.1.1.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
v0.1.1
2026-04-24 14:54:54 +10:00
bradautomates 29b8a2988a Initial commit: /watch skill v0.1.0
Give Claude the ability to watch any video — yt-dlp download, ffmpeg
frame extraction with auto-scaled fps, native-caption transcript with
Whisper (Groq/OpenAI) fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0.1.0
2026-04-24 14:40:34 +10:00