diff --git a/apps/server/src/routes/suggestions/generate-suggestions.ts b/apps/server/src/routes/suggestions/generate-suggestions.ts
index c8000ce5..8362ab2f 100644
--- a/apps/server/src/routes/suggestions/generate-suggestions.ts
+++ b/apps/server/src/routes/suggestions/generate-suggestions.ts
@@ -6,9 +6,87 @@ import { query } from '@anthropic-ai/claude-agent-sdk';
import type { EventEmitter } from '../../lib/events.js';
import { createLogger } from '@automaker/utils';
import { createSuggestionsOptions } from '../../lib/sdk-options.js';
+import { FeatureLoader } from '../../services/feature-loader.js';
+import { getAppSpecPath } from '@automaker/platform';
+import * as secureFs from '../../lib/secure-fs.js';
const logger = createLogger('Suggestions');
+/**
+ * Extract implemented features from app_spec.txt XML content
+ */
+function extractImplementedFeatures(specContent: string): string[] {
+ const features: string[] = [];
+
+ // Match ... section
+ const implementedMatch = specContent.match(
+ /([\s\S]*?)<\/implemented_features>/
+ );
+
+ if (implementedMatch) {
+ const implementedSection = implementedMatch[1];
+
+ // Extract feature names from ... tags
+ const nameRegex = /(.*?)<\/name>/g;
+ let match;
+
+ while ((match = nameRegex.exec(implementedSection)) !== null) {
+ features.push(match[1].trim());
+ }
+ }
+
+ return features;
+}
+
+/**
+ * Load existing context (app spec and backlog features) to avoid duplicates
+ */
+async function loadExistingContext(projectPath: string): Promise {
+ let context = '';
+
+ // 1. Read app_spec.txt for implemented features
+ try {
+ const appSpecPath = getAppSpecPath(projectPath);
+ const specContent = (await secureFs.readFile(appSpecPath, 'utf-8')) as string;
+
+ if (specContent && specContent.trim().length > 0) {
+ const implementedFeatures = extractImplementedFeatures(specContent);
+
+ if (implementedFeatures.length > 0) {
+ context += '\n\n=== ALREADY IMPLEMENTED FEATURES ===\n';
+ context += 'These features are already implemented in the codebase:\n';
+ implementedFeatures.forEach((feature) => {
+ context += `- ${feature}\n`;
+ });
+ }
+ }
+ } catch (error) {
+ // app_spec.txt doesn't exist or can't be read - that's okay
+ logger.debug('No app_spec.txt found or error reading it:', error);
+ }
+
+ // 2. Load existing features from backlog
+ try {
+ const featureLoader = new FeatureLoader();
+ const features = await featureLoader.getAll(projectPath);
+
+ if (features.length > 0) {
+ context += '\n\n=== EXISTING FEATURES IN BACKLOG ===\n';
+ context += 'These features are already planned or in progress:\n';
+ features.forEach((feature) => {
+ const status = feature.status || 'pending';
+ const title = feature.title || feature.description.substring(0, 50);
+ context += `- ${title} (${status})\n`;
+ });
+ }
+ } catch (error) {
+ // Features directory doesn't exist or can't be read - that's okay
+ logger.debug('No features found or error loading them:', error);
+ }
+
+ return context;
+}
+
/**
* JSON Schema for suggestions output
*/
@@ -51,8 +129,13 @@ export async function generateSuggestions(
performance: 'Analyze this project for performance issues and suggest optimizations.',
};
- const prompt = `${typePrompts[suggestionType] || typePrompts.features}
+ // Load existing context to avoid duplicates
+ const existingContext = await loadExistingContext(projectPath);
+ const prompt = `${typePrompts[suggestionType] || typePrompts.features}
+${existingContext}
+
+${existingContext ? '\nIMPORTANT: Do NOT suggest features that are already implemented or already in the backlog above. Focus on NEW ideas that complement what already exists.\n' : ''}
Look at the codebase and provide 3-5 concrete suggestions.
For each suggestion, provide: