fix(backlog-plan): add Cursor-specific prompt with no-file-write instructions

- Import isCursorModel to detect Cursor models
- For Cursor: embed systemPrompt in userPrompt with explicit instructions
- Add "DO NOT write any files" directive for Cursor models
- Prevents Cursor from writing plan to files instead of returning JSON
- Matches pattern used by github validation (validate-issue.ts)

Cursor doesn't support systemPrompt separation like Claude SDK,
so we need to combine prompts and add explicit instructions to
prevent it from using Write/Edit tools and creating files.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Kacper
2026-01-01 19:15:37 +01:00
parent 0e22098652
commit 3b3e61da8d

View File

@@ -7,7 +7,7 @@
import type { EventEmitter } from '../../lib/events.js';
import type { Feature, BacklogPlanResult, BacklogChange, DependencyUpdate } from '@automaker/types';
import { DEFAULT_PHASE_MODELS } from '@automaker/types';
import { DEFAULT_PHASE_MODELS, isCursorModel } from '@automaker/types';
import { FeatureLoader } from '../../services/feature-loader.js';
import { ProviderFactory } from '../../providers/provider-factory.js';
import { extractJsonWithArray } from '../../lib/json-extractor.js';
@@ -123,12 +123,32 @@ export async function generateBacklogPlan(
'[BacklogPlan]'
);
// For Cursor models, we need to combine prompts with explicit instructions
// because Cursor doesn't support systemPrompt separation like Claude SDK
let finalPrompt = userPrompt;
let finalSystemPrompt: string | undefined = systemPrompt;
if (isCursorModel(effectiveModel)) {
logger.info('[BacklogPlan] Using Cursor model - adding explicit no-file-write instructions');
finalPrompt = `${systemPrompt}
CRITICAL INSTRUCTIONS:
1. DO NOT write any files. Return the JSON in your response only.
2. DO NOT use Write, Edit, or any file modification tools.
3. Respond with ONLY a JSON object - no explanations, no markdown, just raw JSON.
4. Your entire response should be valid JSON starting with { and ending with }.
5. No text before or after the JSON object.
${userPrompt}`;
finalSystemPrompt = undefined; // System prompt is now embedded in the user prompt
}
// Execute the query
const stream = provider.executeQuery({
prompt: userPrompt,
prompt: finalPrompt,
model: effectiveModel,
cwd: projectPath,
systemPrompt,
systemPrompt: finalSystemPrompt,
maxTurns: 1,
allowedTools: [], // No tools needed for this
abortController,