mirror of
https://github.com/Luchexx/claude-video.git
synced 2026-11-02 09:19:48 +00:00
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>
This commit is contained in:
parent
de8b5b5dc0
commit
457627318c
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "watch",
|
"name": "watch",
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"description": "Give an agent video evidence: timestamped frames and native captions, with optional local WhisperX or Groq/OpenAI transcription.",
|
"description": "Give an agent video evidence: timestamped frames and native captions, with optional local WhisperX or Groq/OpenAI transcription.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Bradley Bonanno"
|
"name": "Bradley Bonanno"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "watch",
|
"name": "watch",
|
||||||
"version": "0.3.0",
|
"version": "0.3.1",
|
||||||
"description": "Give an agent video evidence: timestamped frames and native captions, with optional local WhisperX or Groq/OpenAI transcription.",
|
"description": "Give an agent video evidence: timestamped frames and native captions, with optional local WhisperX or Groq/OpenAI transcription.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Bradley Bonanno"
|
"name": "Bradley Bonanno"
|
||||||
|
|||||||
@ -20,7 +20,8 @@ Agent Skills package that gives an agent a video input. Installable across Claud
|
|||||||
- The product is the slash-command-invoked skill (`/watch <url-or-path> [question]`), not a CLI. `scripts/watch.py` is implementation. Features must work across every harness the skill installs into, not just Claude Code.
|
- The product is the slash-command-invoked skill (`/watch <url-or-path> [question]`), not a CLI. `scripts/watch.py` is implementation. Features must work across every harness the skill installs into, not just Claude Code.
|
||||||
- **The skill is one self-contained folder: `skills/watch/`.** SKILL.md and `scripts/` are siblings inside it. This is what lets `npx skills add` copy a working skill as a unit — do NOT move SKILL.md or `scripts/` back to the repo root, or non-Claude installers will copy SKILL.md without the scripts.
|
- **The skill is one self-contained folder: `skills/watch/`.** SKILL.md and `scripts/` are siblings inside it. This is what lets `npx skills add` copy a working skill as a unit — do NOT move SKILL.md or `scripts/` back to the repo root, or non-Claude installers will copy SKILL.md without the scripts.
|
||||||
- **Path resolution is harness-agnostic.** SKILL.md resolves `SKILL_DIR` as the directory of the SKILL.md the model just Read, then runs `${SKILL_DIR}/scripts/...`. Do NOT reintroduce `${CLAUDE_SKILL_DIR}` (Claude-Code-only) — it is unset on Codex/Cursor/agents and breaks every script call there.
|
- **Path resolution is harness-agnostic.** SKILL.md resolves `SKILL_DIR` as the directory of the SKILL.md the model just Read, then runs `${SKILL_DIR}/scripts/...`. Do NOT reintroduce `${CLAUDE_SKILL_DIR}` (Claude-Code-only) — it is unset on Codex/Cursor/agents and breaks every script call there.
|
||||||
- **No `commands/` wrapper.** `/watch` is derived from SKILL.md frontmatter (`name: watch` + `user-invocable: true`). A separate command file creates a duplicate slash command.
|
- **No `commands/` wrapper.** `/watch` comes from `name: watch` (skills are user-invocable by default). A separate command file creates a duplicate slash command.
|
||||||
|
- **SKILL.md frontmatter uses only Agent Skills keys:** `name`, `description`, `license`, `allowed-tools`, `metadata`, `compatibility`. Claude's skill upload rejects anything else; the version lives in `metadata.version`.
|
||||||
|
|
||||||
## Install surfaces
|
## Install surfaces
|
||||||
|
|
||||||
@ -45,6 +46,6 @@ bash skills/watch/scripts/build-skill.sh # → dist/watch.skill
|
|||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
|
|
||||||
- Keep the version in sync across `skills/watch/SKILL.md` (frontmatter), `.claude-plugin/plugin.json`, and `.codex-plugin/plugin.json` when cutting a release.
|
- Keep the version in sync across `skills/watch/SKILL.md` (`metadata.version`), `.claude-plugin/plugin.json`, and `.codex-plugin/plugin.json` when cutting a release.
|
||||||
- Releasing: tag `vX.Y.Z` and push the tag; `.github/workflows/release.yml` builds `dist/watch.skill` and attaches it to the GitHub release.
|
- Releasing: tag `vX.Y.Z` and push the tag; `.github/workflows/release.yml` builds `dist/watch.skill` and attaches it to the GitHub release.
|
||||||
- Never commit real API keys or `.env` contents; keys live in `~/.config/watch/.env` (mode `0600`) at runtime.
|
- Never commit real API keys or `.env` contents; keys live in `~/.config/watch/.env` (mode `0600`) at runtime.
|
||||||
|
|||||||
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
All notable changes to `/watch` are documented here.
|
All notable changes to `/watch` are documented here.
|
||||||
|
|
||||||
|
## [0.3.1] — Unreleased
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- `SKILL.md` frontmatter uses only Agent Skills keys, so `watch.skill` uploads to Claude (the upload rejected `version`, `argument-hint`, `user-invocable`, and other extra keys). The version moves to `metadata.version`.
|
||||||
|
|
||||||
## [0.3.0] — 2026-09-25
|
## [0.3.0] — 2026-09-25
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@ -1,14 +1,10 @@
|
|||||||
---
|
---
|
||||||
name: watch
|
name: watch
|
||||||
version: "0.3.0"
|
|
||||||
description: Watch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or local WhisperX / cloud Whisper fallback), and hands the result to the agent so it can answer questions about what's in the video. With a Gemini API key, Google's agentic video model watches the full video instead.
|
description: Watch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or local WhisperX / cloud Whisper fallback), and hands the result to the agent so it can answer questions about what's in the video. With a Gemini API key, Google's agentic video model watches the full video instead.
|
||||||
argument-hint: "<video-url-or-path> [question]"
|
|
||||||
allowed-tools: Bash, Read, AskUserQuestion
|
|
||||||
homepage: https://github.com/bradautomates/claude-video
|
|
||||||
repository: https://github.com/bradautomates/claude-video
|
|
||||||
author: bradautomates
|
|
||||||
license: MIT
|
license: MIT
|
||||||
user-invocable: true
|
allowed-tools: Bash, Read, AskUserQuestion
|
||||||
|
metadata:
|
||||||
|
version: "0.3.1"
|
||||||
---
|
---
|
||||||
|
|
||||||
# /watch
|
# /watch
|
||||||
@ -17,7 +13,7 @@ Run the bundled Python script. With the **gemini** engine (a `GEMINI_API_KEY` is
|
|||||||
|
|
||||||
## Resolve the skill and interpreter
|
## Resolve the skill and interpreter
|
||||||
|
|
||||||
Set `SKILL_DIR` to the **absolute directory containing this SKILL.md that you just read**. `scripts/` is its sibling in every host; do not use a Claude-specific environment variable. Check that `SKILL_DIR/scripts/watch.py` exists. The whole `skills/watch/` folder must be installed, with one canonical skill and no command wrapper.
|
`SKILL_DIR` is the absolute directory containing this SKILL.md; `scripts/` sits beside it.
|
||||||
|
|
||||||
Commands below use `python3` for macOS/Linux. On Windows, verify a working Python 3.10+ with `python --version` or `py -3 --version` and use that interpreter. `python3` is not always a Store alias; inspect the actual result. In PowerShell use `$SKILL_DIR` rather than Bash variable syntax, for example:
|
Commands below use `python3` for macOS/Linux. On Windows, verify a working Python 3.10+ with `python --version` or `py -3 --version` and use that interpreter. `python3` is not always a Store alias; inspect the actual result. In PowerShell use `$SKILL_DIR` rather than Bash variable syntax, for example:
|
||||||
|
|
||||||
|
|||||||
@ -10,6 +10,14 @@ from pathlib import Path
|
|||||||
ROOT = Path(__file__).resolve().parents[1]
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
||||||
|
|
||||||
|
def test_frontmatter_uses_only_agent_skills_keys():
|
||||||
|
# claude.ai uploads reject any other top-level key.
|
||||||
|
text = (ROOT / 'skills/watch/SKILL.md').read_text(encoding='utf-8')
|
||||||
|
frontmatter = text.split('---\n')[1]
|
||||||
|
keys = {line.split(':')[0] for line in frontmatter.splitlines() if line and not line.startswith(' ')}
|
||||||
|
assert keys <= {'name', 'description', 'license', 'allowed-tools', 'metadata', 'compatibility'}
|
||||||
|
|
||||||
|
|
||||||
def test_release_versions_match_canonical_skill():
|
def test_release_versions_match_canonical_skill():
|
||||||
skill = ROOT / 'skills/watch/SKILL.md'
|
skill = ROOT / 'skills/watch/SKILL.md'
|
||||||
version = re.search(r'^ version: "([^"]+)"', skill.read_text(encoding='utf-8'), re.M).group(1)
|
version = re.search(r'^ version: "([^"]+)"', skill.read_text(encoding='utf-8'), re.M).group(1)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user