Handle rename & deletes in proposal
This commit is contained in:
@@ -10,6 +10,8 @@ import {
|
|||||||
Check,
|
Check,
|
||||||
Loader2,
|
Loader2,
|
||||||
Package,
|
Package,
|
||||||
|
FileX,
|
||||||
|
SendToBack,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useCallback, useEffect, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
@@ -32,6 +34,7 @@ import {
|
|||||||
Proposal,
|
Proposal,
|
||||||
SuggestedAction,
|
SuggestedAction,
|
||||||
ProposalResult,
|
ProposalResult,
|
||||||
|
FileChange,
|
||||||
} from "@/lib/schemas";
|
} from "@/lib/schemas";
|
||||||
import type { Message } from "@/ipc/ipc_types";
|
import type { Message } from "@/ipc/ipc_types";
|
||||||
import { isPreviewOpenAtom } from "@/atoms/viewAtoms";
|
import { isPreviewOpenAtom } from "@/atoms/viewAtoms";
|
||||||
@@ -461,10 +464,7 @@ function ChatInputActions({
|
|||||||
<ul className="space-y-1">
|
<ul className="space-y-1">
|
||||||
{proposal.filesChanged.map((file, index) => (
|
{proposal.filesChanged.map((file, index) => (
|
||||||
<li key={index} className="flex items-center space-x-2">
|
<li key={index} className="flex items-center space-x-2">
|
||||||
<FileText
|
{getIconForFileChange(file)}
|
||||||
size={16}
|
|
||||||
className="text-muted-foreground flex-shrink-0"
|
|
||||||
/>
|
|
||||||
<span title={file.path} className="truncate cursor-default">
|
<span title={file.path} className="truncate cursor-default">
|
||||||
{file.name}
|
{file.name}
|
||||||
</span>
|
</span>
|
||||||
@@ -481,3 +481,20 @@ function ChatInputActions({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getIconForFileChange(file: FileChange) {
|
||||||
|
switch (file.type) {
|
||||||
|
case "write":
|
||||||
|
return (
|
||||||
|
<FileText size={16} className="text-muted-foreground flex-shrink-0" />
|
||||||
|
);
|
||||||
|
case "rename":
|
||||||
|
return (
|
||||||
|
<SendToBack size={16} className="text-muted-foreground flex-shrink-0" />
|
||||||
|
);
|
||||||
|
case "delete":
|
||||||
|
return (
|
||||||
|
<FileX size={16} className="text-muted-foreground flex-shrink-0" />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { ipcMain, type IpcMainInvokeEvent } from "electron";
|
import { ipcMain, type IpcMainInvokeEvent } from "electron";
|
||||||
import type { CodeProposal, ProposalResult } from "@/lib/schemas";
|
import type {
|
||||||
|
CodeProposal,
|
||||||
|
FileChange,
|
||||||
|
ProposalResult,
|
||||||
|
} from "../../lib/schemas";
|
||||||
import { db } from "../../db";
|
import { db } from "../../db";
|
||||||
import { messages } from "../../db/schema";
|
import { messages } from "../../db/schema";
|
||||||
import { desc, eq, and, Update } from "drizzle-orm";
|
import { desc, eq, and, Update } from "drizzle-orm";
|
||||||
@@ -8,6 +12,8 @@ import path from "node:path"; // Import path for basename
|
|||||||
import {
|
import {
|
||||||
getDyadAddDependencyTags,
|
getDyadAddDependencyTags,
|
||||||
getDyadChatSummaryTag,
|
getDyadChatSummaryTag,
|
||||||
|
getDyadDeleteTags,
|
||||||
|
getDyadRenameTags,
|
||||||
getDyadWriteTags,
|
getDyadWriteTags,
|
||||||
processFullResponseActions,
|
processFullResponseActions,
|
||||||
} from "../processors/response_processor";
|
} from "../processors/response_processor";
|
||||||
@@ -65,34 +71,51 @@ const getProposalHandler = async (
|
|||||||
);
|
);
|
||||||
const messageContent = latestAssistantMessage.content;
|
const messageContent = latestAssistantMessage.content;
|
||||||
|
|
||||||
// Parse tags directly from message content
|
|
||||||
const proposalTitle = getDyadChatSummaryTag(messageContent);
|
const proposalTitle = getDyadChatSummaryTag(messageContent);
|
||||||
const proposalFiles = getDyadWriteTags(messageContent); // Gets { path: string, content: string }[]
|
|
||||||
|
const proposalWriteFiles = getDyadWriteTags(messageContent);
|
||||||
|
const proposalRenameFiles = getDyadRenameTags(messageContent);
|
||||||
|
const proposalDeleteFiles = getDyadDeleteTags(messageContent);
|
||||||
|
|
||||||
const packagesAdded = getDyadAddDependencyTags(messageContent);
|
const packagesAdded = getDyadAddDependencyTags(messageContent);
|
||||||
|
|
||||||
|
const filesChanged = [
|
||||||
|
...proposalWriteFiles.map((tag) => ({
|
||||||
|
name: path.basename(tag.path),
|
||||||
|
path: tag.path,
|
||||||
|
summary: tag.description ?? "(no change summary found)", // Generic summary
|
||||||
|
type: "write" as const,
|
||||||
|
})),
|
||||||
|
...proposalRenameFiles.map((tag) => ({
|
||||||
|
name: path.basename(tag.to),
|
||||||
|
path: tag.to,
|
||||||
|
summary: `Rename from ${tag.from} to ${tag.to}`,
|
||||||
|
type: "rename" as const,
|
||||||
|
})),
|
||||||
|
...proposalDeleteFiles.map((tag) => ({
|
||||||
|
name: path.basename(tag),
|
||||||
|
path: tag,
|
||||||
|
summary: `Delete file`,
|
||||||
|
type: "delete" as const,
|
||||||
|
})),
|
||||||
|
];
|
||||||
// Check if we have enough information to create a proposal
|
// Check if we have enough information to create a proposal
|
||||||
if (
|
if (filesChanged.length > 0 || packagesAdded.length > 0) {
|
||||||
proposalTitle ||
|
|
||||||
proposalFiles.length > 0 ||
|
|
||||||
packagesAdded.length > 0
|
|
||||||
) {
|
|
||||||
const proposal: CodeProposal = {
|
const proposal: CodeProposal = {
|
||||||
type: "code-proposal",
|
type: "code-proposal",
|
||||||
// Use parsed title or a default title if summary tag is missing but write tags exist
|
// Use parsed title or a default title if summary tag is missing but write tags exist
|
||||||
title: proposalTitle ?? "Proposed File Changes",
|
title: proposalTitle ?? "Proposed File Changes",
|
||||||
securityRisks: [], // Keep empty
|
securityRisks: [], // Keep empty
|
||||||
filesChanged: proposalFiles.map((tag) => ({
|
filesChanged,
|
||||||
name: path.basename(tag.path),
|
|
||||||
path: tag.path,
|
|
||||||
summary: tag.description ?? "(no change summary found)", // Generic summary
|
|
||||||
})),
|
|
||||||
packagesAdded,
|
packagesAdded,
|
||||||
};
|
};
|
||||||
logger.log(
|
logger.log(
|
||||||
"Generated code proposal. title=",
|
"Generated code proposal. title=",
|
||||||
proposal.title,
|
proposal.title,
|
||||||
"files=",
|
"files=",
|
||||||
proposal.filesChanged.length
|
proposal.filesChanged.length,
|
||||||
|
"packages=",
|
||||||
|
proposal.packagesAdded.length
|
||||||
);
|
);
|
||||||
return { proposal, chatId, messageId }; // Return proposal and messageId
|
return { proposal, chatId, messageId }; // Return proposal and messageId
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ export interface FileChange {
|
|||||||
name: string;
|
name: string;
|
||||||
path: string;
|
path: string;
|
||||||
summary: string;
|
summary: string;
|
||||||
|
type: "write" | "rename" | "delete";
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CodeProposal {
|
export interface CodeProposal {
|
||||||
|
|||||||
Reference in New Issue
Block a user