diff --git a/.claude/CLAUDE-KNOWLEDGE.md b/.claude/CLAUDE-KNOWLEDGE.md index 175fc2296..c958c395c 100644 --- a/.claude/CLAUDE-KNOWLEDGE.md +++ b/.claude/CLAUDE-KNOWLEDGE.md @@ -544,3 +544,6 @@ A: `Project.createAndSwitch` should leave `backendContext.projectKeys` set to re ## Q: How should backend SMTP SSRF checks be rolled out? A: Keep the real outbound SMTP policy in `apps/backend/src/private/implementation/smtp-egress-policy.ts`, export it through `apps/backend/src/private/index.ts`, and provide a simple `implementation-fallback` function for self-hosters. It should allow only SMTP ports 25, 465, 587, 2465, 2587, and 2525, reject internal IP literals or DNS resolutions, and initially run report-only from `emails-low-level.tsx` via `captureError("smtp-egress-policy-report-only", ...)` before enforcing hard failures. + +## Q: What project-level `sourceOfTruth` config is supported? +A: Project config overrides only support the hosted `sourceOfTruth` shape. Legacy external source-of-truth overrides such as Postgres or Neon are removed by `migrateConfigOverride("project", ...)`, while raw schema validation should reject them. diff --git a/apps/backend/src/lib/ai/models.ts b/apps/backend/src/lib/ai/models.ts index 4c2c638c4..56044906b 100644 --- a/apps/backend/src/lib/ai/models.ts +++ b/apps/backend/src/lib/ai/models.ts @@ -28,11 +28,11 @@ const MODEL_SELECTION_MATRIX: Record< }, smart: { slow: { - authenticated: { modelId: "moonshotai/kimi-k2.6:nitro" }, + authenticated: { modelId: "x-ai/grok-build-0.1" }, unauthenticated: { modelId: "deepseek/deepseek-v4-flash" }, }, fast: { - authenticated: { modelId: "moonshotai/kimi-k2.6:nitro" }, + authenticated: { modelId: "x-ai/grok-build-0.1" }, unauthenticated: { modelId: "deepseek/deepseek-v4-flash:nitro" }, }, }, diff --git a/apps/backend/src/lib/config.tsx b/apps/backend/src/lib/config.tsx index 9c535d095..4c5dc1b45 100644 --- a/apps/backend/src/lib/config.tsx +++ b/apps/backend/src/lib/config.tsx @@ -772,22 +772,18 @@ import.meta.vitest?.test('_validateConfigOverrideSchemaImpl(...)', async ({ expe // Actual configs — advanced cases expect(await validateConfigOverrideSchema(projectConfigSchema, projectSchemaBase, { sourceOfTruth: { - type: 'postgres', - connectionString: 'postgres://user:pass@host:port/db', + type: 'hosted', }, })).toEqual(Result.ok(null)); expect(await validateConfigOverrideSchema(projectConfigSchema, projectSchemaBase, { sourceOfTruth: { type: 'postgres', + connectionString: 'postgres://user:pass@host:port/db', }, })).toEqual(Result.error(deindent` - [WARNING] sourceOfTruth is not matched by any of the provided schemas: + [ERROR] sourceOfTruth is not matched by any of the provided schemas: Schema 0: - sourceOfTruth.type must be one of the following values: hosted - Schema 1: - sourceOfTruth.connectionStrings must be defined - Schema 2: - sourceOfTruth.connectionString must be defined + sourceOfTruth contains unknown properties: connectionString `)); // Dot-notation keys that dot into nothing — detected by simulating the rendering pipeline diff --git a/apps/dashboard/src/components/commands/create-dashboard/dashboard-sandbox-host.tsx b/apps/dashboard/src/components/commands/create-dashboard/dashboard-sandbox-host.tsx index bbb1091a1..350bcc983 100644 --- a/apps/dashboard/src/components/commands/create-dashboard/dashboard-sandbox-host.tsx +++ b/apps/dashboard/src/components/commands/create-dashboard/dashboard-sandbox-host.tsx @@ -179,15 +179,12 @@ function getDependencyScripts(esmVersion: string, esmFallbackVersion: string, da `; } -function escapeScriptContent(code: string): string { - return code - .replace(/<\/script/gi, "<\\/script") - .replace(//g, "--\\>"); +function encodeSourceForJsonScript(code: string): string { + return JSON.stringify(code).replace(/
- - - + + + + + + ${getDependencyScripts(esmVersion, esmFallbackVersion, dashboardUrl)} - + + +