-
Notifications
You must be signed in to change notification settings - Fork 483
feat: customizable prompts #322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: customizable prompts #322
Conversation
Add comprehensive prompt customization system allowing users to customize
all AI prompts (Auto Mode, Agent Runner, Backlog Plan, Enhancement) through
the Settings UI.
## Features
### Core Customization System
- New TypeScript types for prompt customization with enabled flag
- CustomPrompt interface with value and enabled state
- Prompts preserved even when disabled (no data loss)
- Merged prompt system (custom overrides defaults when enabled)
- Persistent storage in ~/.automaker/settings.json
### Settings UI
- New "Prompt Customization" section in Settings
- 4 tabs: Auto Mode, Agent, Backlog Plan, Enhancement
- Toggle-based editing (read-only default → editable custom)
- Dynamic textarea height based on prompt length (120px-600px)
- Visual state indicators (Custom/Default labels)
### Warning System
- Critical prompt warnings for Backlog Plan (JSON format requirement)
- Field-level warnings when editing critical prompts
- Info banners for Auto Mode planning markers
- Color-coded warnings (blue=info, amber=critical)
### Backend Integration
- Auto Mode service loads prompts from settings
- Agent service loads prompts from settings
- Backlog Plan service loads prompts from settings
- Enhancement endpoint loads prompts from settings
- Settings sync includes promptCustomization field
### Files Changed
- libs/types/src/prompts.ts - Type definitions
- libs/prompts/src/defaults.ts - Default prompt values
- libs/prompts/src/merge.ts - Merge utilities
- apps/ui/src/components/views/settings-view/prompts/ - UI components
- apps/server/src/lib/settings-helpers.ts - getPromptCustomization()
- All service files updated to use customizable prompts
## Technical Details
Prompt storage format:
```json
{
"promptCustomization": {
"autoMode": {
"planningLite": {
"value": "Custom prompt text...",
"enabled": true
}
}
}
}
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove caching from Auto Mode and Agent services to allow custom prompts to take effect immediately without requiring app restart. Changes: - Auto Mode: Load prompts on every feature execution instead of caching - Agent Service: Load prompts on every chat message instead of caching - Remove unused class fields: planningPrompts, agentSystemPrompt This makes custom prompts work consistently across all features: ✓ Auto Mode - hot reload enabled ✓ Agent Runner - hot reload enabled ✓ Backlog Plan - already had hot reload ✓ Enhancement - already had hot reload Users can now modify prompts in Settings and see changes immediately without restarting the app. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace all console.log/console.error calls in settings-helpers.ts with
the centralized logger from @automaker/utils for consistency.
Changes:
- Import createLogger from @automaker/utils
- Create logger instance: createLogger('SettingsHelper')
- Replace console.log → logger.info
- Replace console.error → logger.error
Benefits:
- Consistent logging across the codebase
- Better log formatting and structure
- Easier to filter/control log output
- Follows existing patterns in other services
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughThis PR adds a prompt customization system: new prompt types/defaults/merge utilities, settings-driven prompt loading across server services/routes, UI for editing prompts, SettingsService threaded into enhance routes, and logging/refactoring to use a logger and async prompt retrieval. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Router as Enhance Route
participant Handler as Enhance Handler
participant SettingsSvc as SettingsService
participant SettingsHelper
participant Defaults as DefaultPrompts
participant AgentSvc as AgentService
Client->>Router: POST /enhance
Router->>Handler: invoke handler (settingsService)
Handler->>SettingsHelper: getPromptCustomization(settingsService)
alt SettingsService available
SettingsHelper->>SettingsSvc: load global promptCustomization
SettingsSvc-->>SettingsHelper: customizations
else fallback
SettingsHelper->>Defaults: use DEFAULT_ENHANCEMENT_PROMPTS
end
SettingsHelper-->>Handler: ResolvedEnhancementPrompts
Handler->>AgentSvc: call enhancement with selected systemPrompt
AgentSvc-->>Client: response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
📜 Recent review detailsConfiguration used: defaults Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
🧰 Additional context used📓 Path-based instructions (3)**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
apps/server/src/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (1)📚 Learning: 2025-12-28T05:07:48.138ZApplied to files:
🧬 Code graph analysis (1)apps/server/src/services/agent-service.ts (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (3)
Comment |
Summary of ChangesHello @casiusss, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request delivers a significant new feature that empowers users to tailor the AI's behavior across various application modules by customizing its underlying prompts. It provides a user-friendly interface for managing these customizations, backed by robust backend logic to ensure seamless integration and persistence of user-defined prompts, ultimately offering greater control and flexibility over the AI's interactions and outputs. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a major and well-executed feature: customizable prompts. The changes span across the backend and frontend, centralizing prompt management into a new @automaker/prompts library, which is a significant architectural improvement. Backend services are refactored to dynamically load prompts, and a comprehensive new UI section is added for users to manage these customizations. The state management is also correctly updated to persist these settings. Overall, this is a high-quality contribution that greatly enhances the application's flexibility. My review includes a few suggestions to further improve code clarity and type safety.
apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx
Show resolved
Hide resolved
apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx
Outdated
Show resolved
Hide resolved
Add Record<string, string> type to planningPrompts object to fix TypeScript
error when using string as index.
Error fixed:
Element implicitly has an 'any' type because expression of type 'string'
can't be used to index type '{ lite: string; ... }'.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit fixes two issues introduced during prompt customization: 1. **Restored Full Planning Prompts from Main** - Lite Mode: Added "Silently analyze the codebase first" instruction - Spec Mode: Restored detailed task format rules, [TASK_START]/[TASK_COMPLETE] markers - Full Mode: Restored comprehensive SDD format with [PHASE_COMPLETE] markers - Fixed table structures (Files to Modify, Technical Context, Risks & Mitigations) - Ensured all critical instructions for Auto Mode functionality are preserved 2. **Fixed Test Suite (774 tests passing)** - Made getPlanningPromptPrefix() async-aware in all 11 planning tests - Replaced console.log/error mocks with createLogger mocks (settings-helpers, agent-service) - Updated test expectations to match restored prompts - Fixed variable hoisting issue in agent-service mock setup - Built prompts library to apply changes The planning prompts now match the detailed, production-ready versions from main branch, ensuring Auto Mode has all necessary instructions for proper task execution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Applied three code quality improvements suggested by Gemini Code Assist: 1. **Replace nested ternary with map object (enhance.ts)** - Changed nested ternary operator to Record<EnhancementMode, string> map - Improves readability and maintainability - More declarative approach for system prompt selection 2. **Simplify handleToggle logic (prompt-customization-section.tsx)** - Removed redundant if/else branches - Both branches were calculating the same value - Cleaner, more concise implementation 3. **Add type safety to updatePrompt with generics (prompt-customization-section.tsx)** - Changed field parameter from string to keyof NonNullable<PromptCustomization[T]> - Prevents runtime errors from misspelled field names - Improved developer experience with autocomplete All tests passing (774/774). Builds successful. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
@gemini-code-assist review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces a major new feature allowing users to customize AI prompts. The implementation is well-structured, with a clear separation of concerns. Prompts have been refactored out of service logic into a dedicated libs/prompts package, which is a significant improvement for maintainability. The new UI for prompt customization is comprehensive and provides a good user experience with features like default/custom toggles and warnings for critical prompts. The backend changes correctly integrate with the new settings service to load and apply these custom prompts. My review focuses on improving test quality, which has slightly regressed in some areas due to the refactoring. Specifically, assertions for error logging have been removed, and the logger mocking strategy could be improved for better testability.
| // Mock the logger | ||
| vi.mock('@automaker/utils', async () => { | ||
| const actual = await vi.importActual('@automaker/utils'); | ||
| return { | ||
| ...actual, | ||
| createLogger: () => ({ | ||
| info: vi.fn(), | ||
| error: vi.fn(), | ||
| warn: vi.fn(), | ||
| debug: vi.fn(), | ||
| }), | ||
| }; | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way the logger is mocked makes it difficult to assert that logging functions are called. Each call to createLogger in the code under test will get a new set of mock functions. To make this testable, you should create a single mock logger instance that is returned by createLogger. This will allow you to assert calls on that instance across your tests.
After applying this suggestion, you can update your tests to assert logging calls, for example:
// in apps/server/tests/unit/lib/settings-helpers.test.ts:203
expect(mockLogger.error).toHaveBeenCalled();This will make your tests more robust by verifying error logging behavior. This pattern should be applied to other test files with similar logger mocks, like agent-service.test.ts.
import { createLogger } from '@automaker/utils';
const mockLogger = {
info: vi.fn(),
error: vi.fn(),
warn: vi.fn(),
debug: vi.fn(),
};
// Mock the logger
vi.mock('@automaker/utils', async () => {
const actual = await vi.importActual('@automaker/utils');
return {
...actual,
createLogger: () => mockLogger,
};
});| await service.sendMessage({ | ||
| sessionId: 'session-1', | ||
| message: 'Check this', | ||
| imagePaths: ['/path/test.png'], | ||
| }); | ||
|
|
||
| expect(consoleSpy).toHaveBeenCalled(); | ||
| consoleSpy.mockRestore(); | ||
| // Logger will be called with error, but we don't need to assert it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test case correctly simulates a failed image load, but the assertion for error logging has been removed. The sendMessage method in AgentService still uses console.error for this case. The test should be updated to assert that console.error is called. Alternatively, AgentService could be updated to use the new logger consistently with other parts of the codebase, and the test could assert that the logger's error method is called.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx (2)
74-79: LGTM - Toggle logic simplified and preserves user work.The
handleToggleimplementation correctly preserves the existing custom value when toggling, addressing the earlier review feedback. Users won't lose their work when temporarily switching back to the default view.
146-159: LGTM - Type-safe updatePrompt with generics.The generic implementation ensures
fieldis a valid key for the givencategory, providing compile-time safety against typos in field names. This addresses the earlier type safety concern.
🧹 Nitpick comments (2)
apps/server/src/routes/backlog-plan/generate-plan.ts (1)
82-92: LGTM! Clean dynamic prompt loading.The implementation correctly loads prompts from settings and uses template replacement to inject current features and user requests. The approach is straightforward and integrates well with the new prompt customization system.
Optional: Template validation for robustness.
Consider validating that the template contains expected placeholders before replacement, or documenting that templates must include
{{currentFeatures}}and{{userRequest}}. This would make debugging easier if users create custom templates that are missing these markers.🔎 Example validation approach
// Build the user prompt from template const currentFeatures = formatFeaturesForPrompt(features); +const template = prompts.backlogPlan.userPromptTemplate; +if (!template.includes('{{currentFeatures}}') || !template.includes('{{userRequest}}')) { + logger.warn('[BacklogPlan] User prompt template missing required placeholders'); +} -const userPrompt = prompts.backlogPlan.userPromptTemplate +const userPrompt = template .replace('{{currentFeatures}}', currentFeatures) .replace('{{userRequest}}', prompt);apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx (1)
115-125: Consider addingaria-labelfor better screen reader support.The
Textareausesid={label}for label association, but adding an explicitaria-labelor ensuring theLabelcomponent has a properhtmlForwould strengthen accessibility. CurrentlyhtmlFor={label}may not match the actual element ID iflabelcontains spaces.🔎 Suggested improvement
<Textarea id={label} value={displayValue} onChange={(e) => handleTextChange(e.target.value)} readOnly={!isEnabled} style={{ minHeight }} + aria-label={label} + aria-readonly={!isEnabled} className={cn( 'font-mono text-xs resize-y', !isEnabled && 'cursor-not-allowed bg-muted/50 text-muted-foreground' )} />
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
apps/server/src/index.tsapps/server/src/lib/settings-helpers.tsapps/server/src/routes/backlog-plan/generate-plan.tsapps/server/src/routes/enhance-prompt/index.tsapps/server/src/routes/enhance-prompt/routes/enhance.tsapps/server/src/services/agent-service.tsapps/server/src/services/auto-mode-service.tsapps/server/tests/unit/lib/settings-helpers.test.tsapps/server/tests/unit/services/agent-service.test.tsapps/server/tests/unit/services/auto-mode-service-planning.test.tsapps/ui/src/components/views/settings-view.tsxapps/ui/src/components/views/settings-view/config/navigation.tsapps/ui/src/components/views/settings-view/hooks/use-settings-view.tsapps/ui/src/components/views/settings-view/prompts/index.tsapps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsxapps/ui/src/hooks/use-settings-migration.tsapps/ui/src/store/app-store.tslibs/prompts/src/defaults.tslibs/prompts/src/index.tslibs/prompts/src/merge.tslibs/types/src/index.tslibs/types/src/prompts.tslibs/types/src/settings.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Always import from shared packages (@automaker/*), never from old relative paths
Files:
libs/types/src/settings.tsapps/ui/src/components/views/settings-view/hooks/use-settings-view.tsapps/ui/src/components/views/settings-view/prompts/index.tsapps/server/src/index.tsapps/server/src/routes/enhance-prompt/index.tsapps/server/src/routes/backlog-plan/generate-plan.tsapps/server/src/routes/enhance-prompt/routes/enhance.tsapps/ui/src/components/views/settings-view.tsxapps/server/tests/unit/lib/settings-helpers.test.tsapps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsxapps/server/src/services/agent-service.tsapps/ui/src/hooks/use-settings-migration.tslibs/types/src/index.tslibs/types/src/prompts.tslibs/prompts/src/merge.tsapps/ui/src/store/app-store.tsapps/ui/src/components/views/settings-view/config/navigation.tslibs/prompts/src/index.tslibs/prompts/src/defaults.tsapps/server/src/services/auto-mode-service.tsapps/server/src/lib/settings-helpers.tsapps/server/tests/unit/services/agent-service.test.tsapps/server/tests/unit/services/auto-mode-service-planning.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
resolveModelString()from @automaker/model-resolver to convert model aliases (haiku, sonnet, opus) to full model names
Files:
libs/types/src/settings.tsapps/ui/src/components/views/settings-view/hooks/use-settings-view.tsapps/ui/src/components/views/settings-view/prompts/index.tsapps/server/src/index.tsapps/server/src/routes/enhance-prompt/index.tsapps/server/src/routes/backlog-plan/generate-plan.tsapps/server/src/routes/enhance-prompt/routes/enhance.tsapps/ui/src/components/views/settings-view.tsxapps/server/tests/unit/lib/settings-helpers.test.tsapps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsxapps/server/src/services/agent-service.tsapps/ui/src/hooks/use-settings-migration.tslibs/types/src/index.tslibs/types/src/prompts.tslibs/prompts/src/merge.tsapps/ui/src/store/app-store.tsapps/ui/src/components/views/settings-view/config/navigation.tslibs/prompts/src/index.tslibs/prompts/src/defaults.tsapps/server/src/services/auto-mode-service.tsapps/server/src/lib/settings-helpers.tsapps/server/tests/unit/services/agent-service.test.tsapps/server/tests/unit/services/auto-mode-service-planning.test.ts
apps/server/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Use
createEventEmitter()fromlib/events.tsfor all server operations to emit events that stream to frontend via WebSocket
Files:
apps/server/src/index.tsapps/server/src/routes/enhance-prompt/index.tsapps/server/src/routes/backlog-plan/generate-plan.tsapps/server/src/routes/enhance-prompt/routes/enhance.tsapps/server/src/services/agent-service.tsapps/server/src/services/auto-mode-service.tsapps/server/src/lib/settings-helpers.ts
🧠 Learnings (2)
📚 Learning: 2025-12-28T05:07:48.138Z
Learnt from: CR
Repo: AutoMaker-Org/automaker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T05:07:48.138Z
Learning: Applies to **/*.{ts,tsx} : Use `resolveModelString()` from automaker/model-resolver to convert model aliases (haiku, sonnet, opus) to full model names
Applied to files:
apps/server/src/routes/enhance-prompt/routes/enhance.ts
📚 Learning: 2025-12-28T05:07:48.138Z
Learnt from: CR
Repo: AutoMaker-Org/automaker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T05:07:48.138Z
Learning: Store project-specific rules in `.automaker/context/` and load them into agent prompts via `loadContextFiles()` from automaker/utils
Applied to files:
apps/server/src/services/agent-service.tslibs/prompts/src/index.tslibs/prompts/src/defaults.tsapps/server/src/lib/settings-helpers.ts
🧬 Code graph analysis (7)
apps/server/src/index.ts (1)
apps/server/src/routes/enhance-prompt/index.ts (1)
createEnhancePromptRoutes(18-24)
apps/server/src/routes/enhance-prompt/index.ts (2)
apps/server/src/services/settings-service.ts (1)
SettingsService(104-583)apps/server/src/routes/enhance-prompt/routes/enhance.ts (1)
createEnhanceHandler(90-202)
apps/server/src/routes/backlog-plan/generate-plan.ts (1)
apps/server/src/lib/settings-helpers.ts (1)
getPromptCustomization(276-306)
apps/server/src/services/agent-service.ts (1)
apps/server/src/lib/settings-helpers.ts (1)
getPromptCustomization(276-306)
libs/prompts/src/defaults.ts (3)
libs/prompts/src/index.ts (7)
DEFAULT_AUTO_MODE_PLANNING_LITE(29-29)DEFAULT_AUTO_MODE_PROMPTS(37-37)ResolvedAutoModePrompts(58-58)ResolvedAgentPrompts(59-59)ResolvedBacklogPlanPrompts(60-60)ResolvedEnhancementPrompts(61-61)DEFAULT_PROMPTS(44-44)libs/types/src/index.ts (4)
ResolvedAutoModePrompts(60-60)ResolvedAgentPrompts(61-61)ResolvedBacklogPlanPrompts(62-62)ResolvedEnhancementPrompts(63-63)libs/types/src/prompts.ts (4)
ResolvedAutoModePrompts(128-137)ResolvedAgentPrompts(139-141)ResolvedBacklogPlanPrompts(143-146)ResolvedEnhancementPrompts(148-153)
apps/server/src/lib/settings-helpers.ts (4)
apps/server/src/services/settings-service.ts (1)
SettingsService(104-583)libs/prompts/src/index.ts (4)
mergeAutoModePrompts(49-49)mergeAgentPrompts(50-50)mergeBacklogPlanPrompts(51-51)mergeEnhancementPrompts(52-52)libs/prompts/src/merge.ts (4)
mergeAutoModePrompts(42-68)mergeAgentPrompts(74-78)mergeBacklogPlanPrompts(84-92)mergeEnhancementPrompts(98-117)libs/types/src/prompts.ts (1)
PromptCustomization(100-112)
apps/server/tests/unit/services/auto-mode-service-planning.test.ts (1)
apps/server/src/services/auto-mode-service.ts (1)
getPlanningPromptPrefix(1607-1635)
🔇 Additional comments (36)
libs/types/src/prompts.ts (1)
1-153: LGTM! Well-structured type definitions.The prompt customization types are cleanly organized with excellent JSDoc documentation. The separation between optional
CustomPromptfields and requiredResolved*variants provides good type safety for the merge/resolution flow. Theenabledflag design preserves user work even when disabled, which is a thoughtful UX decision.apps/server/tests/unit/services/agent-service.test.ts (3)
12-26: LGTM! Clean mock pattern.The mock preserves actual exports via
importActualand only overrides specific utilities needed for testing. ThecreateLoggerstub returns a complete logger interface with all required methods, which aligns with the broader logger integration introduced in this PR.
39-43: LGTM! Good default mock setup.Setting a default return value for
loadContextFilesinbeforeEachensures predictable test behavior and prevents undefined errors in tests that don't explicitly configure the mock.
247-247: LGTM! Appropriate test adjustment.Replacing the console assertion with a comment is correct since logging now goes through the mocked logger. The comment documents the behavior without coupling tests to logging implementation details.
apps/ui/src/hooks/use-settings-migration.ts (1)
234-234: LGTM! Consistent addition.The
promptCustomizationfield is correctly added to the settings sync payload, following the same pattern as other global settings fields.apps/ui/src/components/views/settings-view/hooks/use-settings-view.ts (1)
7-7: LGTM! Type extension for new view.The
'prompts'literal is correctly added to theSettingsViewIdunion type, enabling navigation to the new Prompt Customization section in the Settings UI.apps/server/tests/unit/lib/settings-helpers.test.ts (3)
5-17: LGTM! Consistent mock pattern.The
@automaker/utilsmock follows the same pattern as other test files, preserving actual exports while providing a stub logger. This enables testing without coupling to specific logging calls.
22-22: LGTM! Simplified test setup.Using
vi.clearAllMocks()is cleaner than setting up individual console spies, especially now that logging goes through the mocked logger.
203-203: LGTM! Appropriate test adjustment.Replacing assertions with comments correctly decouples tests from logging implementation details while documenting expected behavior.
apps/server/src/index.ts (1)
158-158: LGTM! Consistent dependency injection.Passing
settingsServicetocreateEnhancePromptRoutesenables dynamic prompt loading from user settings. The change is consistent with other route initializations (lines 162, 164, 171-173) and maintains backward compatibility since the parameter is optional.apps/server/src/routes/backlog-plan/generate-plan.ts (1)
11-11: LGTM! Import addition.The
getPromptCustomizationimport is correctly added to support dynamic prompt loading from settings.apps/server/tests/unit/services/auto-mode-service-planning.test.ts (4)
27-38: LGTM! Correct async handling.The tests are properly converted to async functions to await the now-async
getPlanningPromptPrefixmethod. The assertions remain correct for skip mode behavior.
39-63: LGTM! Updated expectations match new prompt structure.The test assertions are correctly updated to expect Markdown headings (e.g.,
"## Planning Phase (Lite Mode)") and approval-specific instructions. This validates that the settings-driven prompts contain the expected structure.
100-109: LGTM! Good coverage of instruction validation.The test correctly validates that all planning modes include the critical instruction about not outputting exploration text, ensuring consistent behavior across modes.
286-325: LGTM! Comprehensive structure validation.The tests thoroughly validate prompt structure across all modes, ensuring each contains expected sections, headings, and content. The async conversions are correct, and assertions are appropriately specific.
libs/types/src/index.ts (1)
52-65: LGTM!The new prompt customization type exports are well-organized and follow the established patterns in this barrel file. The grouping of related types with a clear comment header maintains consistency with other export blocks.
apps/ui/src/components/views/settings-view/config/navigation.ts (1)
13-13: LGTM!The new navigation item for prompt customization follows the established pattern. The
MessageSquareTexticon is an appropriate choice, and placement in the navigation order is logical.Also applies to: 28-28
libs/types/src/settings.ts (1)
10-10: LGTM!The
PromptCustomizationtype addition toGlobalSettingsis well-implemented:
- Optional field ensures backward compatibility with existing settings files
- Import follows existing patterns
- JSDoc clearly documents the purpose
Keeping
promptCustomizationout ofDEFAULT_GLOBAL_SETTINGSis the correct approach since the defaults are handled by thegetPromptCustomizationmerge utility.Also applies to: 364-367
apps/ui/src/components/views/settings-view/prompts/index.ts (1)
1-1: LGTM!Standard barrel export pattern for the prompts module.
apps/server/src/services/auto-mode-service.ts (2)
1607-1635: LGTM!The conversion to async prompt loading is well-implemented:
- Correctly loads prompts from settings via
getPromptCustomization- All planning modes (lite, lite_with_approval, spec, full) are properly mapped
- The "no caching" approach enables hot reload as documented in PR objectives
- The function gracefully returns empty string for 'skip' mode or unknown modes
441-442: LGTM!The call site is correctly updated to await the now-async
getPlanningPromptPrefix.apps/ui/src/components/views/settings-view.tsx (1)
22-22: LGTM!The
PromptCustomizationSectionintegration follows the established pattern for settings sections:
- Import from local barrel module
- State and setter destructured from app store
- Props passed consistently with other section patterns
The case placement aligns with the navigation item order.
Also applies to: 57-58, 125-131
apps/server/src/routes/enhance-prompt/index.ts (1)
9-9: LGTM!Clean dependency injection pattern for threading
SettingsServiceto the enhance handler. The optional parameter maintains backward compatibility, and the type-only import is appropriate since the type is only used for the function signature.Also applies to: 15-21
apps/server/src/routes/enhance-prompt/routes/enhance.ts (2)
13-14: LGTM!Imports correctly added for the settings service type and prompt customization helper.
87-92: LGTM!The dynamic prompt loading implementation is well-structured:
systemPromptMapapproach (as recommended in past review) provides clean, declarative mode-to-prompt mapping- All four enhancement modes are properly covered
- Debug logging helps with troubleshooting custom prompt issues
- Correctly uses
resolveModelString()per coding guidelinesAlso applies to: 135-147
apps/ui/src/store/app-store.ts (1)
496-498: LGTM - Prompt customization state management follows established patterns.The implementation correctly mirrors existing async settings actions (like
setAutoLoadClaudeMd), using the same sync-to-server pattern. The empty object default appropriately allows all prompts to use built-in defaults until customized.Also applies to: 781-783, 1639-1645
apps/server/src/services/agent-service.ts (1)
785-789: LGTM - Async system prompt loading enables hot reload.The conversion from synchronous to asynchronous prompt retrieval is implemented correctly. The caller at line 250 properly awaits the result, and the "no caching" design choice documented in the comment enables users to see prompt changes immediately without server restart.
libs/prompts/src/index.ts (1)
26-62: LGTM - Clean barrel file exports.The new exports are well-organized: default prompt constants, merge utilities, and resolved types are logically grouped. This provides a clean public API surface for the
@automaker/promptspackage.libs/prompts/src/merge.ts (2)
34-36: LGTM - Clean prompt resolution logic.The
resolvePrompthelper correctly implements the enable/disable toggle behavior: whenenabledis true, use the custom value; otherwise, fall back to the default. The null-safe optional chaining (custom?.enabled) handles undefined custom prompts gracefully.
42-68: LGTM - Consistent merge function implementations.All merge functions follow the same pattern, ensuring consistent behavior across prompt categories. Each function properly resolves all fields defined in the corresponding
Resolved*Promptsinterface.Also applies to: 74-78, 84-92, 98-117
apps/server/src/lib/settings-helpers.ts (2)
276-306: LGTM - Robust prompt loading with graceful fallback.The implementation correctly handles all scenarios:
- When
settingsServiceis unavailable, returns merged defaults- When settings load fails, logs the error and falls back to defaults (doesn't crash the feature)
- When successful, merges custom prompts with defaults
The silent fallback approach is appropriate for prompt customization—users get a working experience even if settings fail to load.
7-16: LGTM - Centralized logging improves consistency.Replacing
console.log/errorcalls with the structuredcreateLoggerfrom@automaker/utilsimproves log filtering and consistency across the server codebase.libs/prompts/src/defaults.ts (4)
1-18: LGTM - Well-documented defaults module.The module header clearly explains its purpose and origin of the prompts. Type imports from
@automaker/typesensure the exported objects conform to the expected interfaces.
26-109: LGTM - Planning prompts preserve critical workflow markers.The prompts correctly include markers like
[PLAN_GENERATED],[SPEC_GENERATED],[TASK_START], and[TASK_COMPLETE]that the Auto Mode workflow relies on for parsing progress. The UI appropriately warns users about preserving these markers (via thecritical={true}prop in the settings UI).
402-417: LGTM - Enhancement prompts re-exported without duplication.Importing from
./enhancement.jsand composing intoDEFAULT_ENHANCEMENT_PROMPTSavoids duplicating the prompt text while providing a consistent interface through the defaults module.
428-433: LGTM - Combined defaults withas constfor type inference.The
as constassertion ensures TypeScript infers the narrowest possible type, making the object deeply readonly and preventing accidental mutations of default values.
Replace console.error calls with createLogger for consistent logging across the AgentService. This improves debuggability and makes logger calls testable. Changes: - Add createLogger import from @automaker/utils - Add private logger instance initialized with 'AgentService' prefix - Replace all 7 console.error calls with this.logger.error - Update test mocks to use vi.hoisted() for proper mock access - Update settings-helpers test to create mockLogger inside vi.mock() Test Impact: - All 774 tests passing - Logger error calls are now verifiable in tests - Mock logger properly accessible via vi.hoisted() pattern Resolves Gemini Code Assist suggestions: - "Make logger mockable for test assertions" - "Use logger instead of console.error in AgentService" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
New Dependencies
None - uses existing packages
Breaking Changes
None - fully backward compatible
🎨 UI Screenshots
Prompt Customization Overview:
Toggle UI:
Warning System:
✅ Checklist
📝 Additional Notes
Design Decisions:
Settings Sync:
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.