Support add dependencies as part of approval workflow
This commit is contained in:
@@ -4,6 +4,7 @@ import {
|
|||||||
getDyadRenameTags,
|
getDyadRenameTags,
|
||||||
getDyadDeleteTags,
|
getDyadDeleteTags,
|
||||||
processFullResponseActions,
|
processFullResponseActions,
|
||||||
|
getDyadAddDependencyTags,
|
||||||
} from "../ipc/processors/response_processor";
|
} from "../ipc/processors/response_processor";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import git from "isomorphic-git";
|
import git from "isomorphic-git";
|
||||||
@@ -49,6 +50,40 @@ vi.mock("../db", () => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
describe("getDyadAddDependencyTags", () => {
|
||||||
|
it("should return an empty array when no dyad-add-dependency tags are found", () => {
|
||||||
|
const result = getDyadAddDependencyTags("No dyad-add-dependency tags here");
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return an array of dyad-add-dependency tags", () => {
|
||||||
|
const result = getDyadAddDependencyTags(
|
||||||
|
`<dyad-add-dependency packages="uuid"></dyad-add-dependency>`
|
||||||
|
);
|
||||||
|
expect(result).toEqual(["uuid"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return all the packages in the dyad-add-dependency tags", () => {
|
||||||
|
const result = getDyadAddDependencyTags(
|
||||||
|
`<dyad-add-dependency packages="pkg1 pkg2"></dyad-add-dependency>`
|
||||||
|
);
|
||||||
|
expect(result).toEqual(["pkg1", "pkg2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return all the packages in the dyad-add-dependency tags", () => {
|
||||||
|
const result = getDyadAddDependencyTags(
|
||||||
|
`txt before<dyad-add-dependency packages="pkg1 pkg2"></dyad-add-dependency>text after`
|
||||||
|
);
|
||||||
|
expect(result).toEqual(["pkg1", "pkg2"]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should return all the packages in multiple dyad-add-dependency tags", () => {
|
||||||
|
const result = getDyadAddDependencyTags(
|
||||||
|
`txt before<dyad-add-dependency packages="pkg1 pkg2"></dyad-add-dependency>txt between<dyad-add-dependency packages="pkg3"></dyad-add-dependency>text after`
|
||||||
|
);
|
||||||
|
expect(result).toEqual(["pkg1", "pkg2", "pkg3"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
describe("getDyadWriteTags", () => {
|
describe("getDyadWriteTags", () => {
|
||||||
it("should return an empty array when no dyad-write tags are found", () => {
|
it("should return an empty array when no dyad-write tags are found", () => {
|
||||||
const result = getDyadWriteTags("No dyad-write tags here");
|
const result = getDyadWriteTags("No dyad-write tags here");
|
||||||
@@ -407,7 +442,7 @@ const Index: React.FC = () => {
|
|||||||
export default Index;
|
export default Index;
|
||||||
</dyad-write>
|
</dyad-write>
|
||||||
|
|
||||||
<dyad-add-dependency package="uuid"></dyad-add-dependency>
|
<dyad-add-dependency packages="uuid"></dyad-add-dependency>
|
||||||
|
|
||||||
<dyad-write path="src/types/uuid.d.ts" description="Adding type definitions for uuid">
|
<dyad-write path="src/types/uuid.d.ts" description="Adding type definitions for uuid">
|
||||||
declare module 'uuid' {
|
declare module 'uuid' {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
FileText,
|
FileText,
|
||||||
Check,
|
Check,
|
||||||
Loader2,
|
Loader2,
|
||||||
|
Package,
|
||||||
} 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";
|
||||||
@@ -427,26 +428,54 @@ function ChatInputActions({
|
|||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{proposal.packagesAdded?.length > 0 && (
|
||||||
|
<div className="mb-3">
|
||||||
|
<h4 className="font-semibold mb-1">Packages Added</h4>
|
||||||
|
<ul className="space-y-1">
|
||||||
|
{proposal.packagesAdded.map((pkg, index) => (
|
||||||
|
<li
|
||||||
|
key={index}
|
||||||
|
className="flex items-center space-x-2"
|
||||||
|
onClick={() => {
|
||||||
|
IpcClient.getInstance().openExternalUrl(
|
||||||
|
`https://www.npmjs.com/package/${pkg}`
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Package
|
||||||
|
size={16}
|
||||||
|
className="text-muted-foreground flex-shrink-0"
|
||||||
|
/>
|
||||||
|
<span className="cursor-pointer text-blue-500 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300">
|
||||||
|
{pkg}
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div>
|
{proposal.filesChanged?.length > 0 && (
|
||||||
<h4 className="font-semibold mb-1">Files Changed</h4>
|
<div>
|
||||||
<ul className="space-y-1">
|
<h4 className="font-semibold mb-1">Files Changed</h4>
|
||||||
{proposal.filesChanged.map((file, index) => (
|
<ul className="space-y-1">
|
||||||
<li key={index} className="flex items-center space-x-2">
|
{proposal.filesChanged.map((file, index) => (
|
||||||
<FileText
|
<li key={index} className="flex items-center space-x-2">
|
||||||
size={16}
|
<FileText
|
||||||
className="text-muted-foreground flex-shrink-0"
|
size={16}
|
||||||
/>
|
className="text-muted-foreground flex-shrink-0"
|
||||||
<span title={file.path} className="truncate cursor-default">
|
/>
|
||||||
{file.name}
|
<span title={file.path} className="truncate cursor-default">
|
||||||
</span>
|
{file.name}
|
||||||
<span className="text-muted-foreground text-xs truncate">
|
</span>
|
||||||
- {file.summary}
|
<span className="text-muted-foreground text-xs truncate">
|
||||||
</span>
|
- {file.summary}
|
||||||
</li>
|
</span>
|
||||||
))}
|
</li>
|
||||||
</ul>
|
))}
|
||||||
</div>
|
</ul>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -29,44 +29,9 @@ export const DyadAddDependency: React.FC<DyadAddDependencyProps> = ({
|
|||||||
// Extract package attribute from the node if available
|
// Extract package attribute from the node if available
|
||||||
const packages = node?.properties?.packages?.split(" ") || "";
|
const packages = node?.properties?.packages?.split(" ") || "";
|
||||||
const [isInstalling, setIsInstalling] = useState(false);
|
const [isInstalling, setIsInstalling] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
|
||||||
const selectedChatId = useAtomValue(selectedChatIdAtom);
|
|
||||||
const [messages, setMessages] = useAtom(chatMessagesAtom);
|
|
||||||
const { streamMessage, isStreaming } = useStreamChat();
|
|
||||||
const [isContentVisible, setIsContentVisible] = useState(false);
|
const [isContentVisible, setIsContentVisible] = useState(false);
|
||||||
const hasChildren = !!children;
|
const hasChildren = !!children;
|
||||||
|
|
||||||
const handleInstall = async () => {
|
|
||||||
if (!packages || !selectedChatId) return;
|
|
||||||
|
|
||||||
setIsInstalling(true);
|
|
||||||
setError(null);
|
|
||||||
try {
|
|
||||||
const ipcClient = IpcClient.getInstance();
|
|
||||||
|
|
||||||
await ipcClient.addDependency({
|
|
||||||
chatId: selectedChatId,
|
|
||||||
packages,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Refresh the chat messages
|
|
||||||
const chat = await IpcClient.getInstance().getChat(selectedChatId);
|
|
||||||
setMessages(chat.messages);
|
|
||||||
|
|
||||||
await streamMessage({
|
|
||||||
prompt: `I've installed ${packages.join(", ")}. Keep going.`,
|
|
||||||
chatId: selectedChatId,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
setError("There was an error installing this package.");
|
|
||||||
|
|
||||||
const chat = await IpcClient.getInstance().getChat(selectedChatId);
|
|
||||||
setMessages(chat.messages);
|
|
||||||
} finally {
|
|
||||||
setIsInstalling(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`bg-(--background-lightest) dark:bg-gray-900 hover:bg-(--background-lighter) rounded-lg px-4 py-3 border my-2 ${
|
className={`bg-(--background-lightest) dark:bg-gray-900 hover:bg-(--background-lighter) rounded-lg px-4 py-3 border my-2 ${
|
||||||
@@ -139,27 +104,6 @@ export const DyadAddDependency: React.FC<DyadAddDependencyProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Always show install button if there are no children */}
|
|
||||||
{packages.length > 0 && !hasChildren && (
|
|
||||||
<div className="mt-4 flex justify-center">
|
|
||||||
<Button
|
|
||||||
onClick={(e) => {
|
|
||||||
if (hasChildren) e.stopPropagation();
|
|
||||||
handleInstall();
|
|
||||||
}}
|
|
||||||
disabled={isInstalling || isStreaming}
|
|
||||||
size="default"
|
|
||||||
variant="default"
|
|
||||||
className="font-medium bg-primary/90 flex items-center gap-2 w-full max-w-sm py-4 mt-2 mb-2"
|
|
||||||
>
|
|
||||||
<Download size={16} />
|
|
||||||
{isInstalling ? "Installing..." : "Install packages"}
|
|
||||||
</Button>
|
|
||||||
|
|
||||||
{error && <div className="text-sm text-red-500 mt-2">{error}</div>}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,12 +2,8 @@ import { ipcMain } from "electron";
|
|||||||
import { db } from "../../db";
|
import { db } from "../../db";
|
||||||
import { messages, apps, chats } from "../../db/schema";
|
import { messages, apps, chats } from "../../db/schema";
|
||||||
import { eq } from "drizzle-orm";
|
import { eq } from "drizzle-orm";
|
||||||
import { spawn } from "node:child_process";
|
|
||||||
import { exec } from "node:child_process";
|
|
||||||
import { promisify } from "node:util";
|
|
||||||
import { getDyadAppPath } from "../../paths/paths";
|
import { getDyadAppPath } from "../../paths/paths";
|
||||||
|
import { executeAddDependency } from "../processors/executeAddDependency";
|
||||||
const execPromise = promisify(exec);
|
|
||||||
|
|
||||||
export function registerDependencyHandlers() {
|
export function registerDependencyHandlers() {
|
||||||
ipcMain.handle(
|
ipcMain.handle(
|
||||||
@@ -53,74 +49,11 @@ export function registerDependencyHandlers() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the message content contains the dependency tag
|
executeAddDependency({
|
||||||
const dependencyTagRegex = new RegExp(
|
packages,
|
||||||
`<dyad-add-dependency packages="${packages.join(
|
message,
|
||||||
" "
|
appPath: getDyadAppPath(app.path),
|
||||||
)}">[^<]*</dyad-add-dependency>`,
|
});
|
||||||
"g"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!dependencyTagRegex.test(message.content)) {
|
|
||||||
throw new Error(
|
|
||||||
`Message doesn't contain the dependency tag for packages ${packages.join(
|
|
||||||
", "
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute npm install
|
|
||||||
try {
|
|
||||||
const { stdout, stderr } = await execPromise(
|
|
||||||
`npm install ${packages.join(" ")}`,
|
|
||||||
{
|
|
||||||
cwd: getDyadAppPath(app.path),
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const installResults = stdout + (stderr ? `\n${stderr}` : "");
|
|
||||||
|
|
||||||
// Update the message content with the installation results
|
|
||||||
const updatedContent = message.content.replace(
|
|
||||||
new RegExp(
|
|
||||||
`<dyad-add-dependency packages="${packages.join(
|
|
||||||
" "
|
|
||||||
)}">[^<]*</dyad-add-dependency>`,
|
|
||||||
"g"
|
|
||||||
),
|
|
||||||
`<dyad-add-dependency packages="${packages.join(
|
|
||||||
" "
|
|
||||||
)}">${installResults}</dyad-add-dependency>`
|
|
||||||
);
|
|
||||||
|
|
||||||
// Save the updated message back to the database
|
|
||||||
await db
|
|
||||||
.update(messages)
|
|
||||||
.set({ content: updatedContent })
|
|
||||||
.where(eq(messages.id, message.id));
|
|
||||||
|
|
||||||
// Return undefined implicitly
|
|
||||||
} catch (error: any) {
|
|
||||||
// Update the message with the error
|
|
||||||
const updatedContent = message.content.replace(
|
|
||||||
new RegExp(
|
|
||||||
`<dyad-add-dependency packages="${packages.join(
|
|
||||||
" "
|
|
||||||
)}">[^<]*</dyad-add-dependency>`,
|
|
||||||
"g"
|
|
||||||
),
|
|
||||||
`<dyad-add-dependency packages="${packages.join(" ")}"><dyad-error>${
|
|
||||||
error.message
|
|
||||||
}</dyad-error></dyad-add-dependency>`
|
|
||||||
);
|
|
||||||
|
|
||||||
// Save the updated message back to the database
|
|
||||||
await db
|
|
||||||
.update(messages)
|
|
||||||
.set({ content: updatedContent })
|
|
||||||
.where(eq(messages.id, message.id));
|
|
||||||
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { desc, eq, and, Update } from "drizzle-orm";
|
|||||||
import path from "node:path"; // Import path for basename
|
import path from "node:path"; // Import path for basename
|
||||||
// Import tag parsers
|
// Import tag parsers
|
||||||
import {
|
import {
|
||||||
|
getDyadAddDependencyTags,
|
||||||
getDyadChatSummaryTag,
|
getDyadChatSummaryTag,
|
||||||
getDyadWriteTags,
|
getDyadWriteTags,
|
||||||
processFullResponseActions,
|
processFullResponseActions,
|
||||||
@@ -67,9 +68,14 @@ const getProposalHandler = async (
|
|||||||
// Parse tags directly from message 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 proposalFiles = getDyadWriteTags(messageContent); // Gets { path: string, content: string }[]
|
||||||
|
const packagesAdded = getDyadAddDependencyTags(messageContent);
|
||||||
|
|
||||||
// Check if we have enough information to create a proposal
|
// Check if we have enough information to create a proposal
|
||||||
if (proposalTitle || proposalFiles.length > 0) {
|
if (
|
||||||
|
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
|
||||||
@@ -80,6 +86,7 @@ const getProposalHandler = async (
|
|||||||
path: tag.path,
|
path: tag.path,
|
||||||
summary: tag.description ?? "(no change summary found)", // Generic summary
|
summary: tag.description ?? "(no change summary found)", // Generic summary
|
||||||
})),
|
})),
|
||||||
|
packagesAdded,
|
||||||
};
|
};
|
||||||
logger.log(
|
logger.log(
|
||||||
"Generated code proposal. title=",
|
"Generated code proposal. title=",
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ export interface CreateAppResult {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface Message {
|
export interface Message {
|
||||||
id: string;
|
id: number;
|
||||||
role: "user" | "assistant";
|
role: "user" | "assistant";
|
||||||
content: string;
|
content: string;
|
||||||
approvalState?: "approved" | "rejected";
|
approvalState?: "approved" | "rejected" | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Chat {
|
export interface Chat {
|
||||||
|
|||||||
71
src/ipc/processors/executeAddDependency.ts
Normal file
71
src/ipc/processors/executeAddDependency.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { db } from "../../db";
|
||||||
|
import { messages } from "../../db/schema";
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
import { Message } from "../ipc_types";
|
||||||
|
import { exec } from "node:child_process";
|
||||||
|
import { promisify } from "node:util";
|
||||||
|
|
||||||
|
export const execPromise = promisify(exec);
|
||||||
|
|
||||||
|
export async function executeAddDependency({
|
||||||
|
packages,
|
||||||
|
message,
|
||||||
|
appPath,
|
||||||
|
}: {
|
||||||
|
packages: string[];
|
||||||
|
message: Message;
|
||||||
|
appPath: string;
|
||||||
|
}) {
|
||||||
|
const packageStr = packages.join(" ");
|
||||||
|
try {
|
||||||
|
const { stdout, stderr } = await execPromise(
|
||||||
|
`(pnpm add ${packageStr}) || (npm install ${packageStr})`,
|
||||||
|
{
|
||||||
|
cwd: appPath,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const installResults = stdout + (stderr ? `\n${stderr}` : "");
|
||||||
|
|
||||||
|
// Update the message content with the installation results
|
||||||
|
const updatedContent = message.content.replace(
|
||||||
|
new RegExp(
|
||||||
|
`<dyad-add-dependency packages="${packages.join(
|
||||||
|
" "
|
||||||
|
)}">[^<]*</dyad-add-dependency>`,
|
||||||
|
"g"
|
||||||
|
),
|
||||||
|
`<dyad-add-dependency packages="${packages.join(
|
||||||
|
" "
|
||||||
|
)}">${installResults}</dyad-add-dependency>`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save the updated message back to the database
|
||||||
|
await db
|
||||||
|
.update(messages)
|
||||||
|
.set({ content: updatedContent })
|
||||||
|
.where(eq(messages.id, message.id));
|
||||||
|
|
||||||
|
// Return undefined implicitly
|
||||||
|
} catch (error: any) {
|
||||||
|
// Update the message with the error
|
||||||
|
const updatedContent = message.content.replace(
|
||||||
|
new RegExp(
|
||||||
|
`<dyad-add-dependency packages="${packages.join(
|
||||||
|
" "
|
||||||
|
)}">[^<]*</dyad-add-dependency>`,
|
||||||
|
"g"
|
||||||
|
),
|
||||||
|
`<dyad-add-dependency packages="${packages.join(" ")}"><dyad-error>${
|
||||||
|
error.message
|
||||||
|
}</dyad-error></dyad-add-dependency>`
|
||||||
|
);
|
||||||
|
|
||||||
|
// Save the updated message back to the database
|
||||||
|
await db
|
||||||
|
.update(messages)
|
||||||
|
.set({ content: updatedContent })
|
||||||
|
.where(eq(messages.id, message.id));
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { db } from "../../db";
|
import { db } from "../../db";
|
||||||
import { chats, messages } from "../../db/schema";
|
import { chats, messages } from "../../db/schema";
|
||||||
import { eq } from "drizzle-orm";
|
import { and, eq } from "drizzle-orm";
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
import { getDyadAppPath } from "../../paths/paths";
|
import { getDyadAppPath } from "../../paths/paths";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
@@ -8,6 +8,7 @@ import git from "isomorphic-git";
|
|||||||
import { getGithubUser } from "../handlers/github_handlers";
|
import { getGithubUser } from "../handlers/github_handlers";
|
||||||
import { getGitAuthor } from "../utils/git_author";
|
import { getGitAuthor } from "../utils/git_author";
|
||||||
import log from "electron-log";
|
import log from "electron-log";
|
||||||
|
import { executeAddDependency } from "./executeAddDependency";
|
||||||
|
|
||||||
const logger = log.scope("response_processor");
|
const logger = log.scope("response_processor");
|
||||||
|
|
||||||
@@ -81,11 +82,11 @@ export function getDyadDeleteTags(fullResponse: string): string[] {
|
|||||||
|
|
||||||
export function getDyadAddDependencyTags(fullResponse: string): string[] {
|
export function getDyadAddDependencyTags(fullResponse: string): string[] {
|
||||||
const dyadAddDependencyRegex =
|
const dyadAddDependencyRegex =
|
||||||
/<dyad-add-dependency package="([^"]+)">[^<]*<\/dyad-add-dependency>/g;
|
/<dyad-add-dependency packages="([^"]+)">[^<]*<\/dyad-add-dependency>/g;
|
||||||
let match;
|
let match;
|
||||||
const packages: string[] = [];
|
const packages: string[] = [];
|
||||||
while ((match = dyadAddDependencyRegex.exec(fullResponse)) !== null) {
|
while ((match = dyadAddDependencyRegex.exec(fullResponse)) !== null) {
|
||||||
packages.push(match[1]);
|
packages.push(...match[1].split(" "));
|
||||||
}
|
}
|
||||||
return packages;
|
return packages;
|
||||||
}
|
}
|
||||||
@@ -134,7 +135,36 @@ export async function processFullResponseActions(
|
|||||||
const dyadDeletePaths = getDyadDeleteTags(fullResponse);
|
const dyadDeletePaths = getDyadDeleteTags(fullResponse);
|
||||||
const dyadAddDependencyPackages = getDyadAddDependencyTags(fullResponse);
|
const dyadAddDependencyPackages = getDyadAddDependencyTags(fullResponse);
|
||||||
|
|
||||||
|
const message = await db.query.messages.findFirst({
|
||||||
|
where: and(
|
||||||
|
eq(messages.id, messageId),
|
||||||
|
eq(messages.role, "assistant"),
|
||||||
|
eq(messages.chatId, chatId)
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!message) {
|
||||||
|
logger.error(`No message found for ID: ${messageId}`);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Handle add dependency tags
|
// TODO: Handle add dependency tags
|
||||||
|
if (dyadAddDependencyPackages.length > 0) {
|
||||||
|
await executeAddDependency({
|
||||||
|
packages: dyadAddDependencyPackages,
|
||||||
|
message: message,
|
||||||
|
appPath,
|
||||||
|
});
|
||||||
|
writtenFiles.push("package.json");
|
||||||
|
const pnpmFilename = "pnpm-lock.yaml";
|
||||||
|
if (fs.existsSync(path.join(appPath, pnpmFilename))) {
|
||||||
|
writtenFiles.push(pnpmFilename);
|
||||||
|
}
|
||||||
|
const packageLockFilename = "package-lock.json";
|
||||||
|
if (fs.existsSync(path.join(appPath, packageLockFilename))) {
|
||||||
|
writtenFiles.push(packageLockFilename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process all file writes
|
// Process all file writes
|
||||||
for (const tag of dyadWriteTags) {
|
for (const tag of dyadWriteTags) {
|
||||||
@@ -218,7 +248,8 @@ export async function processFullResponseActions(
|
|||||||
hasChanges =
|
hasChanges =
|
||||||
writtenFiles.length > 0 ||
|
writtenFiles.length > 0 ||
|
||||||
renamedFiles.length > 0 ||
|
renamedFiles.length > 0 ||
|
||||||
deletedFiles.length > 0;
|
deletedFiles.length > 0 ||
|
||||||
|
dyadAddDependencyPackages.length > 0;
|
||||||
if (hasChanges) {
|
if (hasChanges) {
|
||||||
// Stage all written files
|
// Stage all written files
|
||||||
for (const file of writtenFiles) {
|
for (const file of writtenFiles) {
|
||||||
@@ -237,6 +268,10 @@ export async function processFullResponseActions(
|
|||||||
changes.push(`renamed ${renamedFiles.length} file(s)`);
|
changes.push(`renamed ${renamedFiles.length} file(s)`);
|
||||||
if (deletedFiles.length > 0)
|
if (deletedFiles.length > 0)
|
||||||
changes.push(`deleted ${deletedFiles.length} file(s)`);
|
changes.push(`deleted ${deletedFiles.length} file(s)`);
|
||||||
|
if (dyadAddDependencyPackages.length > 0)
|
||||||
|
changes.push(
|
||||||
|
`added ${dyadAddDependencyPackages.join(", ")} package(s)`
|
||||||
|
);
|
||||||
|
|
||||||
// Use chat summary, if provided, or default for commit message
|
// Use chat summary, if provided, or default for commit message
|
||||||
await git.commit({
|
await git.commit({
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ export interface CodeProposal {
|
|||||||
title: string;
|
title: string;
|
||||||
securityRisks: SecurityRisk[];
|
securityRisks: SecurityRisk[];
|
||||||
filesChanged: FileChange[];
|
filesChanged: FileChange[];
|
||||||
|
packagesAdded: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SuggestedAction {
|
export interface SuggestedAction {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ If new code needs to be written (i.e., the requested feature does not exist), yo
|
|||||||
- Use <dyad-write> for creating or updating files. Try to create small, focused files that will be easy to maintain. Use only one <dyad-write> block per file. Do not forget to close the dyad-write tag after writing the file. If you do NOT need to change a file, then do not use the <dyad-write> tag.
|
- Use <dyad-write> for creating or updating files. Try to create small, focused files that will be easy to maintain. Use only one <dyad-write> block per file. Do not forget to close the dyad-write tag after writing the file. If you do NOT need to change a file, then do not use the <dyad-write> tag.
|
||||||
- Use <dyad-rename> for renaming files.
|
- Use <dyad-rename> for renaming files.
|
||||||
- Use <dyad-delete> for removing files.
|
- Use <dyad-delete> for removing files.
|
||||||
- Use <dyad-add-dependency> for installing packages. IF you need to install a package, then STOP. The user will install the package and then continue the conversation.
|
- Use <dyad-add-dependency> for installing packages.
|
||||||
- If the user asks for multiple packages, use <dyad-add-dependency packages="package1 package2 package3"></dyad-add-dependency>
|
- If the user asks for multiple packages, use <dyad-add-dependency packages="package1 package2 package3"></dyad-add-dependency>
|
||||||
- MAKE SURE YOU USE SPACES BETWEEN PACKAGES AND NOT COMMAS.
|
- MAKE SURE YOU USE SPACES BETWEEN PACKAGES AND NOT COMMAS.
|
||||||
- Look carefully at all imports and ensure the files you're importing are present. If any packages need to be installed, use <dyad-add-dependency>.
|
- Look carefully at all imports and ensure the files you're importing are present. If any packages need to be installed, use <dyad-add-dependency>.
|
||||||
|
|||||||
Reference in New Issue
Block a user