diff --git a/packages/server/src/server/persisted-config-json-schema.test.ts b/packages/server/src/server/persisted-config-json-schema.test.ts new file mode 100644 index 0000000000..f943f859ec --- /dev/null +++ b/packages/server/src/server/persisted-config-json-schema.test.ts @@ -0,0 +1,78 @@ +import { readFileSync } from "node:fs"; +import Ajv from "ajv"; +import { expect, test } from "vitest"; +import { z } from "zod"; + +import { PersistedConfigSchema } from "./persisted-config.js"; + +const publishedSchema = JSON.parse( + readFileSync( + new URL("../../../website/public/schemas/paseo.config.v1.json", import.meta.url), + "utf8", + ), +); + +test("editors accept the daemon's browser, profile, plugin and metadata configuration", () => { + const config = { + $schema: "https://paseo.sh/schemas/paseo.config.v1.json", + version: 1, + daemon: { + browserTools: { enabled: true }, + terminalProfiles: [], + agentProfiles: [], + }, + pluginsEnabled: true, + plugins: {}, + agents: { + metadataGeneration: { providers: [{ provider: "claude", model: "claude-opus-5" }] }, + }, + }; + expect(PersistedConfigSchema.parse(config)).toEqual(config); + const validate = new Ajv({ allErrors: true, strict: false }).compile(publishedSchema); + const valid = validate(config); + expect(validate.errors).toBeNull(); + expect(valid).toBe(true); +}); + +test("the published schema stays current with the daemon's configuration schema", () => { + const generated = z.toJSONSchema(PersistedConfigSchema, { + target: "draft-07", + unrepresentable: "any", + io: "input", + }); + generated.title = "PaseoConfigV1"; + expect( + publishedSchema, + "Run npm run generate:config-schema --workspace=@getpaseo/server", + ).toEqual(generated); +}); + +test("editors retain the existing proxy configuration help", () => { + const daemon = publishedSchema.properties.daemon.properties; + expect(daemon.trustedProxies.description).toBe( + 'Express trusted proxy setting for X-Forwarded-* headers. Defaults to ["loopback"]. Use true only when the final trusted proxy overwrites client-supplied forwarded headers.', + ); + expect(daemon.serviceProxy.properties.enabled.description).toBe( + "Compatibility shim. false suppresses optional service proxy listen/public layers only; localhost proxying remains enabled.", + ); + expect(daemon.serviceProxy.properties.listen.description).toBe( + "Optional service-only listener address. Presence enables the standalone service proxy listener.", + ); + expect(daemon.serviceProxy.properties.publicBaseUrl.description).toBe( + "Optional public base URL for service host aliases.", + ); +}); + +test.each([ + { daemon: { browserTools: { enabled: "yes" } } }, + { daemon: { terminalProfiles: "default" } }, + { daemon: { agentProfiles: "default" } }, + { pluginsEnabled: "yes" }, + { plugins: [] }, + { agents: { metadataGeneration: { providers: [{ provider: "" }] } } }, + { unknownSetting: true }, +])("editors still reject invalid configuration: %j", (config) => { + expect(PersistedConfigSchema.safeParse(config).success).toBe(false); + const validate = new Ajv({ allErrors: true, strict: false }).compile(publishedSchema); + expect(validate(config)).toBe(false); +}); diff --git a/packages/server/src/server/persisted-config.ts b/packages/server/src/server/persisted-config.ts index 79e3d97218..4998455713 100644 --- a/packages/server/src/server/persisted-config.ts +++ b/packages/server/src/server/persisted-config.ts @@ -237,7 +237,12 @@ export const PersistedConfigSchema = z listen: z.string().optional(), hostnames: z.union([z.literal(true), z.array(z.string())]).optional(), allowedHosts: z.union([z.literal(true), z.array(z.string())]).optional(), - trustedProxies: z.union([z.literal(true), z.array(z.string())]).optional(), + trustedProxies: z + .union([z.literal(true), z.array(z.string())]) + .optional() + .describe( + 'Express trusted proxy setting for X-Forwarded-* headers. Defaults to ["loopback"]. Use true only when the final trusted proxy overwrites client-supplied forwarded headers.', + ), mcp: z .object({ enabled: z.boolean().optional(), @@ -284,9 +289,22 @@ export const PersistedConfigSchema = z // COMPAT(serviceProxyEnabled): added 2026-06-02, remove after 2026-12-02. // Parsed only to suppress optional public/listen layers for old configs; // localhost service proxying remains always enabled. - enabled: z.boolean().optional(), - listen: z.string().optional(), - publicBaseUrl: z.url().optional(), + enabled: z + .boolean() + .optional() + .describe( + "Compatibility shim. false suppresses optional service proxy listen/public layers only; localhost proxying remains enabled.", + ), + listen: z + .string() + .optional() + .describe( + "Optional service-only listener address. Presence enables the standalone service proxy listener.", + ), + publicBaseUrl: z + .url() + .optional() + .describe("Optional public base URL for service host aliases."), }) .strict() .optional(), diff --git a/packages/website/public/schemas/paseo.config.v1.json b/packages/website/public/schemas/paseo.config.v1.json index c1cfbb4b6c..415d307ca0 100644 --- a/packages/website/public/schemas/paseo.config.v1.json +++ b/packages/website/public/schemas/paseo.config.v1.json @@ -1,188 +1,270 @@ { - "$ref": "#/definitions/PaseoConfigV1", - "definitions": { - "PaseoConfigV1": { + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "$schema": { + "type": "string" + }, + "version": { + "type": "number", + "const": 1 + }, + "daemon": { "type": "object", "properties": { - "$schema": { + "listen": { "type": "string" }, - "version": { - "type": "number", - "const": 1 + "hostnames": { + "anyOf": [ + { + "type": "boolean", + "const": true + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] }, - "daemon": { + "allowedHosts": { + "anyOf": [ + { + "type": "boolean", + "const": true + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "trustedProxies": { + "description": "Express trusted proxy setting for X-Forwarded-* headers. Defaults to [\"loopback\"]. Use true only when the final trusted proxy overwrites client-supplied forwarded headers.", + "anyOf": [ + { + "type": "boolean", + "const": true + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "mcp": { "type": "object", "properties": { + "enabled": { + "type": "boolean" + }, + "injectIntoAgents": { + "type": "boolean" + } + }, + "additionalProperties": {} + }, + "browserTools": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + }, + "additionalProperties": {} + }, + "git": { + "type": "object", + "properties": { + "maxProcessesPerSecond": { + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 9007199254740991 + }, + "maxProcessConcurrency": { + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 9007199254740991 + } + }, + "additionalProperties": false + }, + "autoArchiveAfterMerge": { + "type": "boolean" + }, + "enableTerminalAgentHooks": { + "type": "boolean" + }, + "appendSystemPrompt": { + "type": "string" + }, + "terminalProfiles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "command": { + "type": "string" + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "icon": { + "type": "string" + } + }, + "required": ["id", "name", "command"], + "additionalProperties": {} + } + }, + "agentProfiles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "color": { + "type": "string" + }, + "provider": { + "type": "string" + }, + "model": { + "type": "string" + }, + "modeId": { + "type": "string" + }, + "thinkingOptionId": { + "type": "string" + }, + "featureValues": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + }, + "notes": { + "type": "string" + } + }, + "required": ["id", "name", "provider"], + "additionalProperties": {} + } + }, + "cors": { + "type": "object", + "properties": { + "allowedOrigins": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "relay": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "endpoint": { + "type": "string" + }, + "publicEndpoint": { + "type": "string" + }, + "useTls": { + "type": "boolean" + }, + "publicUseTls": { + "type": "boolean" + } + }, + "additionalProperties": false + }, + "serviceProxy": { + "type": "object", + "properties": { + "enabled": { + "description": "Compatibility shim. false suppresses optional service proxy listen/public layers only; localhost proxying remains enabled.", + "type": "boolean" + }, "listen": { + "description": "Optional service-only listener address. Presence enables the standalone service proxy listener.", "type": "string" }, - "hostnames": { - "anyOf": [ - { - "type": "boolean", - "const": true - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "allowedHosts": { - "anyOf": [ - { - "type": "boolean", - "const": true - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "trustedProxies": { - "description": "Express trusted proxy setting for X-Forwarded-* headers. Defaults to [\"loopback\"]. Use true only when the final trusted proxy overwrites client-supplied forwarded headers.", - "anyOf": [ - { - "type": "boolean", - "const": true - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - }, - "mcp": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "injectIntoAgents": { - "type": "boolean" - } - }, - "additionalProperties": true - }, - "git": { - "type": "object", - "properties": { - "maxProcessesPerSecond": { - "type": "integer", - "exclusiveMinimum": 0 - }, - "maxProcessConcurrency": { - "type": "integer", - "exclusiveMinimum": 0 - } - }, - "additionalProperties": false - }, - "autoArchiveAfterMerge": { - "type": "boolean" - }, - "enableTerminalAgentHooks": { - "type": "boolean" - }, - "appendSystemPrompt": { - "type": "string" - }, - "cors": { - "type": "object", - "properties": { - "allowedOrigins": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "relay": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "endpoint": { - "type": "string" - }, - "publicEndpoint": { - "type": "string" - }, - "useTls": { - "type": "boolean" - }, - "publicUseTls": { - "type": "boolean" - } - }, - "additionalProperties": false - }, - "serviceProxy": { - "type": "object", - "properties": { - "enabled": { - "description": "Compatibility shim. false suppresses optional service proxy listen/public layers only; localhost proxying remains enabled.", - "type": "boolean" - }, - "listen": { - "description": "Optional service-only listener address. Presence enables the standalone service proxy listener.", - "type": "string" - }, - "publicBaseUrl": { - "description": "Optional public base URL for service host aliases.", - "type": "string", - "format": "uri" - } - }, - "additionalProperties": false - }, - "auth": { - "type": "object", - "properties": { - "password": { - "type": "string", - "pattern": "^\\$2[aby]\\$\\d{2}\\$[./A-Za-z0-9]{53}$" - } - }, - "additionalProperties": false + "publicBaseUrl": { + "description": "Optional public base URL for service host aliases.", + "type": "string", + "format": "uri" } }, "additionalProperties": false }, - "app": { + "auth": { "type": "object", "properties": { - "baseUrl": { - "type": "string" + "password": { + "type": "string", + "pattern": "^\\$2[aby]\\$\\d{2}\\$[./A-Za-z0-9]{53}$" } }, "additionalProperties": false - }, - "worktrees": { + } + }, + "additionalProperties": false + }, + "app": { + "type": "object", + "properties": { + "baseUrl": { + "type": "string" + } + }, + "additionalProperties": false + }, + "providers": { + "type": "object", + "properties": { + "openai": { "type": "object", "properties": { - "root": { + "apiKey": { "type": "string", "minLength": 1 - } - }, - "additionalProperties": false - }, - "providers": { - "type": "object", - "properties": { - "openai": { + }, + "baseUrl": { + "type": "string", + "minLength": 1 + }, + "stt": { "type": "object", "properties": { "apiKey": { @@ -192,42 +274,18 @@ "baseUrl": { "type": "string", "minLength": 1 - }, - "stt": { - "type": "object", - "properties": { - "apiKey": { - "type": "string", - "minLength": 1 - }, - "baseUrl": { - "type": "string", - "minLength": 1 - } - }, - "additionalProperties": false - }, - "tts": { - "type": "object", - "properties": { - "apiKey": { - "type": "string", - "minLength": 1 - }, - "baseUrl": { - "type": "string", - "minLength": 1 - } - }, - "additionalProperties": false } }, "additionalProperties": false }, - "local": { + "tts": { "type": "object", "properties": { - "modelsDir": { + "apiKey": { + "type": "string", + "minLength": 1 + }, + "baseUrl": { "type": "string", "minLength": 1 } @@ -237,256 +295,466 @@ }, "additionalProperties": false }, - "agents": { + "local": { "type": "object", "properties": { - "providers": { - "type": "object", - "additionalProperties": { + "modelsDir": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "pluginRegistries": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "object", + "properties": { + "authorization": { + "type": "string", + "minLength": 1 + } + }, + "required": ["authorization"] + } + }, + "pluginsEnabled": { + "type": "boolean" + }, + "plugins": { + "type": "object", + "propertyNames": { + "type": "string", + "pattern": "^[a-z][a-z0-9-]*$" + }, + "additionalProperties": { + "oneOf": [ + { + "type": "object", + "properties": { + "source": { + "type": "string", + "const": "directory" + }, + "path": { + "type": "string", + "minLength": 1 + }, + "enabled": { + "type": "boolean" + } + }, + "required": ["source", "path"], + "additionalProperties": false + } + ] + } + }, + "worktrees": { + "type": "object", + "properties": { + "root": { + "type": "string", + "minLength": 1 + }, + "servicePorts": { + "type": "object", + "properties": { + "range": { + "type": "string", + "pattern": "^(\\d{1,5})-(\\d{1,5})$" + }, + "portScript": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "agents": { + "type": "object", + "properties": { + "providers": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "object", + "properties": { + "extends": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "command": { + "minItems": 1, + "type": "array", + "items": { + "type": "string", + "minLength": 1 + } + }, + "env": { "type": "object", - "properties": { - "extends": { - "type": "string" - }, - "label": { - "type": "string" - }, - "description": { - "type": "string" - }, - "command": { - "type": "array", - "items": { + "propertyNames": { + "type": "string" + }, + "additionalProperties": { + "type": "string" + } + }, + "options": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + }, + "params": { + "type": "object", + "propertyNames": { + "type": "string" + }, + "additionalProperties": {} + }, + "models": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "string", "minLength": 1 }, - "minItems": 1 - }, - "env": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "models": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string", - "minLength": 1 - }, - "label": { - "type": "string", - "minLength": 1 - }, - "description": { - "type": "string" - }, - "isDefault": { - "type": "boolean" - }, - "thinkingOptions": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "label": { - "type": "string" - }, - "description": { - "type": "string" - }, - "isDefault": { - "type": "boolean" - } - }, - "required": ["id", "label"], - "additionalProperties": false - } - } - }, - "required": ["id", "label"], - "additionalProperties": false - } - }, - "additionalModels": { - "type": "array", - "items": { - "$ref": "#/definitions/PaseoConfigV1/properties/agents/properties/providers/additionalProperties/properties/models/items" - } - }, - "disallowedTools": { - "type": "array", - "items": { - "type": "string" - } - }, - "paseoTools": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "disabledTools": { - "type": "array", - "items": { - "type": "string" - } - } + "label": { + "type": "string", + "minLength": 1 }, - "additionalProperties": false + "description": { + "type": "string" + }, + "isDefault": { + "type": "boolean" + }, + "thinkingOptions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "isDefault": { + "type": "boolean" + } + }, + "required": ["id", "label"] + } + } }, + "required": ["id", "label"] + } + }, + "additionalModels": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "label": { + "type": "string", + "minLength": 1 + }, + "description": { + "type": "string" + }, + "isDefault": { + "type": "boolean" + }, + "thinkingOptions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "isDefault": { + "type": "boolean" + } + }, + "required": ["id", "label"] + } + } + }, + "required": ["id", "label"] + } + }, + "disallowedTools": { + "type": "array", + "items": { + "type": "string" + } + }, + "paseoTools": { + "type": "object", + "properties": { "enabled": { "type": "boolean" }, - "order": { - "type": "number" + "disabledTools": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "enabled": { + "type": "boolean" + }, + "order": { + "type": "number" + } + } + } + }, + "catalogRefreshTimeoutMs": { + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 2147483647 + }, + "metadataGeneration": { + "type": "object", + "properties": { + "providers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "provider": { + "type": "string", + "minLength": 1 + }, + "model": { + "type": "string", + "minLength": 1 + }, + "thinkingOptionId": { + "type": "string", + "minLength": 1 } }, + "required": ["provider"], "additionalProperties": false } - }, - "catalogRefreshTimeoutMs": { - "type": "integer", - "exclusiveMinimum": 0, - "maximum": 2147483647 } }, "additionalProperties": false }, - "features": { + "skills": { "type": "object", "properties": { - "dictation": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "stt": { + "selection": { + "oneOf": [ + { "type": "object", "properties": { - "provider": { - "allOf": [ - { - "type": "string" - }, - { - "type": "string", - "enum": ["openai", "local"] - } - ] - }, - "model": { + "mode": { "type": "string", - "minLength": 1 - }, - "language": { - "type": "string", - "minLength": 1 - }, - "confidenceThreshold": { - "type": "number" + "const": "all" } }, + "required": ["mode"], "additionalProperties": false + }, + { + "type": "object", + "properties": { + "mode": { + "type": "string", + "const": "custom" + }, + "skills": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": ["mode", "skills"], + "additionalProperties": false + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "features": { + "type": "object", + "properties": { + "dictation": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "stt": { + "type": "object", + "properties": { + "provider": { + "type": "string" + }, + "model": { + "type": "string", + "minLength": 1 + }, + "language": { + "type": "string", + "minLength": 1 + }, + "confidenceThreshold": { + "type": "number" } }, "additionalProperties": false + } + }, + "additionalProperties": false + }, + "voiceMode": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" }, - "voiceMode": { + "llm": { "type": "object", "properties": { - "enabled": { - "type": "boolean" + "provider": { + "type": "string" }, - "llm": { - "type": "object", - "properties": { - "provider": { - "type": "string" - }, - "model": { - "type": "string", - "minLength": 1 - } - }, - "additionalProperties": false - }, - "stt": { - "type": "object", - "properties": { - "provider": { - "$ref": "#/definitions/PaseoConfigV1/properties/features/properties/dictation/properties/stt/properties/provider" - }, - "model": { - "type": "string", - "minLength": 1 - }, - "language": { - "type": "string", - "minLength": 1 - } - }, - "additionalProperties": false - }, - "turnDetection": { - "type": "object", - "properties": { - "provider": { - "$ref": "#/definitions/PaseoConfigV1/properties/features/properties/dictation/properties/stt/properties/provider" - } - }, - "additionalProperties": false - }, - "tts": { - "type": "object", - "properties": { - "provider": { - "$ref": "#/definitions/PaseoConfigV1/properties/features/properties/dictation/properties/stt/properties/provider" - }, - "model": { - "type": "string", - "minLength": 1 - }, - "voice": { - "type": "string", - "enum": ["alloy", "echo", "fable", "onyx", "nova", "shimmer"] - }, - "speakerId": { - "type": "integer" - }, - "speed": { - "type": "number" - } - }, - "additionalProperties": false - } - }, - "additionalProperties": false - }, - "webUi": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "distDir": { + "model": { "type": "string", "minLength": 1 } }, "additionalProperties": false + }, + "stt": { + "type": "object", + "properties": { + "provider": { + "type": "string" + }, + "model": { + "type": "string", + "minLength": 1 + }, + "language": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": false + }, + "turnDetection": { + "type": "object", + "properties": { + "provider": { + "type": "string" + } + }, + "additionalProperties": false + }, + "tts": { + "type": "object", + "properties": { + "provider": { + "type": "string" + }, + "model": { + "type": "string", + "minLength": 1 + }, + "voice": { + "type": "string", + "enum": ["alloy", "echo", "fable", "onyx", "nova", "shimmer"] + }, + "speakerId": { + "type": "integer", + "minimum": -9007199254740991, + "maximum": 9007199254740991 + }, + "speed": { + "type": "number" + } + }, + "additionalProperties": false } }, "additionalProperties": false }, - "log": { + "webUi": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "distDir": { + "type": "string", + "minLength": 1 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + "log": { + "type": "object", + "properties": { + "level": { + "type": "string", + "enum": ["trace", "debug", "info", "warn", "error", "fatal"] + }, + "format": { + "type": "string", + "enum": ["pretty", "json"] + }, + "console": { "type": "object", "properties": { "level": { @@ -496,42 +764,32 @@ "format": { "type": "string", "enum": ["pretty", "json"] + } + }, + "additionalProperties": false + }, + "file": { + "type": "object", + "properties": { + "level": { + "type": "string", + "enum": ["trace", "debug", "info", "warn", "error", "fatal"] }, - "console": { + "path": { + "type": "string", + "minLength": 1 + }, + "rotate": { "type": "object", "properties": { - "level": { - "$ref": "#/definitions/PaseoConfigV1/properties/log/properties/level" - }, - "format": { - "$ref": "#/definitions/PaseoConfigV1/properties/log/properties/format" - } - }, - "additionalProperties": false - }, - "file": { - "type": "object", - "properties": { - "level": { - "$ref": "#/definitions/PaseoConfigV1/properties/log/properties/level" - }, - "path": { + "maxSize": { "type": "string", "minLength": 1 }, - "rotate": { - "type": "object", - "properties": { - "maxSize": { - "type": "string", - "minLength": 1 - }, - "maxFiles": { - "type": "integer", - "exclusiveMinimum": 0 - } - }, - "additionalProperties": false + "maxFiles": { + "type": "integer", + "exclusiveMinimum": 0, + "maximum": 9007199254740991 } }, "additionalProperties": false @@ -543,5 +801,6 @@ "additionalProperties": false } }, - "$schema": "http://json-schema.org/draft-07/schema#" + "additionalProperties": false, + "title": "PaseoConfigV1" } diff --git a/plugins/claude-usage-source/server/stores.test.ts b/plugins/claude-usage-source/server/stores.test.ts index 9859fcc902..093fbf114f 100644 --- a/plugins/claude-usage-source/server/stores.test.ts +++ b/plugins/claude-usage-source/server/stores.test.ts @@ -45,6 +45,8 @@ async function logins(options: Parameters[1]) { async function database(path: string) { await mkdir((await import("node:path")).dirname(path), { recursive: true }); const db = new DatabaseSync(path); + // Create the fixture with one durable commit instead of one per row. + db.exec("BEGIN"); db.exec( "CREATE TABLE auth_credentials (id INTEGER PRIMARY KEY, provider TEXT, credential_type TEXT, data TEXT, disabled_cause TEXT)", ); @@ -78,6 +80,7 @@ async function database(path: string) { null, ); insert.run(5, "anthropic", "oauth", "invalid", null); + db.exec("COMMIT"); db.close(); } diff --git a/plugins/codex-usage-source/server/stores.test.ts b/plugins/codex-usage-source/server/stores.test.ts index 708c289f0f..335985bacd 100644 --- a/plugins/codex-usage-source/server/stores.test.ts +++ b/plugins/codex-usage-source/server/stores.test.ts @@ -39,6 +39,8 @@ async function database(path: string) { await mkdir((await import("node:path")).dirname(path), { recursive: true }); const { DatabaseSync } = await import("node:sqlite"); const db = new DatabaseSync(path); + // Create the fixture with one durable commit instead of one per row. + db.exec("BEGIN"); db.exec( "CREATE TABLE auth_credentials (id INTEGER PRIMARY KEY, provider TEXT, credential_type TEXT, data TEXT, disabled_cause TEXT)", ); @@ -72,6 +74,7 @@ async function database(path: string) { null, ); insert.run(5, "openai-codex", "oauth", "invalid", null); + db.exec("COMMIT"); db.close(); }