Publish server settings schema with release versions#1593
Publish server settings schema with release versions#1593juliusmarminge wants to merge 9 commits intomainfrom
Conversation
- Generate the marketing schema and versioned copies during release version bumps - Move JSON Schema export helper into shared utilities - Update release smoke coverage and schema generation tests
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Object spread ordering may override explicit metadata
- Moved
...schemaspread before the explicit$schema,title, anddescriptionproperties so the explicit metadata always takes precedence.
- Moved
Or push these changes by commenting:
@cursor push b2932708c6
Preview (b2932708c6)
diff --git a/scripts/lib/server-settings-schema.ts b/scripts/lib/server-settings-schema.ts
--- a/scripts/lib/server-settings-schema.ts
+++ b/scripts/lib/server-settings-schema.ts
@@ -21,10 +21,10 @@
}
return {
+ ...schema,
$schema: JSON_SCHEMA_DRAFT_2020_12,
title: "T3 Code Server Settings",
description: "JSON Schema for the server-authoritative settings.json file consumed by T3 Code.",
- ...schema,
};
}You can send follow-ups to this agent here.
- Run the manifest merge script with `process.execPath` instead of `bun` - Keeps the smoke test aligned with the current Node runtime
- Add marketing JSON Schema artifacts for keybindings - Reuse shared JSON schema writer for server settings and keybindings - Preserve top-level `$schema` when rewriting settings
| return { | ||
| $schema: JSON_SCHEMA_DRAFT_2020_12, | ||
| title: options.title, | ||
| description: options.description, | ||
| ...jsonSchema, | ||
| }; |
There was a problem hiding this comment.
🟡 Medium lib/json-schema.ts:24
The spread ...jsonSchema is placed after the explicit $schema, title, and description properties, so if toJsonSchemaObject(schema) returns an object containing any of those keys (common for Effect schemas with annotations), those values will silently override the options.title and options.description parameters passed to the function. Place the spread first so explicit parameters take precedence.
- return {
- $schema: JSON_SCHEMA_DRAFT_2020_12,
- title: options.title,
- description: options.description,
- ...jsonSchema,
- };🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file scripts/lib/json-schema.ts around lines 24-29:
The spread `...jsonSchema` is placed after the explicit `$schema`, `title`, and `description` properties, so if `toJsonSchemaObject(schema)` returns an object containing any of those keys (common for Effect schemas with annotations), those values will silently override the `options.title` and `options.description` parameters passed to the function. Place the spread first so explicit parameters take precedence.
Evidence trail:
scripts/lib/json-schema.ts lines 22-27 (at REVIEWED_COMMIT) show the object literal with `...jsonSchema` spread after explicit properties `$schema`, `title`, `description`. JavaScript object spread semantics (MDN, ECMAScript spec) confirm that later properties override earlier ones, so if `jsonSchema` contains these keys, they will override the explicit values passed via `options`.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Spread ordering lets schema override explicit metadata
- Moved the ...jsonSchema spread before the explicit $schema, title, and description properties so the explicit metadata always wins.
Or push these changes by commenting:
@cursor push 782716bd83
Preview (782716bd83)
diff --git a/scripts/lib/json-schema.ts b/scripts/lib/json-schema.ts
--- a/scripts/lib/json-schema.ts
+++ b/scripts/lib/json-schema.ts
@@ -22,10 +22,10 @@
}
return {
+ ...jsonSchema,
$schema: JSON_SCHEMA_DRAFT_2020_12,
title: options.title,
description: options.description,
- ...jsonSchema,
};
}You can send follow-ups to this agent here.
| title: options.title, | ||
| description: options.description, | ||
| ...jsonSchema, | ||
| }; |
There was a problem hiding this comment.
Spread ordering lets schema override explicit metadata
Medium Severity
In buildJsonSchemaDocument, the ...jsonSchema spread comes after the explicit $schema, title, and description properties. In JavaScript, later properties override earlier ones, so if toJsonSchemaObject returns an object containing title or description (which Effect Schema includes when .annotations({ title: "..." }) is set on the schema), those would silently override the intended values from options. The spread needs to come first so the explicit metadata always wins.
- Add schema descriptions for editor tooling and generated JSON schemas - Update published keybindings and server settings schema docs
- Reflow schema arrays and required lists - Keep published server settings and keybindings schemas normalized
- Centralize settings copy in schema annotations - Reuse schema descriptions in the settings UI - Refresh generated server settings schema output
| const makeTrimmedStringSetting = (description: string) => | ||
| Schema.String.annotate({ description }).pipe( | ||
| Schema.decodeTo(TrimmedString, SchemaTransformation.passthrough()), | ||
| ); |
There was a problem hiding this comment.
Trimming behavior lost via passthrough transformation
Medium Severity
makeTrimmedStringSetting uses Schema.decodeTo(TrimmedString, SchemaTransformation.passthrough()), where passthrough() is an identity transformation that does not apply TrimmedString (Schema.Trim)'s whitespace-trimming decode logic. The old makeBinaryPathSetting started directly from TrimmedString, so strings were trimmed before the fallback check. Now binaryPath and homePath settings pass untrimmed values through, meaning a whitespace-only input like " " would no longer fall back to the default and could cause binary resolution failures.
- Move server settings and keybindings schema URLs to shorter `.json` paths - Update release tooling, docs, and tests to match the new schema locations
- Avoid writing versioned schema snapshots when the latest schema content did not change - Add coverage for keybindings, server settings, and release version updates
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Stale
$schemaref not reset on parse failure- Added the missing
elsebranch to resetschemaDeclarationReftoundefinedwhenUnknownJsondecoding fails, consistent with the file-not-found case.
- Added the missing
Or push these changes by commenting:
@cursor push 0e0490b6b1
Preview (0e0490b6b1)
diff --git a/apps/server/src/serverSettings.ts b/apps/server/src/serverSettings.ts
--- a/apps/server/src/serverSettings.ts
+++ b/apps/server/src/serverSettings.ts
@@ -228,6 +228,8 @@
? valueRecord[SETTINGS_SCHEMA_DECLARATION_KEY]
: undefined;
yield* Ref.set(schemaDeclarationRef, schemaDeclaration);
+ } else {
+ yield* Ref.set(schemaDeclarationRef, undefined);
}
const decoded = Schema.decodeUnknownExit(ServerSettingsJson)(raw);You can send follow-ups to this agent here.
| ? valueRecord[SETTINGS_SCHEMA_DECLARATION_KEY] | ||
| : undefined; | ||
| yield* Ref.set(schemaDeclarationRef, schemaDeclaration); | ||
| } |
There was a problem hiding this comment.
Stale $schema ref not reset on parse failure
Low Severity
When UnknownJson decoding fails (completely malformed file), schemaDeclarationRef is not reset to undefined. On a file-watcher reload, a stale $schema value from a previous successful load survives and gets written into the next updateSettings call, even though the current file no longer contains that declaration. The else branch for rawJson._tag === "Failure" is missing a Ref.set(schemaDeclarationRef, undefined).
|
Bugbot Autofix prepared a fix for the issue found in the latest run.
Or push these changes by commenting: Preview (1b6e8ab339)diff --git a/packages/contracts/src/settings.ts b/packages/contracts/src/settings.ts
--- a/packages/contracts/src/settings.ts
+++ b/packages/contracts/src/settings.ts
@@ -23,10 +23,7 @@
export type SidebarThreadSortOrder = typeof SidebarThreadSortOrder.Type;
export const DEFAULT_SIDEBAR_THREAD_SORT_ORDER: SidebarThreadSortOrder = "updated_at";
-const makeTrimmedStringSetting = (description: string) =>
- Schema.String.annotate({ description }).pipe(
- Schema.decodeTo(TrimmedString, SchemaTransformation.passthrough()),
- );
+const makeTrimmedStringSetting = (description: string) => TrimmedString.annotate({ description });
export const ClientSettingsSchema = Schema.Struct({
confirmThreadArchive: Schema.Boolean.annotate({You can send follow-ups to this agent here. |



Summary
server-settings.schema.jsonand a versioned copy underserver-settings/<version>.schema.jsonduring release/version alignment.@t3tools/shared/schemaJsonand update server git layers to import from there.Testing
buildServerSettingsJsonSchema()andwriteServerSettingsJsonSchemas().updateReleasePackageVersions()writing the latest and versioned schema files.Note
Medium Risk
Updates release/version-bump automation and server settings persistence, so regressions could affect release commits or overwrite
settings.jsonunexpectedly. Core runtime behavior is mostly unchanged, but schema generation and file-writing paths are new/modified.Overview
Publishes JSON Schema artifacts for
settings.jsonandkeybindings.jsonas part of releases. Release/version alignment (scripts/update-release-package-versions.tsand.github/workflows/release.yml) now generates/commits latest schemas underapps/marketing/public/schemas/plus immutable versioned snapshots (only when the latest schema changed).Moves JSON-schema conversion/pretty JSON encoding into
@t3tools/shared/schemaJson, updates Codex/Claude git text-generation layers to use it, and annotates contract schemas so generated docs include field descriptions. The server now preserves an existing top-level$schemainsettings.jsonwhen rewriting, and the web settings UI pulls setting descriptions from schema metadata instead of hard-coded strings, with added tests/smoke checks covering schema generation and release bumps.Written by Cursor Bugbot for commit 32f1d4c. This will update automatically on new commits. Configure here.
Note
Publish JSON Schemas for server settings and keybindings with each release
apps/marketing/public/schemas/.settings/0.0.15.json) are only written when the latest schema changes.settings.ts,keybindings.ts,model.ts,orchestration.ts) so the generated JSON Schemas include human-readable field descriptions.serverSettings.tsnow preserves an existing top-level$schemaproperty insettings.jsonwhen rewriting the file, and switches to a shared pretty-JSON encoder.SettingsPanels.tsxreads field descriptions from schema annotations instead of hard-coded strings.Macroscope summarized 32f1d4c.