Skip to content
Merged
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
32 changes: 20 additions & 12 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
# Changesets
# Releases

Every change to a published package needs a changeset: run `pnpm changeset`,
pick the bump, and describe the change for the changelog.
Every change to a published package needs a changeset (`pnpm changeset`). All `@typeonce/ritmo*` packages are one fixed group and always share a version. A breaking entry carries its fix (a short diff or the exact replacement): the shipped `CHANGELOG.md` is the upgrade guide.

All `@typeonce/ritmo*` packages are one fixed group: they are always
released together with the same version.
On merge to `main`, the release workflow opens a "Version Packages" pull request. Merging it publishes to npm with trusted publishing and provenance. The workflow runs only while the repository variable `RITMO_RELEASES_ENABLED` is `true`.

On merge to `main`, the release workflow opens a "Version Packages" pull
request that applies pending changesets. Merging that pull request publishes
the new version to npm.
If a publish fails, start a fresh run (`gh workflow run release.yml --ref main`) instead of re-running the job: a re-run fails with `TLOG_CREATE_ENTRY_ERROR (409)` because the first attempt already logged its provenance.

The workflow waits until the repository is named `typeonce-dev/ritmo` and
the repository variable `RITMO_RELEASES_ENABLED` is `true`.
Follow [RELEASING.md](../RELEASING.md) for the first Ritmo publication and
trusted-publisher setup before relying on automatic publishing.
## Add a package

Trusted publishing cannot create a package, so a new `packages/<dir>` (`@typeonce/<name>`) is published once by hand:

1. In its PR: give it the group's current version, and add it to the `fixed` group in `config.json`, to `scripts/pack-check.ts`, and to `tsconfig.packages.json`, with a changeset.
2. After merge, from clean `main`:

```sh
pnpm install --frozen-lockfile && pnpm run check && pnpm pack:check
npm login
mkdir -p /tmp/ritmo-bootstrap && pnpm build && pnpm --dir packages/<dir> pack --pack-destination /tmp/ritmo-bootstrap
npm publish /tmp/ritmo-bootstrap/typeonce-<name>-<version>.tgz --access public --provenance=false --ignore-scripts
```

3. On npm, add a trusted publisher: `typeonce-dev` / `ritmo` / `release.yml` / environment `npm`, and tick **Allow npm publish** (without it the workflow gets `403 OIDC permission denied`). Do it close to the next release: an unvalidated publisher expires after two days.
4. After the next CI release publishes it, require 2FA and disallow token publishing in its npm settings.
2 changes: 1 addition & 1 deletion .changeset/agent-docs-and-simulation-coverage.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@

- **Breaking: `ritmo-devtools lint` fails on an uncovered simulation module.** Every module the entry loads that the `ritmo/keep-simulation-headless` override in `.oxlintrc.json` does not cover is reported as `uncovered-simulation-module`, and the command exits 1. Add the module (or its folder) to the simulation override's `"files"`, or stop importing values from it. Modules loaded only inside `lintTarget` are not checked. Requires Node 22.15 or newer (`engines.node` is now `>=22.15`).
- **An agent skill ships with `@typeonce/ritmo`** in `skills/ritmo/SKILL.md`, for every change: where the docs are, and principles for where a game's code and state belong. Link it into the folder the game's agent reads skills from, for example `ln -s ../../node_modules/@typeonce/ritmo/skills/ritmo .agents/skills/ritmo`. `SETUP.md` in `@typeonce/ritmo` is the one-time setup: the base packages and checks every game uses, the add-ons, and linking the skill.
- **Every package ships its `CHANGELOG.md`.** The upgrade notes for 0.8.0 and 0.9.0 moved from the repository's `MIGRATION.md` into the `@typeonce/ritmo` changelog.
- **Every package ships its `CHANGELOG.md`.** The upgrade notes for 0.8.0 and 0.9.0 are in the `@typeonce/ritmo` changelog.
- **JSDoc corrections.** Examples no longer provide randomness or time as services (use the `Random` resource and `Clock`), the `Command` module example declares its commands, inspector docs state that `added`/`changed` reads report records since the inspector's previous evaluation, and every example uses prefixed names (`"Game/Position"`). Guidance that lived only in the repository's guides (spawn order, `ReadonlyValue` helpers, re-entering a state, `thisTick` and plugin systems, service effects and rollback) is now in the JSDoc.
- Package READMEs link other packages' READMEs by GitHub URL, so the links work on npm.
20 changes: 20 additions & 0 deletions .changeset/skill-playbooks-and-renderer-free-schema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
"@typeonce/ritmo": patch
"@typeonce/ritmo-math": patch
"@typeonce/oxlint-plugin-ritmo": minor
---

**The Ritmo skill routes each change to a playbook, and simulation code names no renderer type.**

- **Breaking: `ritmo/keep-simulation-headless` reports type-only renderer imports** (`import type { Container } from "pixi.js"`, `export type ... from "three"`) and subpath imports of `@typeonce/ritmo-render` and `@typeonce/ritmo-pixi`. A schema that names a renderer type ties the simulation to that renderer. Move the renderer service (a `Descriptor.Service<NodeRegistry.NodeRegistry<Sprite>>()(...)`) and the systems that use it into render code; services are not registered in the schema, so nothing else changes:

```diff
-// src/game/schema.ts
-import type { Sprite } from "pixi.js"
-export const Sprites = Descriptor.Service<NodeRegistry.NodeRegistry<Sprite>>()("Game/Sprites")
+// src/render/sprites.ts
+import type { Sprite } from "pixi.js"
+export const Sprites = Descriptor.Service<NodeRegistry.NodeRegistry<Sprite>>()("Game/Sprites")
```

- **The skill in `skills/ritmo` now has playbooks**: one per kind of change (a mechanic, content, UI and rendering, a bug fix, a refactor, state and upgrades), each a short list of steps that ends with the check that proves it. `SKILL.md` routes to them and keeps the principles. A game that already links the skill folder gets them on upgrade.
3 changes: 1 addition & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ permissions:
jobs:
release:
name: Version or publish
# Enable after the organization transfer, rename, first publication, and npm trust setup.
# See RELEASING.md. An unset variable leaves release automation paused.
# An unset RITMO_RELEASES_ENABLED variable pauses release automation (see .changeset/README.md).
if: github.repository == 'typeonce-dev/ritmo' && vars.RITMO_RELEASES_ENABLED == 'true'
runs-on: ubuntu-latest
environment: npm
Expand Down
20 changes: 3 additions & 17 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{
"files": [
"packages/*/src/**",
"examples/**",
"integration/**",
"scripts/**"
],
"rules": {
Expand All @@ -22,11 +22,7 @@
{
"files": [
"packages/*/src/**",
"examples/*/simulation.ts",
"examples/*/schema.ts",
"examples/*/systems/**",
"examples/genetics/logic.ts",
"examples/genetics/math.ts"
"integration/*/**"
],
"rules": {
"ritmo/use-clock-for-time": "error",
Expand All @@ -35,22 +31,12 @@
"ritmo/keep-simulation-headless": "error",
"ritmo/no-infinity-in-simulation-data": "error"
}
},
{
"files": [
"examples/*/systems/render*.ts"
],
"rules": {
"ritmo/keep-simulation-headless": "off"
}
}
],
"ignorePatterns": [
"**/dist/**",
"**/node_modules/**",
"coverage/**",
".agents/**",
"docs/**",
"output/**"
".agents/**"
]
}
Loading
Loading