diff --git a/src/components/SupabaseIntegrationSwitch.tsx b/src/components/SupabaseIntegrationSwitch.tsx
new file mode 100644
index 0000000..26bb726
--- /dev/null
+++ b/src/components/SupabaseIntegrationSwitch.tsx
@@ -0,0 +1,64 @@
+import { useState, useEffect } from "react";
+import { Switch } from "@/components/ui/switch";
+import { useSettings } from "@/hooks/useSettings";
+import { showSuccess, showError } from "@/lib/toast";
+
+interface SupabaseIntegrationSwitchProps {
+ showToast?: boolean;
+}
+
+export function SupabaseIntegrationSwitch({
+ showToast = true,
+}: SupabaseIntegrationSwitchProps) {
+ const { settings, updateSettings, refreshSettings } = useSettings();
+ const [isEnabled, setIsEnabled] = useState(false);
+ const [isUpdating, setIsUpdating] = useState(false);
+
+ useEffect(() => {
+ if (settings) {
+ setIsEnabled(settings.experiments?.enableSupabaseIntegration || false);
+ }
+ }, [settings]);
+
+ const handleToggle = async () => {
+ try {
+ setIsUpdating(true);
+ const newValue = !isEnabled;
+
+ await updateSettings({
+ experiments: {
+ enableSupabaseIntegration: newValue,
+ },
+ });
+
+ setIsEnabled(newValue);
+ if (showToast) {
+ showSuccess(
+ `Supabase integration ${newValue ? "enabled" : "disabled"}`
+ );
+ }
+ refreshSettings();
+ } catch (error) {
+ console.error("Error toggling Supabase integration:", error);
+ if (showToast) {
+ showError("Failed to update Supabase integration setting");
+ }
+ } finally {
+ setIsUpdating(false);
+ }
+ };
+
+ return (
+
+
+
+
+ );
+}
diff --git a/src/ipc/handlers/chat_stream_handlers.ts b/src/ipc/handlers/chat_stream_handlers.ts
index 4ec5df8..04458ee 100644
--- a/src/ipc/handlers/chat_stream_handlers.ts
+++ b/src/ipc/handlers/chat_stream_handlers.ts
@@ -167,16 +167,18 @@ export function registerChatStreamHandlers() {
messageHistory.pop();
}
let systemPrompt = SYSTEM_PROMPT;
- if (updatedChat.app?.supabaseProjectId) {
- systemPrompt +=
- "\n\n" +
- SUPABASE_AVAILABLE_SYSTEM_PROMPT +
- "\n\n" +
- (await getSupabaseContext({
- supabaseProjectId: updatedChat.app.supabaseProjectId,
- }));
- } else {
- systemPrompt += "\n\n" + SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT;
+ if (readSettings().experiments?.enableSupabaseIntegration) {
+ if (updatedChat.app?.supabaseProjectId) {
+ systemPrompt +=
+ "\n\n" +
+ SUPABASE_AVAILABLE_SYSTEM_PROMPT +
+ "\n\n" +
+ (await getSupabaseContext({
+ supabaseProjectId: updatedChat.app.supabaseProjectId,
+ }));
+ } else {
+ systemPrompt += "\n\n" + SUPABASE_NOT_AVAILABLE_SYSTEM_PROMPT;
+ }
}
const { textStream } = streamText({
maxTokens: 8_000,
diff --git a/src/lib/schemas.ts b/src/lib/schemas.ts
index 5989a77..3164c5e 100644
--- a/src/lib/schemas.ts
+++ b/src/lib/schemas.ts
@@ -87,6 +87,11 @@ export const SupabaseSchema = z.object({
});
export type Supabase = z.infer;
+export const ExperimentsSchema = z.object({
+ enableSupabaseIntegration: z.boolean().optional(),
+});
+export type Experiments = z.infer;
+
/**
* Zod schema for user settings
*/
@@ -100,6 +105,8 @@ export const UserSettingsSchema = z.object({
telemetryConsent: z.enum(["opted_in", "opted_out", "unset"]).optional(),
telemetryUserId: z.string().optional(),
hasRunBefore: z.boolean().optional(),
+
+ experiments: ExperimentsSchema.optional(),
// DEPRECATED.
runtimeMode: RuntimeModeSchema.optional(),
});
diff --git a/src/main/settings.ts b/src/main/settings.ts
index c0bb4fc..397ecc1 100644
--- a/src/main/settings.ts
+++ b/src/main/settings.ts
@@ -16,6 +16,9 @@ const DEFAULT_SETTINGS: UserSettings = {
telemetryConsent: "unset",
telemetryUserId: uuidv4(),
hasRunBefore: false,
+ experiments: {
+ enableSupabaseIntegration: false,
+ },
};
const SETTINGS_FILE = "user-settings.json";
diff --git a/src/pages/app-details.tsx b/src/pages/app-details.tsx
index 8f6c388..9f47e70 100644
--- a/src/pages/app-details.tsx
+++ b/src/pages/app-details.tsx
@@ -29,6 +29,7 @@ import {
} from "@/components/ui/dialog";
import { GitHubConnector } from "@/components/GitHubConnector";
import { SupabaseConnector } from "@/components/SupabaseConnector";
+import { useSettings } from "@/hooks/useSettings";
export default function AppDetailsPage() {
const navigate = useNavigate();
@@ -48,7 +49,7 @@ export default function AppDetailsPage() {
const [newFolderName, setNewFolderName] = useState("");
const [isRenamingFolder, setIsRenamingFolder] = useState(false);
const appBasePath = useAtomValue(appBasePathAtom);
-
+ const { settings } = useSettings();
// Get the appId from search params and find the corresponding app
const appId = search.appId ? Number(search.appId) : null;
const selectedApp = appId ? appsList.find((app) => app.id === appId) : null;
@@ -241,7 +242,9 @@ export default function AppDetailsPage() {
- {appId && }
+ {appId && settings?.experiments?.enableSupabaseIntegration && (
+
+ )}
{/* Rename Dialog */}
diff --git a/src/pages/settings.tsx b/src/pages/settings.tsx
index 116b4ea..d24512e 100644
--- a/src/pages/settings.tsx
+++ b/src/pages/settings.tsx
@@ -6,6 +6,7 @@ import { IpcClient } from "@/ipc/ipc_client";
import { showSuccess, showError } from "@/lib/toast";
import { AutoApproveSwitch } from "@/components/AutoApproveSwitch";
import { TelemetrySwitch } from "@/components/TelemetrySwitch";
+import { SupabaseIntegrationSwitch } from "@/components/SupabaseIntegrationSwitch";
import { useSettings } from "@/hooks/useSettings";
import { Button } from "@/components/ui/button";
import { ArrowLeft } from "lucide-react";
@@ -145,6 +146,22 @@ export default function SettingsPage() {
+ {/* Experiments Section */}
+
+
+ Experiments
+
+
+
+
+
+ Enable integration with Supabase for auth, database and server
+ function support.
+
+
+
+
+
{/* Danger Zone */}