Conversation
Studio now shows a plugin's own icon beside its name in the Launcher list, so `manifest.json` gains `icon`: a package-relative image the store and the installed list both draw. index.json carries it as an absolute raw URL pinned to the release tag, for the same reason the download URL is - an index entry describes one immutable version, and the picture it shows should not change under it when the next version lands. The validator enforces every rule Studio enforces, one step earlier: square, 64x64 to 512x512, at most 512 KB, .png/.webp/.jpg/.jpeg only, and the bytes must really be the format the name claims. scripts/lib/image.mjs is a port of Studio's reader and carries the same standing obligation as the manifest validator next to it - if Studio's rules move, this moves with them. The icon has to reach dist/ the way manifest.json does, so the template's build script copies it and package-plugin.mjs refuses a zip that is missing it. The starter ships a placeholder piece, which is also what keeps the whole path exercised by `node scripts/validate.mjs` on every run. Also fills in index.schema.json's `contributes.locales`, which the generator has been emitting since language packs landed without the schema knowing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…n sync The starter no longer declares an icon. A template that ships one hands every new plugin a placeholder to forget to replace, and the fallback it was standing in for is better anyway — Studio draws a monogram from the plugin's name, which is a fine place for a plugin to stay. That left the icon rules with nothing in the repository exercising them, so they get their own tests (`node --test scripts/lib/*.test.mjs`, no dependency, wired into CI ahead of the validator). Without them the port would be code CI never runs until the first contributor's plugin is accepted or refused by rules nobody has executed. Also regenerates index.json, which has been stale since the Steam achievements plugin landed without it — `generate-index.mjs --check` runs in CI, so the registry job has been failing on develop since that merge. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… nobody can check The plugin's Rust half had never been compiled and its manifest carried six placeholder sha256 digests, so every game build failed on a file that was not there. The stated reason — that the Steamworks SDK needs a Valve partner account — is not true: steamworks-sys vendors the SDK under its own lib/steam/ and falls back to it whenever STEAM_SDK_LOCATION is unset. So the bridge now builds with a Rust toolchain and nothing else, and contributes.buildDependencies is gone: the shared library ships beside the executable, copied out of cargo's own output so the two can never drift apart. Verified against a live Steam client on windows-x64 with Spacewar (App ID 480): init reports the real App ID and language, an unknown API name is refused by Steam rather than silently succeeding, and unlock / setStat / indicateProgress / resetAll all land through StoreStats. Studio's own artifact compiler stages the package into a preview compile with both digests matching. Digests are now computed, never authored. A sidecar target claims that a package carries certain bytes, and that is only true of a package that has the binary — which this repository does not, they are build output. So manifest.json declares no sidecar at all; sidecar/contribution.json holds what is not a property of a compiled artifact, and build.mjs includes each platform whose files are present, hashes them, and writes the block into dist/manifest.json. With no binaries at all it emits a mirror-only package: every node still works, nothing reaches Steam. That shape is what CI packages on every push, because it is the one that must never break. Also in the TypeScript half: - narraleaf-studio ^0.2.0 -> ^0.5.0. The plugin was written against APIs that version predates, so `yarn typecheck` had failed since the plugin landed and CI has been red ever since. It is green now, with 0 errors. - Join the freeze/reload contract. The store mutated memory before awaiting a write that a frozen project discards, and never re-read after a restore — so the author's next edit wrote pre-restore memory over the version they had just restored. commit() now bails before touching memory, every writing control goes through FreezeGuard, and the store registers a reloader. - The Steam App ID field wrote the whole catalog to disk on every keystroke; it is a DraftInput like every other field now. - 29 tests for the catalog's pure half, and a plugin thumbnail. package-plugin.mjs validates dist/manifest.json too, not just the committed one: the shipped manifest is now generated, and generation was the one part of the package nothing checked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release merge for
narraleaf.steam-achievements@0.1.0. Tag goes onmasteronce this lands, per README → Releasing (maintainers).What lands
Steam Achievements 0.1.0 — now actually shippable. Its Rust half had never been compiled and its manifest carried six placeholder sha256 digests, so every game build failed on a file that was not there. The stated blocker — that the Steamworks SDK needs a Valve partner account — turned out not to be true:
steamworks-sysvendors the SDK under its ownlib/steam/and falls back to it wheneverSTEAM_SDK_LOCATIONis unset. So the bridge builds with a Rust toolchain and nothing else, andcontributes.buildDependenciesis gone: the Steam shared library ships beside the executable, copied out of cargo's own output so the two cannot drift apart.Verified against a live Steam client on
windows-x64using Spacewar (App ID 480): init reports the real App ID and language; an unknown API name is refused by Steam rather than silently succeeding, which is how you know the call reaches Steam;unlock/setStat/indicateProgress/resetAllall land throughStoreStats. Studio's own artifact compiler stages the package into a preview compile with both digests matching.Digests are computed, never authored.
manifest.jsondeclares no sidecar at all — a sidecar target claims a package carries certain bytes, and that is only true of a package that has the binary, which this repository does not (they are build output).sidecar/contribution.jsonholds what is not a property of a compiled artifact;build.mjsincludes each platform whose files are present, hashes them, and writes the block intodist/manifest.json. With no binaries it emits a mirror-only package: every node still works, nothing reaches Steam. That is the shape CI packages on every push, because it is the one that must never break.Plugin thumbnails (
cc27e69,db806ea,b5d97ed) — already ondevelop, riding along.Registry tooling
release.ymlgains a three-platform Rust build matrix. Each runner builds the sidecar for its own platform; the release job collects them and packages. Packaging the macOS image on Linux is safe: no zip writer records POSIX modes, so Studio repairs the executable bit when it spawns a sidecar (sidecarHost.ensureExecutable).ci.ymlruns a plugin'stestscript when it has one.package-plugin.mjsnow validatesdist/manifest.jsontoo, and re-hashes every declared sidecar file. The shipped manifest is generated, and generation was the one part of the package nothing checked.Checks
develop— the first green run since the plugin landed; it had been failing on anarraleaf-studiodevDependency pinned to a version that predates the APIs the plugin uses.yarn typecheck0 errors, 29 unit tests,validate.mjs,generate-index.mjs --check, and the registry tooling tests all pass.Merge with a merge commit, not squash or rebase —
masteronly advances through release merges.🤖 Generated with Claude Code