mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-01 08:13:37 +00:00
- Introduced a new `FeatureSuggestionsService` to analyze projects and generate feature suggestions based on the project structure and existing features. - Added IPC handlers for generating and stopping feature suggestions, as well as checking their status. - Implemented a `SpecRegenerationService` to create and regenerate application specifications based on user-defined project overviews and definitions. - Enhanced the UI with a `FeatureSuggestionsDialog` for displaying generated suggestions and allowing users to import them into their project. - Updated the sidebar and board view components to integrate feature suggestions and spec regeneration functionalities, improving project management capabilities. These changes significantly enhance the application's ability to assist users in feature planning and specification management.
270 lines
8.4 KiB
JavaScript
270 lines
8.4 KiB
JavaScript
const { query, AbortError } = require("@anthropic-ai/claude-agent-sdk");
|
|
const promptBuilder = require("./prompt-builder");
|
|
|
|
/**
|
|
* Feature Suggestions Service - Analyzes project and generates feature suggestions
|
|
*/
|
|
class FeatureSuggestionsService {
|
|
constructor() {
|
|
this.runningAnalysis = null;
|
|
}
|
|
|
|
/**
|
|
* Generate feature suggestions by analyzing the project
|
|
*/
|
|
async generateSuggestions(projectPath, sendToRenderer, execution) {
|
|
console.log(
|
|
`[FeatureSuggestions] Generating suggestions for: ${projectPath}`
|
|
);
|
|
|
|
try {
|
|
const abortController = new AbortController();
|
|
execution.abortController = abortController;
|
|
|
|
const options = {
|
|
model: "claude-sonnet-4-20250514",
|
|
systemPrompt: this.getSystemPrompt(),
|
|
maxTurns: 50,
|
|
cwd: projectPath,
|
|
allowedTools: ["Read", "Glob", "Grep", "Bash"],
|
|
permissionMode: "acceptEdits",
|
|
sandbox: {
|
|
enabled: true,
|
|
autoAllowBashIfSandboxed: true,
|
|
},
|
|
abortController: abortController,
|
|
};
|
|
|
|
const prompt = this.buildAnalysisPrompt();
|
|
|
|
sendToRenderer({
|
|
type: "suggestions_progress",
|
|
content: "Starting project analysis...\n",
|
|
});
|
|
|
|
const currentQuery = query({ prompt, options });
|
|
execution.query = currentQuery;
|
|
|
|
let fullResponse = "";
|
|
for await (const msg of currentQuery) {
|
|
if (!execution.isActive()) break;
|
|
|
|
if (msg.type === "assistant" && msg.message?.content) {
|
|
for (const block of msg.message.content) {
|
|
if (block.type === "text") {
|
|
fullResponse += block.text;
|
|
sendToRenderer({
|
|
type: "suggestions_progress",
|
|
content: block.text,
|
|
});
|
|
} else if (block.type === "tool_use") {
|
|
sendToRenderer({
|
|
type: "suggestions_tool",
|
|
tool: block.name,
|
|
input: block.input,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
execution.query = null;
|
|
execution.abortController = null;
|
|
|
|
// Parse the suggestions from the response
|
|
const suggestions = this.parseSuggestions(fullResponse);
|
|
|
|
sendToRenderer({
|
|
type: "suggestions_complete",
|
|
suggestions: suggestions,
|
|
});
|
|
|
|
return {
|
|
success: true,
|
|
suggestions: suggestions,
|
|
};
|
|
} catch (error) {
|
|
if (error instanceof AbortError || error?.name === "AbortError") {
|
|
console.log("[FeatureSuggestions] Analysis aborted");
|
|
if (execution) {
|
|
execution.abortController = null;
|
|
execution.query = null;
|
|
}
|
|
return {
|
|
success: false,
|
|
message: "Analysis aborted",
|
|
suggestions: [],
|
|
};
|
|
}
|
|
|
|
console.error(
|
|
"[FeatureSuggestions] Error generating suggestions:",
|
|
error
|
|
);
|
|
if (execution) {
|
|
execution.abortController = null;
|
|
execution.query = null;
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Parse suggestions from the LLM response
|
|
* Looks for JSON array in the response
|
|
*/
|
|
parseSuggestions(response) {
|
|
try {
|
|
// Try to find JSON array in the response
|
|
// Look for ```json ... ``` blocks first
|
|
const jsonBlockMatch = response.match(/```json\s*([\s\S]*?)```/);
|
|
if (jsonBlockMatch) {
|
|
const parsed = JSON.parse(jsonBlockMatch[1].trim());
|
|
if (Array.isArray(parsed)) {
|
|
return this.validateSuggestions(parsed);
|
|
}
|
|
}
|
|
|
|
// Try to find a raw JSON array
|
|
const jsonArrayMatch = response.match(/\[\s*\{[\s\S]*\}\s*\]/);
|
|
if (jsonArrayMatch) {
|
|
const parsed = JSON.parse(jsonArrayMatch[0]);
|
|
if (Array.isArray(parsed)) {
|
|
return this.validateSuggestions(parsed);
|
|
}
|
|
}
|
|
|
|
console.warn(
|
|
"[FeatureSuggestions] Could not parse suggestions from response"
|
|
);
|
|
return [];
|
|
} catch (error) {
|
|
console.error("[FeatureSuggestions] Error parsing suggestions:", error);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate and normalize suggestions
|
|
*/
|
|
validateSuggestions(suggestions) {
|
|
return suggestions
|
|
.filter((s) => s && typeof s === "object")
|
|
.map((s, index) => ({
|
|
id: `suggestion-${Date.now()}-${index}`,
|
|
category: s.category || "Uncategorized",
|
|
description: s.description || s.title || "No description",
|
|
steps: Array.isArray(s.steps) ? s.steps : [],
|
|
priority: typeof s.priority === "number" ? s.priority : index + 1,
|
|
reasoning: s.reasoning || "",
|
|
}))
|
|
.sort((a, b) => a.priority - b.priority);
|
|
}
|
|
|
|
/**
|
|
* Get the system prompt for feature suggestion analysis
|
|
*/
|
|
getSystemPrompt() {
|
|
return `You are an expert software architect and product manager. Your job is to analyze a codebase and suggest missing features that would improve the application.
|
|
|
|
You should:
|
|
1. Thoroughly analyze the project structure, code, and any existing documentation
|
|
2. Identify what the application does and what features it currently has (look at the .automaker/app_spec.txt file as well if it exists)
|
|
3. Generate a comprehensive list of missing features that would be valuable to users
|
|
4. Prioritize features by impact and complexity
|
|
5. Provide clear, actionable descriptions and implementation steps
|
|
|
|
When analyzing, look at:
|
|
- README files and documentation
|
|
- Package.json, cargo.toml, or similar config files for tech stack
|
|
- Source code structure and organization
|
|
- Existing features and their implementation patterns
|
|
- Common patterns in similar applications
|
|
- User experience improvements
|
|
- Developer experience improvements
|
|
- Performance optimizations
|
|
- Security enhancements
|
|
|
|
You have access to file reading and search tools. Use them to understand the codebase.`;
|
|
}
|
|
|
|
/**
|
|
* Build the prompt for analyzing the project
|
|
*/
|
|
buildAnalysisPrompt() {
|
|
return `Analyze this project and generate a list of suggested features that are missing or would improve the application.
|
|
|
|
**Your Task:**
|
|
|
|
1. First, explore the project structure:
|
|
- Read README.md, package.json, or similar config files
|
|
- Scan the source code directory structure
|
|
- Identify the tech stack and frameworks used
|
|
- Look at existing features and how they're implemented
|
|
|
|
2. Identify what the application does:
|
|
- What is the main purpose?
|
|
- What features are already implemented?
|
|
- What patterns and conventions are used?
|
|
|
|
3. Generate feature suggestions:
|
|
- Think about what's missing compared to similar applications
|
|
- Consider user experience improvements
|
|
- Consider developer experience improvements
|
|
- Think about performance, security, and reliability
|
|
- Consider testing and documentation improvements
|
|
|
|
4. **CRITICAL: Output your suggestions as a JSON array** at the end of your response, formatted like this:
|
|
|
|
\`\`\`json
|
|
[
|
|
{
|
|
"category": "User Experience",
|
|
"description": "Add dark mode support with system preference detection",
|
|
"steps": [
|
|
"Create a ThemeProvider context to manage theme state",
|
|
"Add a toggle component in the settings or header",
|
|
"Implement CSS variables for theme colors",
|
|
"Add localStorage persistence for user preference"
|
|
],
|
|
"priority": 1,
|
|
"reasoning": "Dark mode is a standard feature that improves accessibility and user comfort"
|
|
},
|
|
{
|
|
"category": "Performance",
|
|
"description": "Implement lazy loading for heavy components",
|
|
"steps": [
|
|
"Identify components that are heavy or rarely used",
|
|
"Use React.lazy() and Suspense for code splitting",
|
|
"Add loading states for lazy-loaded components"
|
|
],
|
|
"priority": 2,
|
|
"reasoning": "Improves initial load time and reduces bundle size"
|
|
}
|
|
]
|
|
\`\`\`
|
|
|
|
**Important Guidelines:**
|
|
- Generate at least 10-20 feature suggestions
|
|
- Order them by priority (1 = highest priority)
|
|
- Each feature should have clear, actionable steps
|
|
- Categories should be meaningful (e.g., "User Experience", "Performance", "Security", "Testing", "Documentation", "Developer Experience", "Accessibility", etc.)
|
|
- Be specific about what files might need to be created or modified
|
|
- Consider the existing tech stack and patterns when suggesting implementation steps
|
|
|
|
Begin by exploring the project structure.`;
|
|
}
|
|
|
|
/**
|
|
* Stop the current analysis
|
|
*/
|
|
stop() {
|
|
if (this.runningAnalysis && this.runningAnalysis.abortController) {
|
|
this.runningAnalysis.abortController.abort();
|
|
}
|
|
this.runningAnalysis = null;
|
|
}
|
|
}
|
|
|
|
module.exports = new FeatureSuggestionsService();
|