feat: add agent-skills discovery release pipeline#66
Conversation
|
Thanks for taking care of this @gregnr! I went through the PR and also compared our Suggested improvements to
|
Replaces the inline bash tar loop with a TypeScript build script that produces both skill tarballs and a discovery index.json conforming to the agent-skills discovery spec (RFC v0.2.0). Applies improvements identified in code review of #66: - Deterministic archives: zero timestamps/uid/gid so digests only change when content changes (requires GNU tar; falls back to BSD tar with a warning on macOS) - Exclude patterns: .gitignore-style walk skips .DS_Store, .vscode, etc. - Auto-detect skill-md vs archive: single-file skills emit type "skill-md" and copy SKILL.md directly instead of creating a tarball - Relative URLs in index.json: portable across serving paths - Validate both name and description frontmatter fields Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
Closing in favor of #77. |
…ne (#77) * feat: build index.json for .well-known/agent-skills in release pipeline Replaces the inline bash tar loop with a TypeScript build script that produces both skill tarballs and a discovery index.json conforming to the agent-skills discovery spec (RFC v0.2.0). Applies improvements identified in code review of #66: - Deterministic archives: zero timestamps/uid/gid so digests only change when content changes (requires GNU tar; falls back to BSD tar with a warning on macOS) - Exclude patterns: .gitignore-style walk skips .DS_Store, .vscode, etc. - Auto-detect skill-md vs archive: single-file skills emit type "skill-md" and copy SKILL.md directly instead of creating a tarball - Relative URLs in index.json: portable across serving paths - Validate both name and description frontmatter fields Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * docs: add .well-known discovery section and GitHub Action migration note to README Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> * feat: simplify release build script using tar npm library Replace shell-out to system tar/gzip binaries with the tar npm package. Drops the custom file-walker, exclude-pattern matching, GNU tar detection, and BSD tar fallback — none of which are needed in a clean CI checkout. Determinism is preserved via portable: true and mtime: new Date(0). Always emits type: "archive" for all skills, removing the isSingleFile branch since the spec recommendation is not a hard requirement. Renames release-please.yml to release.yml. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…45641) ## Summary This PR makes `fetchAgentSkills.mjs` a spec-compliant client of the [agent-skills `.well-known` URI spec](agentskills/agentskills#254), and updates the script to match the current release structure in [`supabase/agent-skills`](https://github.com/supabase/agent-skills). --- ## 1. Spec-compliant URL resolution and digest verification `fetchAgentSkills.mjs` acts as a client consuming the `.well-known` discovery index. The [agent-skills `.well-known` spec](agentskills/agentskills#254) is explicit on two points: **URL resolution** — skill artifact URLs in `index.json` must be resolved per [RFC 3986 §5.2.2](https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.2) using the index URL as the base URI: > "The `url` field specifies where to fetch the skill artifact. URLs are resolved per RFC 3986 Section 5 using the index URL as the base URI." This means `skill.url` can be relative (`supabase.tar.gz`), path-absolute (`/.well-known/agent-skills/supabase.tar.gz`), or fully absolute (e.g. a CDN URL like `https://cdn.example.com/supabase.tar.gz`). The previous implementation extracted a filename with `.split('/').pop()` which happened to work for bare relative URLs but was not doing RFC 3986 resolution. **Digest verification** — clients must verify artifact integrity before use: > "Clients **must** verify downloaded content against the `digest` in the index. A mismatch indicates the content is corrupted or tampered with — clients **must not** use unverified content." The updated script uses `new URL(skill.url, githubReleaseIndexUrl)` for compliant resolution, verifies each artifact's SHA-256 digest from the in-memory buffer before any disk writes, and only writes to `public/.well-known/agent-skills/` once all digests pass. **Acknowledged overhead**: since Supabase owns both the publisher ([`scripts/build-release.ts`](https://github.com/supabase/agent-skills/blob/main/scripts/build-release.ts) in `supabase/agent-skills`) and this consumer, the practical risk of non-compliant URL handling is currently low — the publisher always emits bare relative filenames. However, being spec-compliant here gives us full flexibility to change how skills are packaged or hosted in `supabase/agent-skills` in the future (e.g. moving artifacts to a CDN) without needing to update this script. --- ## 2. Semver release tags #44878 referenced `supabase/agent-skills#66` (date+SHA tags). [supabase/agent-skills#77](supabase/agent-skills#77) has since merged, moving releases to semver tags managed by Release Please. `/releases/latest` works for both formats — no code change needed, just a rebase. --------- Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Implements part 1 of Cloudflare's agent-skills discovery RFC - builds per-skill archives and an
index.jsonthat are meant to live in/.well-known/agent-skills/.... Part 2 is getting ourwwwsite to pull these release artifacts at build time and serve them fromhttps://supabase.com/.well-known/agent-skills/....Artifacts live in GitHub releases within this repo. Releases will auto-generate upon any change to
./skillsinmain. Since each skill has their own independent version, these bundled releases just use the current date+commit hash as the tag.