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
2 changes: 1 addition & 1 deletion CONTRACT.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Status

This document defines the draft `1.0` core catalog document shape. Catalog and package version `0.4.0` remain pre-1.0 and may change incompatibly before a stable release. Registry publication is outside this repository change. User-imported provider packs use the separate contract in [`PROVIDER_PACKS.md`](./PROVIDER_PACKS.md); their custom-term assets never enter this core catalog.
This document defines the draft `1.0` core catalog document shape. Catalog and package version `0.6.0` remain pre-1.0 and may change incompatibly before a stable release. The Rust catalog is distributed on crates.io; generated npm artifacts are maintained in this repository. User-imported provider packs use the separate contract in [`PROVIDER_PACKS.md`](./PROVIDER_PACKS.md); their custom-term assets never enter this core catalog.

The JSON Schema at [`schemas/catalog.schema.json`](./schemas/catalog.schema.json) is the machine-readable source of truth. [`catalog/catalog.json`](./catalog/catalog.json) is the only source catalog. Generated Cargo and npm copies must not be edited directly. The schema is copied into both packages; `$schema` is an editor-facing canonical repository URL and runtime consumers do not fetch it.

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ edition = "2024"
license = "Apache-2.0"
repository = "https://github.com/stack-sh/theme"
rust-version = "1.85"
version = "0.5.0"
version = "0.6.0"

[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

The draft core catalog contract is defined by [`CONTRACT.md`](./CONTRACT.md) and [`schemas/catalog.schema.json`](./schemas/catalog.schema.json). The separate local-only provider-pack contract is defined by [`PROVIDER_PACKS.md`](./PROVIDER_PACKS.md) and [`schemas/provider-pack.schema.json`](./schemas/provider-pack.schema.json). The canonical core source is [`catalog/catalog.json`](./catalog/catalog.json); Cargo and npm artifacts are generated from that source with one content revision.

The current `0.5.0` catalog contains the core `default`, `light`, and `dark` themes, repository-authored fallbacks for every Stack 1.0 node kind, 30 provider-neutral explicit icons, and versioned host-independent font metrics. The explicit icon catalog covers clients and compute, networking and delivery, data and events, development workflows, security, general collaboration tools, and AI systems. Its identifiers are `api`, `web`, `mobile`, `desktop`, `server`, `container`, `cluster`, `cloud`, `scheduler`, `webhook`, `identity`, `observability`, `gateway`, `load-balancer`, `dns`, `cdn`, `firewall`, `network`, `event`, `stream`, `search`, `analytics`, `repository`, `pipeline`, `secret`, `document`, `task`, `chat`, `email`, and `ai`.
The current `0.6.0` catalog contains the core `default`, `light`, and `dark` themes, repository-authored fallbacks for every Stack 1.0 node kind, 30 provider-neutral explicit icons, and versioned host-independent font metrics. The explicit icon catalog covers clients and compute, networking and delivery, data and events, development workflows, security, general collaboration tools, and AI systems. Its identifiers are `api`, `web`, `mobile`, `desktop`, `server`, `container`, `cluster`, `cloud`, `scheduler`, `webhook`, `identity`, `observability`, `gateway`, `load-balancer`, `dns`, `cdn`, `firewall`, `network`, `event`, `stream`, `search`, `analytics`, `repository`, `pipeline`, `secret`, `document`, `task`, `chat`, `email`, and `ai`.

Provider-specific assets are not bundled. The provider-pack contract lets a CLI or browser validate an archive that the user explicitly selected from the provider's official source, keep it local, preserve the artwork, and carry source and terms notices into diagram output.

Expand All @@ -13,7 +13,7 @@ Provider-specific assets are not bundled. The provider-pack contract lets a CLI
Add the Rust catalog from crates.io with:

```sh
cargo add stack-theme@0.5.0
cargo add stack-theme@0.6.0
```

The package supports Rust 1.85 or newer and includes only the generated catalog API, repository-authored SVG assets, public schemas, package documentation, and the Apache-2.0 license.
Expand Down Expand Up @@ -57,4 +57,4 @@ Repository-authored source code, catalog data, and assets are licensed under the

Third-party fonts, icons, and other assets keep their own licenses and are not relicensed under Apache-2.0. Their provenance and redistribution terms must be recorded in [THIRD_PARTY_LICENSES.md](./THIRD_PARTY_LICENSES.md) before they are committed. Current provider icons are user-imported and are never committed or copied into the Cargo or npm packages.

Maintainers use the [initial publication procedure](./docs/releasing.md) for the first crates.io release.
Maintainers use the [trusted publishing procedure](./docs/releasing.md#ongoing-trusted-publishing) for subsequent crates.io releases. See the [0.6.0 release notes](./docs/releases/v0.6.0.md) for the database card update.
8 changes: 4 additions & 4 deletions catalog/catalog.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/stack-sh/theme/main/schemas/catalog.schema.json",
"schemaVersion": "1.0",
"catalogVersion": "0.5.0",
"catalogVersion": "0.6.0",
"reservedThemeIds": [],
"fallbacks": {
"missingThemeId": "default",
Expand Down Expand Up @@ -81,7 +81,7 @@
"service": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 8000, "fallbackIconId": "kind-service" },
"function": { "shape": "hexagon", "fill": "surfaceMuted", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-function" },
"worker": { "shape": "capsule", "fill": "surface", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 16000, "fallbackIconId": "kind-worker" },
"database": { "shape": "cylinder", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-database" },
"database": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 8000, "fallbackIconId": "kind-database" },
"cache": { "shape": "cylinder", "fill": "surfaceMuted", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-cache" },
"queue": { "shape": "capsule", "fill": "surfaceMuted", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 16000, "fallbackIconId": "kind-queue" },
"storage": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 4000, "fallbackIconId": "kind-storage" },
Expand Down Expand Up @@ -143,7 +143,7 @@
"service": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 8000, "fallbackIconId": "kind-service" },
"function": { "shape": "hexagon", "fill": "surfaceMuted", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-function" },
"worker": { "shape": "capsule", "fill": "surface", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 16000, "fallbackIconId": "kind-worker" },
"database": { "shape": "cylinder", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-database" },
"database": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 8000, "fallbackIconId": "kind-database" },
"cache": { "shape": "cylinder", "fill": "surfaceMuted", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-cache" },
"queue": { "shape": "capsule", "fill": "surfaceMuted", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 16000, "fallbackIconId": "kind-queue" },
"storage": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 4000, "fallbackIconId": "kind-storage" },
Expand Down Expand Up @@ -205,7 +205,7 @@
"service": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 8000, "fallbackIconId": "kind-service" },
"function": { "shape": "hexagon", "fill": "surfaceMuted", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-function" },
"worker": { "shape": "capsule", "fill": "surface", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 16000, "fallbackIconId": "kind-worker" },
"database": { "shape": "cylinder", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-database" },
"database": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 8000, "fallbackIconId": "kind-database" },
"cache": { "shape": "cylinder", "fill": "surfaceMuted", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 0, "fallbackIconId": "kind-cache" },
"queue": { "shape": "capsule", "fill": "surfaceMuted", "stroke": "accent", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 16000, "fallbackIconId": "kind-queue" },
"storage": { "shape": "rounded-rectangle", "fill": "surface", "stroke": "border", "text": "text", "accent": "accent", "cornerRadiusMilliPx": 4000, "fallbackIconId": "kind-storage" },
Expand Down
14 changes: 7 additions & 7 deletions crates/stack-theme/src/generated/catalog.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/stack-sh/theme/main/schemas/catalog.schema.json",
"schemaVersion": "1.0",
"catalogVersion": "0.5.0",
"catalogVersion": "0.6.0",
"reservedThemeIds": [],
"fallbacks": {
"missingThemeId": "default",
Expand Down Expand Up @@ -179,12 +179,12 @@
"fallbackIconId": "kind-worker"
},
"database": {
"shape": "cylinder",
"shape": "rounded-rectangle",
"fill": "surface",
"stroke": "accent",
"text": "text",
"accent": "accent",
"cornerRadiusMilliPx": 0,
"cornerRadiusMilliPx": 8000,
"fallbackIconId": "kind-database"
},
"cache": {
Expand Down Expand Up @@ -1386,12 +1386,12 @@
"fallbackIconId": "kind-worker"
},
"database": {
"shape": "cylinder",
"shape": "rounded-rectangle",
"fill": "surface",
"stroke": "accent",
"text": "text",
"accent": "accent",
"cornerRadiusMilliPx": 0,
"cornerRadiusMilliPx": 8000,
"fallbackIconId": "kind-database"
},
"cache": {
Expand Down Expand Up @@ -2593,12 +2593,12 @@
"fallbackIconId": "kind-worker"
},
"database": {
"shape": "cylinder",
"shape": "rounded-rectangle",
"fill": "surface",
"stroke": "accent",
"text": "text",
"accent": "accent",
"cornerRadiusMilliPx": 0,
"cornerRadiusMilliPx": 8000,
"fallbackIconId": "kind-database"
},
"cache": {
Expand Down
4 changes: 2 additions & 2 deletions crates/stack-theme/src/generated/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Generated by scripts/generate.mjs. Do not edit.
pub const CATALOG_VERSION: &str = "0.5.0";
pub const CATALOG_REVISION: &str = "sha256:3bfd66e1a96628b29b95b7273b54373bcce952f7285aefa506b4255a629eaf53";
pub const CATALOG_VERSION: &str = "0.6.0";
pub const CATALOG_REVISION: &str = "sha256:4d4e9dcda36bf2a5187a233c0be74c9e9302f41d5021e1fa2a73712837ff55c1";

pub fn icon_svg(asset_path: &str) -> Option<&'static str> {
match asset_path {
Expand Down
7 changes: 7 additions & 0 deletions docs/releases/v0.6.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Stack Theme 0.6.0

Database nodes now use a rounded card with an 8 px corner radius in the `default`, `light`, and `dark` themes. The database icon retains the node's identity without a decorative cylinder cap competing with its label or border.

Database colors, typography, icons, and minimum dimensions are unchanged. Cache nodes retain their existing shape. The catalog schema remains `1.0`; layout and rendering remain the engine's responsibility.

The Rust crate and generated catalog share version `0.6.0`. This release does not introduce custom palettes or a new npm distribution channel.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "stack-theme-workspace",
"private": true,
"version": "0.5.0",
"version": "0.6.0",
"workspaces": [
"packages/theme"
],
Expand Down
4 changes: 2 additions & 2 deletions packages/theme/catalog-metadata.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"catalogVersion": "0.5.0",
"catalogRevision": "sha256:3bfd66e1a96628b29b95b7273b54373bcce952f7285aefa506b4255a629eaf53"
"catalogVersion": "0.6.0",
"catalogRevision": "sha256:4d4e9dcda36bf2a5187a233c0be74c9e9302f41d5021e1fa2a73712837ff55c1"
}
18 changes: 9 additions & 9 deletions packages/theme/catalog.generated.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions packages/theme/catalog.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://raw.githubusercontent.com/stack-sh/theme/main/schemas/catalog.schema.json",
"schemaVersion": "1.0",
"catalogVersion": "0.5.0",
"catalogVersion": "0.6.0",
"reservedThemeIds": [],
"fallbacks": {
"missingThemeId": "default",
Expand Down Expand Up @@ -179,12 +179,12 @@
"fallbackIconId": "kind-worker"
},
"database": {
"shape": "cylinder",
"shape": "rounded-rectangle",
"fill": "surface",
"stroke": "accent",
"text": "text",
"accent": "accent",
"cornerRadiusMilliPx": 0,
"cornerRadiusMilliPx": 8000,
"fallbackIconId": "kind-database"
},
"cache": {
Expand Down Expand Up @@ -1386,12 +1386,12 @@
"fallbackIconId": "kind-worker"
},
"database": {
"shape": "cylinder",
"shape": "rounded-rectangle",
"fill": "surface",
"stroke": "accent",
"text": "text",
"accent": "accent",
"cornerRadiusMilliPx": 0,
"cornerRadiusMilliPx": 8000,
"fallbackIconId": "kind-database"
},
"cache": {
Expand Down Expand Up @@ -2593,12 +2593,12 @@
"fallbackIconId": "kind-worker"
},
"database": {
"shape": "cylinder",
"shape": "rounded-rectangle",
"fill": "surface",
"stroke": "accent",
"text": "text",
"accent": "accent",
"cornerRadiusMilliPx": 0,
"cornerRadiusMilliPx": 8000,
"fallbackIconId": "kind-database"
},
"cache": {
Expand Down
2 changes: 1 addition & 1 deletion packages/theme/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stack-sh/theme",
"version": "0.5.0",
"version": "0.6.0",
"description": "Canonical Stack theme catalog contract and embedded catalog data",
"type": "module",
"license": "Apache-2.0",
Expand Down
27 changes: 27 additions & 0 deletions tests/catalog.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,33 @@ test("the complete contract fixture is valid", async () => {
await validateCatalog(fixture);
});

test("database fallbacks use cards with their existing database icons", async () => {
const sourceCatalog = await readJson(
path.join(repositoryRoot, "catalog/catalog.json"),
);
for (const theme of sourceCatalog.themes) {
const database = theme.nodeKindFallbacks.database;
assert.equal(
database.shape,
"rounded-rectangle",
`${theme.id} database shape`,
);
assert.equal(database.cornerRadiusMilliPx, 8000, `${theme.id} database radius`);
assert.equal(
database.cornerRadiusMilliPx,
theme.nodeKindFallbacks.service.cornerRadiusMilliPx,
);
assert.equal(database.fallbackIconId, "kind-database");
assert.deepEqual(
[database.fill, database.stroke, database.text, database.accent],
["surface", "accent", "text", "accent"],
);
assert.ok(theme.icons.some((icon) => icon.id === database.fallbackIconId));
assert.equal(theme.nodeKindFallbacks.cache.shape, "cylinder");
assert.equal(theme.nodeKindFallbacks.cache.cornerRadiusMilliPx, 0);
}
});

const providerPackRoot = path.join(
repositoryRoot,
"tests/fixtures/provider-pack",
Expand Down