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",
|
||||
"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.",
|
||||
"author": {
|
||||
"name": "Bradley Bonanno"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"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.",
|
||||
"author": {
|
||||
"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 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.
|
||||
- **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
|
||||
|
||||
@ -45,6 +46,6 @@ bash skills/watch/scripts/build-skill.sh # → dist/watch.skill
|
||||
|
||||
## 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.
|
||||
- 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.
|
||||
|
||||
## [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
|
||||
|
||||
### Added
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
---
|
||||
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.
|
||||
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
|
||||
user-invocable: true
|
||||
allowed-tools: Bash, Read, AskUserQuestion
|
||||
metadata:
|
||||
version: "0.3.1"
|
||||
---
|
||||
|
||||
# /watch
|
||||
@ -17,7 +13,7 @@ Run the bundled Python script. With the **gemini** engine (a `GEMINI_API_KEY` is
|
||||
|
||||
## 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:
|
||||
|
||||
|
||||
@ -10,9 +10,17 @@ from pathlib import Path
|
||||
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():
|
||||
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)
|
||||
for relative in ('.claude-plugin/plugin.json', '.codex-plugin/plugin.json'):
|
||||
assert json.loads((ROOT / relative).read_text(encoding='utf-8'))['version'] == version
|
||||
assert json.loads((ROOT / '.codex-plugin/plugin.json').read_text(encoding='utf-8'))['skills'] == './skills/'
|
||||
|
||||
Loading…
Reference in New Issue
Block a user