Skip to content

Neon / portal template support #713

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Neon / portal template support #713

wants to merge 1 commit into from

Conversation

wwwillchen
Copy link
Contributor

@wwwillchen wwwillchen commented Jul 25, 2025

TODOs:

  • Do restart when checkout / restore if there is a DB
  • List all branches (branch id, name, date)
  • Allow checking out versions with no DB
  • safeguard to never delete main branches
  • create app hook for neon template
  • weird UX with connector on configure panel
  • tiny neon logo in connector
  • deploy to vercel
  • build forgot password page
  • what about email setup
  • lots of imgix errors
  • edit file - db snapshot
  • DYAD_DISABLE_DB_PUSH
  • update portal doc
  • switch preview branch to be read-only endpoint
  • disable supabase sys prompt if neon is enabled
  • https://payloadcms.com/docs/upload/storage-adapters
  • need to use main branch...

Phase 2?

  • generate DB migrations

cursor[bot]

This comment was marked as outdated.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cubic analysis

10 issues found across 44 files • Review in cubic

React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai to give feedback, ask questions, or re-run the review.

export const NeonConfigure = () => {
const selectedAppId = useAtomValue(selectedAppIdAtom);
const { app } = useLoadApp(selectedAppId);
const [] = useState<string | null>(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useState result is destructured into an empty array, making the hook call pointless and creating unnecessary state.

Prompt for AI agents
Address the following comment on src/components/preview_panel/NeonConfigure.tsx at line 37:

<comment>useState result is destructured into an empty array, making the hook call pointless and creating unnecessary state.</comment>

<file context>
@@ -0,0 +1,183 @@
+import { useQuery } from &quot;@tanstack/react-query&quot;;
+import { useAtomValue } from &quot;jotai&quot;;
+import { useState } from &quot;react&quot;;
+import { Card, CardContent, CardHeader, CardTitle } from &quot;@/components/ui/card&quot;;
+import { Badge } from &quot;@/components/ui/badge&quot;;
+
+import {} from &quot;@/components/ui/alert-dialog&quot;;
+import { Database, GitBranch } from &quot;lucide-react&quot;;
+import { selectedAppIdAtom } from &quot;@/atoms/appAtoms&quot;;
</file context>

@@ -54,6 +57,7 @@ export const messages = sqliteTable("messages", {
// Define relations
export const appsRelations = relations(apps, ({ many }) => ({
chats: many(chats),
versions: many(versions),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

versions is referenced before it is declared, so evaluating relations() will throw a runtime ReferenceError in the module’s top-level code.

Prompt for AI agents
Address the following comment on src/db/schema.ts at line 60:

<comment>versions is referenced before it is declared, so evaluating relations() will throw a runtime ReferenceError in the module’s top-level code.</comment>

<file context>
@@ -54,6 +57,7 @@ export const messages = sqliteTable(&quot;messages&quot;, {
 // Define relations
 export const appsRelations = relations(apps, ({ many }) =&gt; ({
   chats: many(chats),
+  versions: many(versions),
 }));
 
</file context>

setLoading(false);
}
},
[processAppOutput],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appUrlObj is referenced inside this callback but omitted from the dependency array, which can cause the function to use an outdated URL object

Prompt for AI agents
Address the following comment on src/hooks/useRunApp.ts at line 106:

<comment>appUrlObj is referenced inside this callback but omitted from the dependency array, which can cause the function to use an outdated URL object</comment>

<file context>
@@ -45,41 +46,65 @@ export function useRunApp() {
       }
     }
   };
-  const runApp = useCallback(async (appId: number) =&gt; {
-    setLoading(true);
-    try {
-      const ipcClient = IpcClient.getInstance();
-      console.debug(&quot;Running app&quot;, appId);
 
</file context>
Suggested change
[processAppOutput],
[processAppOutput, appUrlObj],

// Process proxy server output
processProxyServerOutput(output);
},
[setAppOutput],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

processProxyServerOutput is used inside this callback but is not listed in the dependency array, so React may work with a stale reference and skip necessary updates

Prompt for AI agents
Address the following comment on src/hooks/useRunApp.ts at line 71:

<comment>processProxyServerOutput is used inside this callback but is not listed in the dependency array, so React may work with a stale reference and skip necessary updates</comment>

<file context>
@@ -45,41 +46,65 @@ export function useRunApp() {
       }
     }
   };
-  const runApp = useCallback(async (appId: number) =&gt; {
-    setLoading(true);
-    try {
-      const ipcClient = IpcClient.getInstance();
-      console.debug(&quot;Running app&quot;, appId);
 
</file context>
Suggested change
[setAppOutput],
[setAppOutput, processProxyServerOutput],

</div>
<div className="overflow-y-auto h-[calc(100%-60px)]">
{versions.length === 0 ? (
<div className="p-4 ">No versions available</div>
) : (
<div className="divide-y divide-border">
{versions.map((version: Version, index) => (
{versions.map((version: Version) => (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rendering cost grows quadratically because each iteration performs versions.findIndex to recover the index that was already available from map’s callback.

Prompt for AI agents
Address the following comment on src/components/chat/VersionPane.tsx at line 121:

<comment>Rendering cost grows quadratically because each iteration performs versions.findIndex to recover the index that was already available from map’s callback.</comment>

<file context>
@@ -94,21 +102,23 @@ export function VersionPane({ isVisible, onClose }: VersionPaneProps) {
   return (
     &lt;div className=&quot;h-full border-t border-2 border-border w-full&quot;&gt;
       &lt;div className=&quot;p-2 border-b border-border flex items-center justify-between&quot;&gt;
-        &lt;h2 className=&quot;text-base font-semibold pl-2&quot;&gt;Version History&lt;/h2&gt;
-        &lt;button
-          onClick={onClose}
-          className=&quot;p-1 hover:bg-(--background-lightest) rounded-md  &quot;
-          aria-label=&quot;Close version pane&quot;
-        &gt;
</file context>
Suggested change
{versions.map((version: Version) => (
{versions.map((version: Version, index) => (

/>
<defs>
<linearGradient
id="a"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard-coded gradient ids "a" and "b" are not unique; rendering multiple NeonSvg components will duplicate these ids in the DOM and can break SVG references.

Prompt for AI agents
Address the following comment on src/components/NeonConnector.tsx at line 133:

<comment>Hard-coded gradient ids &quot;a&quot; and &quot;b&quot; are not unique; rendering multiple NeonSvg components will duplicate these ids in the DOM and can break SVG references.</comment>

<file context>
@@ -0,0 +1,157 @@
+import { useEffect } from &quot;react&quot;;
+import { Button } from &quot;@/components/ui/button&quot;;
+import { IpcClient } from &quot;@/ipc/ipc_client&quot;;
+import { toast } from &quot;sonner&quot;;
+import { useSettings } from &quot;@/hooks/useSettings&quot;;
+
+import { useDeepLink } from &quot;@/contexts/DeepLinkContext&quot;;
+import { ExternalLink } from &quot;lucide-react&quot;;
+import { useTheme } from &quot;@/contexts/ThemeContext&quot;;
</file context>

}
};
handleDeepLink();
}, [lastDeepLink]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refreshSettings is used inside the effect but is missing from the dependency array, which can cause stale state if the hook ever returns a new function.

Prompt for AI agents
Address the following comment on src/components/NeonConnector.tsx at line 25:

<comment>refreshSettings is used inside the effect but is missing from the dependency array, which can cause stale state if the hook ever returns a new function.</comment>

<file context>
@@ -0,0 +1,157 @@
+import { useEffect } from &quot;react&quot;;
+import { Button } from &quot;@/components/ui/button&quot;;
+import { IpcClient } from &quot;@/ipc/ipc_client&quot;;
+import { toast } from &quot;sonner&quot;;
+import { useSettings } from &quot;@/hooks/useSettings&quot;;
+
+import { useDeepLink } from &quot;@/contexts/DeepLinkContext&quot;;
+import { ExternalLink } from &quot;lucide-react&quot;;
+import { useTheme } from &quot;@/contexts/ThemeContext&quot;;
</file context>
Suggested change
}, [lastDeepLink]);
}, [lastDeepLink, refreshSettings]);

// Send message to renderer to trigger re-render
mainWindow?.webContents.send("deep-link-received", {
type: parsed.hostname,
url,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sensitive OAuth tokens are forwarded to the renderer via IPC, exposing credentials outside the trusted main process (This reflects feedback from previous reviews about avoiding accidental leakage of secrets to the renderer).

Prompt for AI agents
Address the following comment on src/main.ts at line 227:

<comment>Sensitive OAuth tokens are forwarded to the renderer via IPC, exposing credentials outside the trusted main process (This reflects feedback from previous reviews about avoiding accidental leakage of secrets to the renderer).</comment>

<file context>
@@ -208,6 +209,25 @@ function handleDeepLinkReturn(url: string) {
     );
     return;
   }
+  if (parsed.hostname === &quot;neon-oauth-return&quot;) {
+    const token = parsed.searchParams.get(&quot;token&quot;);
+    const refreshToken = parsed.searchParams.get(&quot;refreshToken&quot;);
+    const expiresIn = Number(parsed.searchParams.get(&quot;expiresIn&quot;));
+    if (!token || !refreshToken || !expiresIn) {
+      dialog.showErrorBox(
</file context>

import { eq } from "drizzle-orm";
import { ipcMain } from "electron";
import { EndpointType } from "@neondatabase/api-client";
import { retryOnLocked } from "../utils/retryOnLocked";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mutual imports between neon_handlers.ts and retryOnLocked.ts create a circular dependency (neon_handlers -> retryOnLocked -> neon_handlers). Although ES modules allow cycles, this pattern risks runtime "undefined is not a function" errors if retryOnLocked is executed before neon_handlers finishes evaluating, and complicates maintainability.

Prompt for AI agents
Address the following comment on src/ipc/handlers/neon_handlers.ts at line 22:

<comment>The mutual imports between neon_handlers.ts and retryOnLocked.ts create a circular dependency (neon_handlers -&gt; retryOnLocked -&gt; neon_handlers). Although ES modules allow cycles, this pattern risks runtime &quot;undefined is not a function&quot; errors if retryOnLocked is executed before neon_handlers finishes evaluating, and complicates maintainability.</comment>

<file context>
@@ -0,0 +1,263 @@
+import log from &quot;electron-log&quot;;
+
+import { createTestOnlyLoggedHandler } from &quot;./safe_handle&quot;;
+import { handleNeonOAuthReturn } from &quot;../../neon_admin/neon_return_handler&quot;;
+import {
+  getNeonClient,
+  getNeonErrorMessage,
+  getNeonOrganizationId,
+} from &quot;../../neon_admin/neon_management_client&quot;;
</file context>

}) {
// Given the connection uri, update the env var for POSTGRES_URL
const envVars = parseEnvFile(await readEnvFile({ appPath }));
for (const envVar of envVars) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updatePostgresUrlEnvVar rewrites the file without inserting POSTGRES_URL when it is absent, so the intended update may be silently skipped

Prompt for AI agents
Address the following comment on src/ipc/utils/app_env_var_utils.ts at line 26:

<comment>updatePostgresUrlEnvVar rewrites the file without inserting POSTGRES_URL when it is absent, so the intended update may be silently skipped</comment>

<file context>
@@ -3,7 +3,58 @@
  * Environment variables are sensitive and should not be logged.
  */
 
+import { getDyadAppPath } from &quot;@/paths/paths&quot;;
 import { EnvVar } from &quot;../ipc_types&quot;;
+import path from &quot;path&quot;;
+import fs from &quot;fs&quot;;
+
+export const ENV_FILE_NAME = &quot;.env.local&quot;;
</file context>

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

Add mini-store template

refactor

ipc handlers / settings / basic UI

create app button

create app flow

support y/n and basic neon setup flow

child branches

wip

wip

changes

fix

DB more progress

restart app when db, and better loading screens

gracefully handle checking out versions wihthout db

polish ui

better warning screen

make user friendly

clean up db

straighten out

clean up neon ui

wip

delete-able branches

simple graph viz

everything working

clean

DB migration

more changes

minor clean

DYAD_DISABLE_DB_PUSH

more neon

Revert "more neon"

This reverts commit 6e209f7.

proper version semantics

skip supabase available sys prompt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant