diff --git a/AGENTS.md b/AGENTS.md index 7c2477e..494e5c2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,14 +1,14 @@ # Cataclysm: Bright Nights Mod Registry Agent Instruction -## Tasks - -- [x] Update workflows and docs for registry-index syncing -- [ ] TASK: improve and refactor code according to coding standards - ## Skills - Add registry manifest skill: `.agents/skills/add-registry/SKILL.md` +## Notes + +- Keep public manifest docs and schema output aligned with runtime autoupdate substitution keys. +- Treat `homepage` as part of manifest URL health checks. + - **Tick the checkbox** in AGENTS.md when you finish a task, and commit (follow conventional commit). - **if all subtasks are ticked, erase task checkbox section and update this file accordingly from knowledge gained from session, then amend it** - Don't `sed`, just edit the file normally. diff --git a/site/docs/submit.md b/site/docs/submit.md index 4a28184..29056b0 100644 --- a/site/docs/submit.md +++ b/site/docs/submit.md @@ -87,14 +87,15 @@ id: your_mod_id display_name: "Your Mod Name" short_description: "A brief description of your mod (max 200 chars)" -author: "Your Name" -license: "MIT" # Use SPDX identifier +author: + - "Your Name" +license: "MIT" homepage: "https://github.com/yourname/your-mod" version: "1.0.0" dependencies: - - bn: ">=0.9.1" + bn: ">=0.9.1" categories: - content @@ -129,7 +130,7 @@ deno task check-urls registry-index/manifests/your_mod_id.yaml | `id` | Unique identifier (lowercase, underscores) | | `display_name` | Human-readable name | | `short_description` | Brief description (max 200 chars) | -| `author` | Mod author(s) | +| `author` | Array of mod author names | | `license` | SPDX license ID or `"ALL-RIGHTS-RESERVED"` | | `version` | Current version | | `source.type` | `"github_archive"`, `"gitlab_archive"`, or `"direct_url"` | @@ -141,8 +142,8 @@ deno task check-urls registry-index/manifests/your_mod_id.yaml | --------------------- | ----------------------------------------------------------------- | | `description` | Full mod description | | `homepage` | Link to repo or documentation | -| `dependencies` | List of required mod IDs | -| `conflicts` | List of incompatible mod IDs | +| `dependencies` | Object mapping required mod IDs to version constraints | +| `conflicts` | Object mapping incompatible mod IDs to version constraints | | `categories` | Organization categories | | `tags` | Search tags | | `icon_url` | Icon URL (`.png`, `.svg`, `.webp`, `.avif`, `.jpg/.jpeg`, `.gif`) | @@ -167,5 +168,11 @@ To enable automatic version updates: ```yaml autoupdate: type: tag # or "commit" - url: "https://github.com/user/repo/archive/$version.zip" + update_url: "https://github.com/user/repo" + url: "https://github.com/user/repo/archive/refs/tags/$version.zip" + icon_url: "https://raw.githubusercontent.com/user/repo/$commit_sha/icon.png" ``` + +`update_url` is used to discover releases. Optional substitution templates such as +`autoupdate.url`, `autoupdate.icon_url`, and `autoupdate.commit_sha` are applied when a +new release is found. diff --git a/src/schema/manifest.ts b/src/schema/manifest.ts index e871ae2..7902310 100644 --- a/src/schema/manifest.ts +++ b/src/schema/manifest.ts @@ -76,6 +76,17 @@ export const AutoupdateConfig = v.looseObject({ update_url: v.optional( v.string("URL to check for updates. If omitted, uses homepage."), ), + url: v.optional( + v.string("Template for release archive URL. Supports $version and $commit_sha substitutions."), + ), + icon_url: v.optional( + v.string("Template for icon URL. Supports $version and $commit_sha substitutions."), + ), + commit_sha: v.optional( + v.string( + "Template override for source.commit_sha. Supports $version and $commit_sha substitutions.", + ), + ), branch: v.optional( v.string('Branch to track when type is "commit"'), ), diff --git a/src/schema/manifest_test.ts b/src/schema/manifest_test.ts new file mode 100644 index 0000000..c8c820d --- /dev/null +++ b/src/schema/manifest_test.ts @@ -0,0 +1,38 @@ +import { assertEquals } from "@std/assert" +import * as v from "valibot" +import { ModManifest } from "./manifest.ts" + +Deno.test("ModManifest parses documented autoupdate substitution fields", () => { + const manifest = v.parse(ModManifest, { + schema_version: "1.0", + id: "example_mod", + display_name: "Example Mod", + short_description: "Example description", + author: ["Example Author"], + license: "MIT", + version: "1.0.0", + homepage: "https://github.com/example/example-mod", + source: { + type: "github_archive", + url: "https://github.com/example/example-mod/archive/refs/tags/v1.0.0.zip", + }, + autoupdate: { + type: "tag", + update_url: "https://github.com/example/example-mod", + url: "https://github.com/example/example-mod/archive/refs/tags/$version.zip", + icon_url: "https://raw.githubusercontent.com/example/example-mod/$commit_sha/icon.png", + commit_sha: "$commit_sha", + regex: "^v", + }, + }) + + assertEquals( + manifest.autoupdate?.url, + "https://github.com/example/example-mod/archive/refs/tags/$version.zip", + ) + assertEquals( + manifest.autoupdate?.icon_url, + "https://raw.githubusercontent.com/example/example-mod/$commit_sha/icon.png", + ) + assertEquals(manifest.autoupdate?.commit_sha, "$commit_sha") +}) diff --git a/src/scripts/check_urls.ts b/src/scripts/check_urls.ts index aa33bf0..a329362 100644 --- a/src/scripts/check_urls.ts +++ b/src/scripts/check_urls.ts @@ -1,7 +1,7 @@ #!/usr/bin/env -S deno run --allow-read --allow-net /** * Check URLs in all manifests. - * Verifies that download URLs and icon URLs are reachable. + * Verifies that download, icon, and homepage URLs are reachable. */ import { Command } from "@cliffy/command" @@ -93,7 +93,7 @@ if (import.meta.main) { await new Command() .name("check-urls") .version("1.0.0") - .description("Check that manifest URLs (download and icon) are reachable") + .description("Check that manifest URLs (download, icon, and homepage) are reachable") .arguments("[target:string]") .action(async (_options, target = "registry-index/manifests") => { try { diff --git a/src/utils/url_checker.ts b/src/utils/url_checker.ts index 2317336..027944b 100644 --- a/src/utils/url_checker.ts +++ b/src/utils/url_checker.ts @@ -115,6 +115,7 @@ export const extractManifestUrls = (manifest: { [ manifest.source?.url, manifest.icon_url, + manifest.homepage, ].filter((url): url is string => url !== undefined) const sleep = (ms: number): Promise => new Promise((resolve) => setTimeout(resolve, ms)) diff --git a/src/utils/url_checker_test.ts b/src/utils/url_checker_test.ts index c22e7db..527412b 100644 --- a/src/utils/url_checker_test.ts +++ b/src/utils/url_checker_test.ts @@ -30,6 +30,20 @@ Deno.test("extractManifestUrls - extracts icon URL", () => { assertEquals(urls.includes("https://example.com/icon.png"), true) }) +Deno.test("extractManifestUrls - extracts homepage URL", () => { + const manifest = { + source: { + url: "https://example.com/mod.zip", + }, + homepage: "https://example.com/mod", + } + + const urls = extractManifestUrls(manifest) + assertEquals(urls.length, 2) + assertEquals(urls.includes("https://example.com/mod.zip"), true) + assertEquals(urls.includes("https://example.com/mod"), true) +}) + Deno.test("extractManifestUrls - handles missing fields", () => { const manifest = {} const urls = extractManifestUrls(manifest)