ADR-0151: Every release publishes its OpenAPI document and generated TypeScript and Java clients
- Status: accepted
- Date: 2026-09-30
- Deciders: Mahdi Amirabdollahi
- Change:
openspec/changes/09-public-api-contract
Context
ADR-0019 generates the web UI's types from web/openapi.json, and the UI keeps using them. Anyone else who wants to call the API writes their own client from the source tree, or from a document that may not match the release they run. The plugin API and SDK already reach Maven Central and npm on every relevant release (ADR-0102), with provenance (ADR-0139). This revisits ADR-0019 in part: it kept the generated types inside the app, and does not publish them.
Decision
- The release attaches the OpenAPI document as
artemis-studio-<V>.openapi.json, withinfo.versionset to the release and a.sha256, and attests its provenance next to the jar. The release job verifies the attestation as a user would. @artemis-studio/client(web/packages/client) isopenapi-typescripttypes plusopenapi-fetch, withcreateStudioClient({baseUrl, token})adding the bearer header and throwing a typedProblemErrorfor a problem+json answer. It is built like the plugin SDK (build.mjsstamps the version, 2026.09.0 is npm 2026.9.0), from the document, and published with npm provenance through trusted publishing on every release.io.github.sudoitir:artemis-studio-client(clients/java/pom.xml) is generated byopenapi-generator-maven-pluginwith generatorjava, librarynative(java.net.httpand Jackson), fromweb/openapi.json. It is a standalone pom, since the Studio pom has no modules. It is built in every pull request, and published to Central on every release, signed and attested like the plugin API.clients/**,web/openapi.jsonandweb/packages/client/**are release inputs, so a change to them releases.- The web UI keeps
schema.d.tsand its ownrequest.ts. It does not move to the published client.
Consequences
- A client of release V is generated from the document the tests checked for V, so it is "of that version" by construction and cannot drift.
- Two more artifacts per release and a new npm package whose trusted publisher the maintainer sets up once on npmjs.com.
- A generator regression can fail a pull request that never touched the generator, because the document is its input; that is the point of building it in CI.
- The clients are as compatible as the API is: before stable, a marked break (ADR-0149) breaks them too.
Alternatives considered
- Publish only when the document changed, like the SDK. The version of a client is then not the version of the Studio it describes, which is the property that makes it useful.
- Hand-written clients. They drift from the API, which is the problem the generated types solved for the UI.
- Other Java libraries (
okhttp-gson,restclient).nativehas no HTTP dependency beyond Jackson. - Move the web UI to the published client. A rewrite of every caller for no product change.