From 63cae19aec1b39364c131982e18667d99643abb4 Mon Sep 17 00:00:00 2001 From: DhanushSantosh Date: Wed, 4 Feb 2026 10:16:35 +0530 Subject: [PATCH] feat(enhance): add project context to prompt enhancements --- .../routes/enhance-prompt/routes/enhance.ts | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/apps/server/src/routes/enhance-prompt/routes/enhance.ts b/apps/server/src/routes/enhance-prompt/routes/enhance.ts index 9045a18d..dbdde007 100644 --- a/apps/server/src/routes/enhance-prompt/routes/enhance.ts +++ b/apps/server/src/routes/enhance-prompt/routes/enhance.ts @@ -10,14 +10,23 @@ import type { Request, Response } from 'express'; import { createLogger } from '@automaker/utils'; import { resolveModelString } from '@automaker/model-resolver'; import { CLAUDE_MODEL_MAP, type ThinkingLevel } from '@automaker/types'; +import { getAppSpecPath } from '@automaker/platform'; import { simpleQuery } from '../../../providers/simple-query-service.js'; import type { SettingsService } from '../../../services/settings-service.js'; import { getPromptCustomization, getProviderByModelId } from '../../../lib/settings-helpers.js'; +import { FeatureLoader } from '../../../services/feature-loader.js'; +import * as secureFs from '../../../lib/secure-fs.js'; import { buildUserPrompt, isValidEnhancementMode, type EnhancementMode, } from '../../../lib/enhancement-prompts.js'; +import { + extractTechnologyStack, + extractXmlElements, + extractXmlSection, + unescapeXml, +} from '../../../lib/xml-extractor.js'; const logger = createLogger('EnhancePrompt'); @@ -53,6 +62,66 @@ interface EnhanceErrorResponse { error: string; } +async function buildProjectContext(projectPath: string): Promise { + const contextBlocks: string[] = []; + + try { + const appSpecPath = getAppSpecPath(projectPath); + const specContent = (await secureFs.readFile(appSpecPath, 'utf-8')) as string; + + const projectName = extractXmlSection(specContent, 'project_name'); + const overview = extractXmlSection(specContent, 'overview'); + const techStack = extractTechnologyStack(specContent); + const coreSection = extractXmlSection(specContent, 'core_capabilities'); + const coreCapabilities = coreSection ? extractXmlElements(coreSection, 'capability') : []; + + const summaryLines: string[] = []; + if (projectName) { + summaryLines.push(`Name: ${unescapeXml(projectName.trim())}`); + } + if (overview) { + summaryLines.push(`Overview: ${unescapeXml(overview.trim())}`); + } + if (techStack.length > 0) { + summaryLines.push(`Tech Stack: ${techStack.join(', ')}`); + } + if (coreCapabilities.length > 0) { + summaryLines.push(`Core Capabilities: ${coreCapabilities.slice(0, 10).join(', ')}`); + } + + if (summaryLines.length > 0) { + contextBlocks.push(`PROJECT CONTEXT:\n${summaryLines.map((line) => `- ${line}`).join('\n')}`); + } + } catch (error) { + logger.debug('No app_spec.txt context available for enhancement', error); + } + + try { + const featureLoader = new FeatureLoader(); + const features = await featureLoader.getAll(projectPath); + const featureTitles = features + .map((feature) => feature.title || feature.name || feature.id) + .filter((title) => Boolean(title)); + + if (featureTitles.length > 0) { + const listed = featureTitles.slice(0, 30).map((title) => `- ${title}`); + contextBlocks.push( + `EXISTING FEATURES (avoid duplicates):\n${listed.join('\n')}${ + featureTitles.length > 30 ? '\n- ...' : '' + }` + ); + } + } catch (error) { + logger.debug('Failed to load existing features for enhancement context', error); + } + + if (contextBlocks.length === 0) { + return null; + } + + return contextBlocks.join('\n\n'); +} + /** * Create the enhance request handler * @@ -122,6 +191,10 @@ export function createEnhanceHandler( // Build the user prompt with few-shot examples const userPrompt = buildUserPrompt(validMode, trimmedText, true); + const projectContext = projectPath ? await buildProjectContext(projectPath) : null; + if (projectContext) { + logger.debug('Including project context in enhancement prompt'); + } // Check if the model is a provider model (like "GLM-4.5-Air") // If so, get the provider config and resolved Claude model @@ -156,7 +229,7 @@ export function createEnhanceHandler( // The system prompt is combined with user prompt since some providers // don't have a separate system prompt concept const result = await simpleQuery({ - prompt: `${systemPrompt}\n\n${userPrompt}`, + prompt: [systemPrompt, projectContext, userPrompt].filter(Boolean).join('\n\n'), model: resolvedModel, cwd: process.cwd(), // Enhancement doesn't need a specific working directory maxTurns: 1,