Commit Graph

32 Commits

Author SHA1 Message Date
bradautomates
7948897be8 docs: point Claude users to Claude Code and offer to open the config for keys
The README now says Watch runs in Claude Code (Desktop's Code tab, VS
Code, or a terminal) and does not work in Claude Chat or Cowork. Cowork's
cloud environment drops the Gemini key between tasks and most sites block
yt-dlp from it. The standalone Chat upload instructions are removed.

Setup lets the user choose how to add an API key: paste it in chat, or
have the agent open ~/.config/watch/.env in their editor.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:25:31 +10:00
bradautomates
7f288b4400 docs: date the 0.3.1 changelog
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 11:00:29 +10:00
bradautomates
457627318c fix: keep SKILL.md frontmatter within the Agent Skills spec
Claude's skill upload rejects frontmatter keys outside the spec. SKILL.md now
uses only spec keys, with the version under metadata.version.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 10:59:01 +10:00
bradautomates
de8b5b5dc0 test: read SKILL.md as UTF-8 and write VTT fixtures as bytes on Windows
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 09:46:09 +10:00
bradautomates
c05d3c6792 docs: date the 0.3.0 changelog
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 09:42:42 +10:00
bradautomates
285d7f46eb fix: prefer English captions when the source language is unknown
Without a reported language, selection fell back to alphabetical order,
so an English video with de + en manual tracks got a German transcript.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 09:37:07 +10:00
bradautomates
fdbffd1c2e feat: support only the latest yt-dlp and update it on HTTP 403
A 403 now carries an update-and-retry-once hint, the skill contract tells
the agent how to update yt-dlp through its owning package manager, and CI
installs the latest yt-dlp instead of a pinned baseline.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 09:34:38 +10:00
bradautomates
3216a9c307 chore: keep versioned planning docs out of the repo
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 09:30:42 +10:00
bradautomates
19b517fd49 test: tolerate FFmpeg 7.1 muxing the shifted-PTS fixture one frame short
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 09:26:23 +10:00
bradautomates
c1975ef3b1 fix: detect -fps_mode in FFmpeg 9 help output
FFmpeg 9 lists the option as "-fps_mode[:<stream_spec>]", so the
whitespace-anchored probe missed it and every local run lost its frames.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 09:14:15 +10:00
bradautomates
a9e2c460d0 chore: keep superpowers planning docs out of the repo
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-25 09:05:48 +10:00
bradautomates
07a1560b6e fix: Gemini acceptance findings — auth on HTTP 400, honest source line, work-dir cleanup
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:54:10 +10:00
bradautomates
bb1738b7bd docs: Gemini engine in the skill contract, README, and changelog
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:48:42 +10:00
bradautomates
afbc483356 feat: setup wizard engine choice and Gemini-aware readiness
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:47:35 +10:00
bradautomates
6dcc18a859 feat: route watch through the Gemini engine when a key is present
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:47:04 +10:00
bradautomates
2bbb265d5b feat: stream uploads to the Gemini Files API with polling and cleanup
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:46:37 +10:00
bradautomates
65d8dd1194 feat: Gemini interaction adapter with categorized, key-safe failures
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:46:22 +10:00
bradautomates
ccf43c5718 feat: resolve watch engine and Gemini key in shared config
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:46:00 +10:00
bradautomates
93822ce2bd fix: quote plugin root in SessionStart hook
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 13:45:19 +10:00
bradautomates
a646981d85 docs: clarify installation paths with desktop screenshots 2026-09-12 22:47:17 +10:00
bradautomates
e90ef44c32 Implement v0.3.0 reliability fixes and managed WhisperX transcription
Add opt-in local transcription with managed installation, cache warm-up,
and a one-time backend choice while preserving native-caption priority.

Correct frame timing and coverage, caption provenance and download
ownership, configuration parsing, provider pairing, and partial reports.
Update cross-host instructions, packaging, and test-gated release CI.

Validate 198 isolated tests, real local English and Spanish inference,
network-denied warm-cache inference, live captions/media, and packaging.
Record platform and account-dependent acceptance limits separately.
2026-09-12 22:09:43 +10:00
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>
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>
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>
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>
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>
2026-04-24 14:40:34 +10:00