mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 21:03:08 +00:00
feat: load context files as system prompt for higher priority
Context files from .automaker/context/ (CLAUDE.md, CODE_QUALITY.md, etc.) are now passed as system prompt instead of prepending to user prompt. This ensures the agent follows project-specific rules like package manager preferences (pnpm vs npm) and coding conventions. Changes: - Add getContextDir() utility to automaker-paths.ts - Add loadContextFiles() method to load .md/.txt files from context dir - Pass context as systemPrompt in executeFeature() and followUpFeature() - Add debug logging to confirm system prompt is provided 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,13 @@ export function getImagesDir(projectPath: string): string {
|
|||||||
return path.join(getAutomakerDir(projectPath), "images");
|
return path.join(getAutomakerDir(projectPath), "images");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the context files directory for a project (user-added context files)
|
||||||
|
*/
|
||||||
|
export function getContextDir(projectPath: string): string {
|
||||||
|
return path.join(getAutomakerDir(projectPath), "context");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the worktrees metadata directory for a project
|
* Get the worktrees metadata directory for a project
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { isAbortError, classifyError } from "../lib/error-handler.js";
|
|||||||
import { resolveDependencies, areDependenciesSatisfied } from "../lib/dependency-resolver.js";
|
import { resolveDependencies, areDependenciesSatisfied } from "../lib/dependency-resolver.js";
|
||||||
import type { Feature } from "./feature-loader.js";
|
import type { Feature } from "./feature-loader.js";
|
||||||
import { FeatureLoader } from "./feature-loader.js";
|
import { FeatureLoader } from "./feature-loader.js";
|
||||||
import { getFeatureDir, getAutomakerDir, getFeaturesDir } from "../lib/automaker-paths.js";
|
import { getFeatureDir, getAutomakerDir, getFeaturesDir, getContextDir } from "../lib/automaker-paths.js";
|
||||||
|
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
|
|
||||||
@@ -559,6 +559,9 @@ export class AutoModeService {
|
|||||||
|
|
||||||
// Build the prompt - use continuation prompt if provided (for recovery after plan approval)
|
// Build the prompt - use continuation prompt if provided (for recovery after plan approval)
|
||||||
let prompt: string;
|
let prompt: string;
|
||||||
|
// Load project context files (CLAUDE.md, CODE_QUALITY.md, etc.) - passed as system prompt
|
||||||
|
const contextFiles = await this.loadContextFiles(projectPath);
|
||||||
|
|
||||||
if (options?.continuationPrompt) {
|
if (options?.continuationPrompt) {
|
||||||
// Continuation prompt is used when recovering from a plan approval
|
// Continuation prompt is used when recovering from a plan approval
|
||||||
// The plan was already approved, so skip the planning phase
|
// The plan was already approved, so skip the planning phase
|
||||||
@@ -592,6 +595,7 @@ export class AutoModeService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Run the agent with the feature's model and images
|
// Run the agent with the feature's model and images
|
||||||
|
// Context files are passed as system prompt for higher priority
|
||||||
await this.runAgent(
|
await this.runAgent(
|
||||||
workDir,
|
workDir,
|
||||||
featureId,
|
featureId,
|
||||||
@@ -604,6 +608,7 @@ export class AutoModeService {
|
|||||||
projectPath,
|
projectPath,
|
||||||
planningMode: feature.planningMode,
|
planningMode: feature.planningMode,
|
||||||
requirePlanApproval: feature.requirePlanApproval,
|
requirePlanApproval: feature.requirePlanApproval,
|
||||||
|
systemPrompt: contextFiles || undefined,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -756,6 +761,9 @@ export class AutoModeService {
|
|||||||
// No previous context
|
// No previous context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load project context files (CLAUDE.md, CODE_QUALITY.md, etc.) - passed as system prompt
|
||||||
|
const contextFiles = await this.loadContextFiles(projectPath);
|
||||||
|
|
||||||
// Build complete prompt with feature info, previous context, and follow-up instructions
|
// Build complete prompt with feature info, previous context, and follow-up instructions
|
||||||
let fullPrompt = `## Follow-up on Feature Implementation
|
let fullPrompt = `## Follow-up on Feature Implementation
|
||||||
|
|
||||||
@@ -874,6 +882,7 @@ Address the follow-up instructions above. Review the previous work and make the
|
|||||||
// Use fullPrompt (already built above) with model and all images
|
// Use fullPrompt (already built above) with model and all images
|
||||||
// Note: Follow-ups skip planning mode - they continue from previous work
|
// Note: Follow-ups skip planning mode - they continue from previous work
|
||||||
// Pass previousContext so the history is preserved in the output file
|
// Pass previousContext so the history is preserved in the output file
|
||||||
|
// Context files are passed as system prompt for higher priority
|
||||||
await this.runAgent(
|
await this.runAgent(
|
||||||
workDir,
|
workDir,
|
||||||
featureId,
|
featureId,
|
||||||
@@ -886,6 +895,7 @@ Address the follow-up instructions above. Review the previous work and make the
|
|||||||
projectPath,
|
projectPath,
|
||||||
planningMode: 'skip', // Follow-ups don't require approval
|
planningMode: 'skip', // Follow-ups don't require approval
|
||||||
previousContent: previousContext || undefined,
|
previousContent: previousContext || undefined,
|
||||||
|
systemPrompt: contextFiles || undefined,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1084,6 +1094,65 @@ Address the follow-up instructions above. Review the previous work and make the
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load context files from .automaker/context/ directory
|
||||||
|
* These are user-defined context files (CLAUDE.md, CODE_QUALITY.md, etc.)
|
||||||
|
* that provide project-specific rules and guidelines for the agent.
|
||||||
|
*/
|
||||||
|
private async loadContextFiles(projectPath: string): Promise<string> {
|
||||||
|
// Use path.resolve for cross-platform absolute path handling
|
||||||
|
const contextDir = path.resolve(getContextDir(projectPath));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check if directory exists first
|
||||||
|
await fs.access(contextDir);
|
||||||
|
|
||||||
|
const files = await fs.readdir(contextDir);
|
||||||
|
// Filter for text-based context files (case-insensitive for Windows)
|
||||||
|
const textFiles = files.filter((f) => {
|
||||||
|
const lower = f.toLowerCase();
|
||||||
|
return lower.endsWith(".md") || lower.endsWith(".txt");
|
||||||
|
});
|
||||||
|
|
||||||
|
if (textFiles.length === 0) return "";
|
||||||
|
|
||||||
|
const contents: string[] = [];
|
||||||
|
for (const file of textFiles) {
|
||||||
|
// Use path.join for cross-platform path construction
|
||||||
|
const filePath = path.join(contextDir, file);
|
||||||
|
const content = await fs.readFile(filePath, "utf-8");
|
||||||
|
contents.push(`## ${file}\n\n${content}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[AutoMode] Loaded ${textFiles.length} context file(s): ${textFiles.join(", ")}`
|
||||||
|
);
|
||||||
|
|
||||||
|
return `# ⚠️ CRITICAL: Project Context Files - READ AND FOLLOW STRICTLY
|
||||||
|
|
||||||
|
**IMPORTANT**: The following context files contain MANDATORY project-specific rules and conventions. You MUST:
|
||||||
|
1. Read these rules carefully before taking any action
|
||||||
|
2. Follow ALL commands exactly as shown (e.g., if the project uses \`pnpm\`, NEVER use \`npm\` or \`npx\`)
|
||||||
|
3. Follow ALL coding conventions, commit message formats, and architectural patterns specified
|
||||||
|
4. Reference these rules before running ANY shell commands or making commits
|
||||||
|
|
||||||
|
Failure to follow these rules will result in broken builds, failed CI, and rejected commits.
|
||||||
|
|
||||||
|
${contents.join("\n\n---\n\n")}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**REMINDER**: Before running any command, verify you are using the correct package manager and following the conventions above.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`;
|
||||||
|
} catch {
|
||||||
|
// Context directory doesn't exist or is empty - this is fine
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Analyze project to gather context
|
* Analyze project to gather context
|
||||||
*/
|
*/
|
||||||
@@ -1731,6 +1800,7 @@ This helps parse your summary correctly in the output logs.`;
|
|||||||
planningMode?: PlanningMode;
|
planningMode?: PlanningMode;
|
||||||
requirePlanApproval?: boolean;
|
requirePlanApproval?: boolean;
|
||||||
previousContent?: string;
|
previousContent?: string;
|
||||||
|
systemPrompt?: string;
|
||||||
}
|
}
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const finalProjectPath = options?.projectPath || projectPath;
|
const finalProjectPath = options?.projectPath || projectPath;
|
||||||
@@ -1838,6 +1908,13 @@ This mock response was generated because AUTOMAKER_MOCK_AGENT=true was set.
|
|||||||
false // don't duplicate paths in text
|
false // don't duplicate paths in text
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Debug: Log if system prompt is provided
|
||||||
|
if (options?.systemPrompt) {
|
||||||
|
console.log(
|
||||||
|
`[AutoMode] System prompt provided (${options.systemPrompt.length} chars), first 200 chars:\n${options.systemPrompt.substring(0, 200)}...`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const executeOptions: ExecuteOptions = {
|
const executeOptions: ExecuteOptions = {
|
||||||
prompt: promptContent,
|
prompt: promptContent,
|
||||||
model: finalModel,
|
model: finalModel,
|
||||||
@@ -1845,6 +1922,7 @@ This mock response was generated because AUTOMAKER_MOCK_AGENT=true was set.
|
|||||||
cwd: workDir,
|
cwd: workDir,
|
||||||
allowedTools: allowedTools,
|
allowedTools: allowedTools,
|
||||||
abortController,
|
abortController,
|
||||||
|
systemPrompt: options?.systemPrompt,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Execute via provider
|
// Execute via provider
|
||||||
|
|||||||
Reference in New Issue
Block a user