Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
21 changes: 14 additions & 7 deletions site/docs/submit.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"` |
Expand All @@ -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`) |
Expand All @@ -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.
11 changes: 11 additions & 0 deletions src/schema/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"'),
),
Expand Down
38 changes: 38 additions & 0 deletions src/schema/manifest_test.ts
Original file line number Diff line number Diff line change
@@ -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")
})
4 changes: 2 additions & 2 deletions src/scripts/check_urls.ts
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/utils/url_checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> => new Promise((resolve) => setTimeout(resolve, ms))
14 changes: 14 additions & 0 deletions src/utils/url_checker_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
Loading