Graduate file editing from experimental (#599)

This commit is contained in:
Will Chen
2025-07-08 11:39:46 -07:00
committed by GitHub
parent dfdd267f53
commit a1aee5c2b8
9 changed files with 6041 additions and 42 deletions

View File

@@ -7,6 +7,7 @@ import type {
CreateAppParams,
RenameBranchParams,
CopyAppParams,
EditAppFileReturnType,
} from "../ipc_types";
import fs from "node:fs";
import path from "node:path";
@@ -32,7 +33,10 @@ import fixPath from "fix-path";
import killPort from "kill-port";
import util from "util";
import log from "electron-log";
import { getSupabaseProjectName } from "../../supabase_admin/supabase_management_client";
import {
deploySupabaseFunctions,
getSupabaseProjectName,
} from "../../supabase_admin/supabase_management_client";
import { createLoggedHandler } from "./safe_handle";
import { getLanguageModelProviders } from "../shared/language_model_helpers";
import { startProxy } from "../utils/start_proxy_server";
@@ -41,6 +45,7 @@ import { createFromTemplate } from "./createFromTemplate";
import { gitCommit } from "../utils/git_utils";
import { safeSend } from "../utils/safe_sender";
import { normalizePath } from "../../../shared/normalizePath";
import { isServerFunction } from "@/supabase_admin/supabase_utils";
async function copyDir(
source: string,
@@ -604,7 +609,7 @@ export function registerAppHandlers() {
filePath,
content,
}: { appId: number; filePath: string; content: string },
): Promise<void> => {
): Promise<EditAppFileReturnType> => {
const app = await db.query.apps.findFirst({
where: eq(apps.id, appId),
});
@@ -641,12 +646,26 @@ export function registerAppHandlers() {
message: `Updated ${filePath}`,
});
}
return;
} catch (error: any) {
logger.error(`Error writing file ${filePath} for app ${appId}:`, error);
throw new Error(`Failed to write file: ${error.message}`);
}
if (isServerFunction(filePath) && app.supabaseProjectId) {
try {
await deploySupabaseFunctions({
supabaseProjectId: app.supabaseProjectId,
functionName: path.basename(path.dirname(filePath)),
content: content,
});
} catch (error) {
logger.error(`Error deploying Supabase function ${filePath}:`, error);
return {
warning: `File saved, but failed to deploy Supabase function: ${filePath}: ${error}`,
};
}
}
return {};
},
);

View File

@@ -37,6 +37,7 @@ import type {
ComponentSelection,
AppUpgrade,
ProblemReport,
EditAppFileReturnType,
} from "./ipc_types";
import type { AppChatContext, ProposalResult } from "@/lib/schemas";
import { showError } from "@/lib/toast";
@@ -220,8 +221,8 @@ export class IpcClient {
appId: number,
filePath: string,
content: string,
): Promise<void> {
await this.ipcRenderer.invoke("edit-app-file", {
): Promise<EditAppFileReturnType> {
return this.ipcRenderer.invoke("edit-app-file", {
appId,
filePath,
content,

View File

@@ -248,3 +248,7 @@ export interface AppUpgrade {
manualUpgradeUrl: string;
isNeeded: boolean;
}
export interface EditAppFileReturnType {
warning?: string;
}

View File

@@ -4,6 +4,9 @@ import path from "node:path";
import fsExtra from "fs-extra";
import { generateCuteAppName } from "../../lib/utils";
// Directories to exclude when scanning files
const EXCLUDED_DIRS = ["node_modules", ".git", ".next"];
/**
* Recursively gets all files in a directory, excluding node_modules and .git
* @param dir The directory to scan
@@ -22,8 +25,8 @@ export function getFilesRecursively(dir: string, baseDir: string): string[] {
const res = path.join(dir, dirent.name);
if (dirent.isDirectory()) {
// For directories, concat the results of recursive call
// Exclude node_modules and .git directories
if (dirent.name !== "node_modules" && dirent.name !== ".git") {
// Exclude specified directories
if (!EXCLUDED_DIRS.includes(dirent.name)) {
files.push(...getFilesRecursively(res, baseDir));
}
} else {