Support add dependencies as part of approval workflow

This commit is contained in:
Will Chen
2025-04-21 16:07:40 -07:00
parent 02f1db7791
commit b07defc9b8
10 changed files with 212 additions and 157 deletions

View File

@@ -2,12 +2,8 @@ import { ipcMain } from "electron";
import { db } from "../../db";
import { messages, apps, chats } from "../../db/schema";
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";
const execPromise = promisify(exec);
import { executeAddDependency } from "../processors/executeAddDependency";
export function registerDependencyHandlers() {
ipcMain.handle(
@@ -53,74 +49,11 @@ export function registerDependencyHandlers() {
);
}
// Check if the message content contains the dependency tag
const dependencyTagRegex = new RegExp(
`<dyad-add-dependency packages="${packages.join(
" "
)}">[^<]*</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;
}
executeAddDependency({
packages,
message,
appPath: getDyadAppPath(app.path),
});
}
);
}

View File

@@ -6,6 +6,7 @@ import { desc, eq, and, Update } from "drizzle-orm";
import path from "node:path"; // Import path for basename
// Import tag parsers
import {
getDyadAddDependencyTags,
getDyadChatSummaryTag,
getDyadWriteTags,
processFullResponseActions,
@@ -67,9 +68,14 @@ const getProposalHandler = async (
// Parse tags directly from message content
const proposalTitle = getDyadChatSummaryTag(messageContent);
const proposalFiles = getDyadWriteTags(messageContent); // Gets { path: string, content: string }[]
const packagesAdded = getDyadAddDependencyTags(messageContent);
// 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 = {
type: "code-proposal",
// 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,
summary: tag.description ?? "(no change summary found)", // Generic summary
})),
packagesAdded,
};
logger.log(
"Generated code proposal. title=",