Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { query } from '@anthropic-ai/claude-agent-sdk';
import * as secureFs from '../../lib/secure-fs.js';
import type { EventEmitter } from '../../lib/events.js';
import { createLogger } from '@automaker/utils';
import { DEFAULT_PHASE_MODELS, isCursorModel } from '@automaker/types';
import { DEFAULT_PHASE_MODELS, isCursorModel, stripProviderPrefix } from '@automaker/types';
import { resolvePhaseModel } from '@automaker/model-resolver';
import { createFeatureGenerationOptions } from '../../lib/sdk-options.js';
import { ProviderFactory } from '../../providers/provider-factory.js';
Expand Down Expand Up @@ -124,6 +124,8 @@ IMPORTANT: Do not ask for clarification. The specification is provided above. Ge
logger.info('[FeatureGeneration] Using Cursor provider');

const provider = ProviderFactory.getProviderForModel(model);
// Strip provider prefix - providers expect bare model IDs
const bareModel = stripProviderPrefix(model);

// Add explicit instructions for Cursor to return JSON in response
const cursorPrompt = `${prompt}
Expand All @@ -135,7 +137,7 @@ CRITICAL INSTRUCTIONS:

for await (const msg of provider.executeQuery({
prompt: cursorPrompt,
model,
model: bareModel,
cwd: projectPath,
maxTurns: 250,
allowedTools: ['Read', 'Glob', 'Grep'],
Expand Down
6 changes: 4 additions & 2 deletions apps/server/src/routes/app-spec/generate-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
type SpecOutput,
} from '../../lib/app-spec-format.js';
import { createLogger } from '@automaker/utils';
import { DEFAULT_PHASE_MODELS, isCursorModel } from '@automaker/types';
import { DEFAULT_PHASE_MODELS, isCursorModel, stripProviderPrefix } from '@automaker/types';
import { resolvePhaseModel } from '@automaker/model-resolver';
import { createSpecGenerationOptions } from '../../lib/sdk-options.js';
import { extractJson } from '../../lib/json-extractor.js';
Expand Down Expand Up @@ -118,6 +118,8 @@ ${getStructuredSpecPromptInstruction()}`;
logger.info('[SpecGeneration] Using Cursor provider');

const provider = ProviderFactory.getProviderForModel(model);
// Strip provider prefix - providers expect bare model IDs
const bareModel = stripProviderPrefix(model);

// For Cursor, include the JSON schema in the prompt with clear instructions
// to return JSON in the response (not write to a file)
Expand All @@ -134,7 +136,7 @@ Your entire response should be valid JSON starting with { and ending with }. No

for await (const msg of provider.executeQuery({
prompt: cursorPrompt,
model,
model: bareModel,
cwd: projectPath,
maxTurns: 250,
allowedTools: ['Read', 'Glob', 'Grep'],
Expand Down
11 changes: 9 additions & 2 deletions apps/server/src/routes/backlog-plan/generate-plan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@

import type { EventEmitter } from '../../lib/events.js';
import type { Feature, BacklogPlanResult, BacklogChange, DependencyUpdate } from '@automaker/types';
import { DEFAULT_PHASE_MODELS, isCursorModel, type ThinkingLevel } from '@automaker/types';
import {
DEFAULT_PHASE_MODELS,
isCursorModel,
stripProviderPrefix,
type ThinkingLevel,
} from '@automaker/types';
import { resolvePhaseModel } from '@automaker/model-resolver';
import { FeatureLoader } from '../../services/feature-loader.js';
import { ProviderFactory } from '../../providers/provider-factory.js';
Expand Down Expand Up @@ -120,6 +125,8 @@ export async function generateBacklogPlan(
logger.info('[BacklogPlan] Using model:', effectiveModel);

const provider = ProviderFactory.getProviderForModel(effectiveModel);
// Strip provider prefix - providers expect bare model IDs
const bareModel = stripProviderPrefix(effectiveModel);

// Get autoLoadClaudeMd setting
const autoLoadClaudeMd = await getAutoLoadClaudeMdSetting(
Expand Down Expand Up @@ -151,7 +158,7 @@ ${userPrompt}`;
// Execute the query
const stream = provider.executeQuery({
prompt: finalPrompt,
model: effectiveModel,
model: bareModel,
cwd: projectPath,
systemPrompt: finalSystemPrompt,
maxTurns: 1,
Expand Down
6 changes: 4 additions & 2 deletions apps/server/src/routes/context/routes/describe-file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import type { Request, Response } from 'express';
import { query } from '@anthropic-ai/claude-agent-sdk';
import { createLogger } from '@automaker/utils';
import { DEFAULT_PHASE_MODELS, isCursorModel } from '@automaker/types';
import { DEFAULT_PHASE_MODELS, isCursorModel, stripProviderPrefix } from '@automaker/types';
import { PathNotAllowedError } from '@automaker/platform';
import { resolvePhaseModel } from '@automaker/model-resolver';
import { createCustomOptions } from '../../../lib/sdk-options.js';
Expand Down Expand Up @@ -198,14 +198,16 @@ File: ${fileName}${truncated ? ' (truncated)' : ''}`;
logger.info(`Using Cursor provider for model: ${model}`);

const provider = ProviderFactory.getProviderForModel(model);
// Strip provider prefix - providers expect bare model IDs
const bareModel = stripProviderPrefix(model);

// Build a simple text prompt for Cursor (no multi-part content blocks)
const cursorPrompt = `${instructionText}\n\n--- FILE CONTENT ---\n${contentToAnalyze}`;

let responseText = '';
for await (const msg of provider.executeQuery({
prompt: cursorPrompt,
model,
model: bareModel,
cwd,
maxTurns: 1,
allowedTools: [],
Expand Down
6 changes: 4 additions & 2 deletions apps/server/src/routes/context/routes/describe-image.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import type { Request, Response } from 'express';
import { query } from '@anthropic-ai/claude-agent-sdk';
import { createLogger, readImageAsBase64 } from '@automaker/utils';
import { DEFAULT_PHASE_MODELS, isCursorModel } from '@automaker/types';
import { DEFAULT_PHASE_MODELS, isCursorModel, stripProviderPrefix } from '@automaker/types';
import { resolvePhaseModel } from '@automaker/model-resolver';
import { createCustomOptions } from '../../../lib/sdk-options.js';
import { ProviderFactory } from '../../../providers/provider-factory.js';
Expand Down Expand Up @@ -357,6 +357,8 @@ export function createDescribeImageHandler(
logger.info(`[${requestId}] Using Cursor provider for model: ${model}`);

const provider = ProviderFactory.getProviderForModel(model);
// Strip provider prefix - providers expect bare model IDs
const bareModel = stripProviderPrefix(model);

// Build prompt with image reference for Cursor
// Note: Cursor CLI may not support base64 image blocks directly,
Expand All @@ -367,7 +369,7 @@ export function createDescribeImageHandler(
const queryStart = Date.now();
for await (const msg of provider.executeQuery({
prompt: cursorPrompt,
model,
model: bareModel,
cwd,
maxTurns: 1,
allowedTools: ['Read'], // Allow Read tool so Cursor can read the image if needed
Expand Down
5 changes: 4 additions & 1 deletion apps/server/src/routes/enhance-prompt/routes/enhance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { resolveModelString } from '@automaker/model-resolver';
import {
CLAUDE_MODEL_MAP,
isCursorModel,
stripProviderPrefix,
ThinkingLevel,
getThinkingTokenBudget,
} from '@automaker/types';
Expand Down Expand Up @@ -98,12 +99,14 @@ async function extractTextFromStream(
*/
async function executeWithCursor(prompt: string, model: string): Promise<string> {
const provider = ProviderFactory.getProviderForModel(model);
// Strip provider prefix - providers expect bare model IDs
const bareModel = stripProviderPrefix(model);

let responseText = '';

for await (const msg of provider.executeQuery({
prompt,
model,
model: bareModel,
cwd: process.cwd(), // Enhancement doesn't need a specific working directory
readOnly: true, // Prompt enhancement only generates text, doesn't write files
})) {
Expand Down
6 changes: 4 additions & 2 deletions apps/server/src/routes/github/routes/validate-issue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import type {
LinkedPRInfo,
ThinkingLevel,
} from '@automaker/types';
import { isCursorModel, DEFAULT_PHASE_MODELS } from '@automaker/types';
import { isCursorModel, DEFAULT_PHASE_MODELS, stripProviderPrefix } from '@automaker/types';
import { resolvePhaseModel } from '@automaker/model-resolver';
import { createSuggestionsOptions } from '../../../lib/sdk-options.js';
import { extractJson } from '../../../lib/json-extractor.js';
Expand Down Expand Up @@ -120,6 +120,8 @@ async function runValidation(
logger.info(`Using Cursor provider for validation with model: ${model}`);

const provider = ProviderFactory.getProviderForModel(model);
// Strip provider prefix - providers expect bare model IDs
const bareModel = stripProviderPrefix(model);

// For Cursor, include the system prompt and schema in the user prompt
const cursorPrompt = `${ISSUE_VALIDATION_SYSTEM_PROMPT}
Expand All @@ -137,7 +139,7 @@ ${prompt}`;

for await (const msg of provider.executeQuery({
prompt: cursorPrompt,
model,
model: bareModel,
cwd: projectPath,
readOnly: true, // Issue validation only reads code, doesn't write
})) {
Expand Down
11 changes: 9 additions & 2 deletions apps/server/src/routes/suggestions/generate-suggestions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
import { query } from '@anthropic-ai/claude-agent-sdk';
import type { EventEmitter } from '../../lib/events.js';
import { createLogger } from '@automaker/utils';
import { DEFAULT_PHASE_MODELS, isCursorModel, type ThinkingLevel } from '@automaker/types';
import {
DEFAULT_PHASE_MODELS,
isCursorModel,
stripProviderPrefix,
type ThinkingLevel,
} from '@automaker/types';
import { resolvePhaseModel } from '@automaker/model-resolver';
import { createSuggestionsOptions } from '../../lib/sdk-options.js';
import { extractJsonWithArray } from '../../lib/json-extractor.js';
Expand Down Expand Up @@ -207,6 +212,8 @@ The response will be automatically formatted as structured JSON.`;
logger.info('[Suggestions] Using Cursor provider');

const provider = ProviderFactory.getProviderForModel(model);
// Strip provider prefix - providers expect bare model IDs
const bareModel = stripProviderPrefix(model);

// For Cursor, include the JSON schema in the prompt with clear instructions
const cursorPrompt = `${prompt}
Expand All @@ -222,7 +229,7 @@ Your entire response should be valid JSON starting with { and ending with }. No

for await (const msg of provider.executeQuery({
prompt: cursorPrompt,
model,
model: bareModel,
cwd: projectPath,
maxTurns: 250,
allowedTools: ['Read', 'Glob', 'Grep'],
Expand Down
7 changes: 6 additions & 1 deletion apps/server/src/services/agent-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,15 @@ export class AgentService {
? await getCustomSubagents(this.settingsService, effectiveWorkDir)
: undefined;

// Load project context files (CLAUDE.md, CODE_QUALITY.md, etc.)
// Load project context files (CLAUDE.md, CODE_QUALITY.md, etc.) and memory files
// Use the user's message as task context for smart memory selection
const contextResult = await loadContextFiles({
projectPath: effectiveWorkDir,
fsModule: secureFs as Parameters<typeof loadContextFiles>[0]['fsModule'],
taskContext: {
title: message.substring(0, 200), // Use first 200 chars as title
description: message,
},
});

// When autoLoadClaudeMd is enabled, filter out CLAUDE.md to avoid duplication
Expand Down
Loading