Skip to content

Conversation

@casiusss
Copy link
Contributor

@casiusss casiusss commented Dec 29, 2025

New Dependencies

None - uses existing packages

Breaking Changes

None - fully backward compatible

🎨 UI Screenshots

Prompt Customization Overview:

  • Settings navigation with new "Prompt Customization" item
  • 4-tab interface (Auto Mode, Agent, Backlog Plan, Enhancement)

Toggle UI:

  • Read-only default view with muted styling
  • Editable custom view with brand-colored toggle
  • Custom/Default label next to toggle

Warning System:

  • Tab-level warning for Backlog Plan
  • Field-level warning when editing critical prompts
  • Info banner for Auto Mode planning markers

✅ Checklist

  • Code follows project style guidelines
  • TypeScript types are properly defined
  • All builds pass successfully
  • No linting errors
  • Settings are persisted correctly
  • Hot reload works for all prompt types
  • Backward compatible (no breaking changes)
  • UI is responsive and accessible
  • Warning system guides users appropriately

📝 Additional Notes

Design Decisions:

  • Used toggle pattern instead of edit/save buttons for simplicity
  • Dynamic textarea height improves UX for long prompts
  • Preserved custom values even when disabled to prevent data loss
  • No caching to enable hot reload (minimal performance impact)

Settings Sync:

  • Custom prompts sync to ~/.automaker/settings.json immediately
  • Settings file is small (~10-50 KB) and OS-cached
  • No noticeable performance impact from reloading on each use

image

Summary by CodeRabbit

  • New Features
    • Added a Prompt Customization settings section with a 4-tab UI (Auto Mode, Agent, Backlog Plan, Enhancement).
    • Users can enable/disable per-field custom prompts, edit textareas, use per-section or Reset All to Defaults, and see guidance/warnings where applicable.
    • Custom prompts persist in the app and sync to the server.
  • Behavior Changes
    • AI workflows now use the configured prompts (when enabled) instead of built-in defaults.

✏️ Tip: You can customize this high-level summary in your review settings.

casiusss and others added 3 commits December 29, 2025 23:17
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>
@coderabbitai
Copy link

coderabbitai bot commented Dec 29, 2025

Note

Other AI code review bot(s) detected

CodeRabbit 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.

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
Server route wiring
apps/server/src/index.ts, apps/server/src/routes/enhance-prompt/index.ts
Pass SettingsService into enhance-prompt route creator; route signature now accepts optional settingsService.
Enhance handler & route logic
apps/server/src/routes/enhance-prompt/routes/enhance.ts
createEnhanceHandler accepts optional SettingsService; prompts loaded via getPromptCustomization and selected by mode.
Backlog plan route
apps/server/src/routes/backlog-plan/generate-plan.ts
Replaced inline prompts with getPromptCustomization(...).backlogPlan; user prompt built from template with injected feature list.
Settings helpers & logging
apps/server/src/lib/settings-helpers.ts
Added getPromptCustomization, switched console -> logger, changed getAutoLoadClaudeMdSetting signature to accept projectPath.
Server services (async prompts)
apps/server/src/services/agent-service.ts, apps/server/src/services/auto-mode-service.ts
System/planning prompt retrieval converted to async using getPromptCustomization; callers updated to await new async methods; added per-module logger usage.
Tests (server unit)
apps/server/tests/unit/*/settings-helpers.test.ts, apps/server/tests/unit/services-*.test.ts
Tests updated to mock logger from @automaker/utils, removed console spies, and converted sync assertions to async where needed.
Prompt defaults & merge utilities
libs/prompts/src/defaults.ts, libs/prompts/src/merge.ts, libs/prompts/src/index.ts
New centralized default prompt constants and merge utilities to resolve custom vs default prompts; re-exports added.
Prompt types & settings integration
libs/types/src/prompts.ts, libs/types/src/index.ts, libs/types/src/settings.ts
New prompt customization types (CustomPrompt, AutoModePrompts, AgentPrompts, BacklogPlanPrompts, EnhancementPrompts, PromptCustomization, Resolved* types) and DEFAULT_PROMPT_CUSTOMIZATION; GlobalSettings extended with optional promptCustomization.
UI: settings + prompt editor
apps/ui/src/components/views/settings-view.tsx, .../config/navigation.ts, .../hooks/use-settings-view.ts, .../prompts/index.ts, .../prompts/prompt-customization-section.tsx
Added "Prompt Customization" nav item, new PromptCustomizationSection component (tabs, toggles, per-field textarea, reset actions), integrated promptCustomization state and setPromptCustomization action.
App store & sync
apps/ui/src/store/app-store.ts, apps/ui/src/hooks/use-settings-migration.ts
Added promptCustomization to AppState, persistence, setPromptCustomization action and included promptCustomization in sync payload to server.

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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • Shironex

Poem

🐰 I nibble defaults, stitch in your tone,
Merged prompts now call a setting of their own.
Routes pass the service; UI gives control,
From rabbit holes to polished AI soul —
Hop on, tweak, and watch responses grown! 🌿

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: customizable prompts' accurately and concisely summarizes the main change—adding user-customizable prompts across the application.
Docstring Coverage ✅ Passed Docstring coverage is 95.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d5aea83 and 504d9aa.

📒 Files selected for processing (3)
  • apps/server/src/services/agent-service.ts
  • apps/server/tests/unit/lib/settings-helpers.test.ts
  • apps/server/tests/unit/services/agent-service.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/server/tests/unit/lib/settings-helpers.test.ts
  • apps/server/tests/unit/services/agent-service.test.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:

  • apps/server/src/services/agent-service.ts
apps/server/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use createEventEmitter() from lib/events.ts for all server operations to emit events that stream to frontend via WebSocket

Files:

  • apps/server/src/services/agent-service.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:

  • apps/server/src/services/agent-service.ts
🧠 Learnings (1)
📚 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.ts
🧬 Code graph analysis (1)
apps/server/src/services/agent-service.ts (2)
libs/utils/src/index.ts (1)
  • createLogger (40-40)
apps/server/src/lib/settings-helpers.ts (1)
  • getPromptCustomization (276-306)
⏰ 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)
  • GitHub Check: e2e
🔇 Additional comments (3)
apps/server/src/services/agent-service.ts (3)

15-15: LGTM!

The new imports for createLogger and getPromptCustomization are correctly sourced from the appropriate packages and support the logging refactor and customizable prompts feature.

Also applies to: 27-27


80-80: LGTM!

The logging refactor consistently replaces console.error with structured logging via createLogger. This improves testability and provides centralized, consistent error reporting across all error paths in the service.

Also applies to: 154-154, 159-159, 181-181, 397-397, 491-491, 725-725, 774-774


787-791: LGTM! Dynamic prompt loading properly implemented.

The async getSystemPrompt() correctly loads prompts from settings and is properly awaited at the call site (line 252). The no-caching design intentionally enables hot reload of custom prompts, which aligns with the PR's stated goals.

Note: The no-caching approach means prompts are loaded from disk on every message. While this enables immediate updates to custom prompts, consider monitoring performance if message volume is high in production.


Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @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

  • Prompt Customization UI: Introduced a new 'Prompt Customization' section in the settings view, featuring a 4-tab interface for Auto Mode, Agent, Backlog Plan, and Enhancement prompts. Each prompt field includes a toggle to switch between default and custom values, with custom values being preserved even when disabled.
  • Dynamic Prompt Loading: Refactored backend services (AgentService, AutoModeService, Backlog Plan, Enhance Prompt routes) to dynamically load AI prompts from user settings, merging them with built-in defaults. This allows for hot reloading of custom prompts without requiring a server restart.
  • Prompt Management Library: Created a new libs/prompts package to centralize default prompt definitions and provide utility functions for merging custom prompts with these defaults, ensuring a consistent and extensible approach to prompt management.
  • Warning System for Critical Prompts: Implemented a warning system within the UI to alert users about critical prompts (e.g., Backlog Plan, Auto Mode planning markers) that require a strict output format, helping prevent functionality breakage due to incorrect modifications.

🧠 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 Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a 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.

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>
@Shironex Shironex added Enhancement Improvements to existing functionality or UI. Work-In-Progress Currently being addressed. Do Not Merge Use this label if something should not be merged. labels Dec 29, 2025
@casiusss casiusss changed the title Feat/customizable prompts feat: customizable prompts Dec 29, 2025
casiusss and others added 2 commits December 30, 2025 00:40
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>
@casiusss casiusss marked this pull request as ready for review December 30, 2025 00:13
@casiusss
Copy link
Contributor Author

@gemini-code-assist review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a 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.

Comment on lines 5 to 17
// 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(),
}),
};
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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,
  };
});

Comment on lines 241 to 247
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Copy link

@coderabbitai coderabbitai bot left a 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 handleToggle implementation 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 field is a valid key for the given category, 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 adding aria-label for better screen reader support.

The Textarea uses id={label} for label association, but adding an explicit aria-label or ensuring the Label component has a proper htmlFor would strengthen accessibility. Currently htmlFor={label} may not match the actual element ID if label contains 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

📥 Commits

Reviewing files that changed from the base of the PR and between 57b7f92 and d5aea83.

📒 Files selected for processing (23)
  • apps/server/src/index.ts
  • apps/server/src/lib/settings-helpers.ts
  • apps/server/src/routes/backlog-plan/generate-plan.ts
  • apps/server/src/routes/enhance-prompt/index.ts
  • apps/server/src/routes/enhance-prompt/routes/enhance.ts
  • apps/server/src/services/agent-service.ts
  • apps/server/src/services/auto-mode-service.ts
  • apps/server/tests/unit/lib/settings-helpers.test.ts
  • apps/server/tests/unit/services/agent-service.test.ts
  • apps/server/tests/unit/services/auto-mode-service-planning.test.ts
  • apps/ui/src/components/views/settings-view.tsx
  • apps/ui/src/components/views/settings-view/config/navigation.ts
  • apps/ui/src/components/views/settings-view/hooks/use-settings-view.ts
  • apps/ui/src/components/views/settings-view/prompts/index.ts
  • apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx
  • apps/ui/src/hooks/use-settings-migration.ts
  • apps/ui/src/store/app-store.ts
  • libs/prompts/src/defaults.ts
  • libs/prompts/src/index.ts
  • libs/prompts/src/merge.ts
  • libs/types/src/index.ts
  • libs/types/src/prompts.ts
  • libs/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.ts
  • apps/ui/src/components/views/settings-view/hooks/use-settings-view.ts
  • apps/ui/src/components/views/settings-view/prompts/index.ts
  • apps/server/src/index.ts
  • apps/server/src/routes/enhance-prompt/index.ts
  • apps/server/src/routes/backlog-plan/generate-plan.ts
  • apps/server/src/routes/enhance-prompt/routes/enhance.ts
  • apps/ui/src/components/views/settings-view.tsx
  • apps/server/tests/unit/lib/settings-helpers.test.ts
  • apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx
  • apps/server/src/services/agent-service.ts
  • apps/ui/src/hooks/use-settings-migration.ts
  • libs/types/src/index.ts
  • libs/types/src/prompts.ts
  • libs/prompts/src/merge.ts
  • apps/ui/src/store/app-store.ts
  • apps/ui/src/components/views/settings-view/config/navigation.ts
  • libs/prompts/src/index.ts
  • libs/prompts/src/defaults.ts
  • apps/server/src/services/auto-mode-service.ts
  • apps/server/src/lib/settings-helpers.ts
  • apps/server/tests/unit/services/agent-service.test.ts
  • apps/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.ts
  • apps/ui/src/components/views/settings-view/hooks/use-settings-view.ts
  • apps/ui/src/components/views/settings-view/prompts/index.ts
  • apps/server/src/index.ts
  • apps/server/src/routes/enhance-prompt/index.ts
  • apps/server/src/routes/backlog-plan/generate-plan.ts
  • apps/server/src/routes/enhance-prompt/routes/enhance.ts
  • apps/ui/src/components/views/settings-view.tsx
  • apps/server/tests/unit/lib/settings-helpers.test.ts
  • apps/ui/src/components/views/settings-view/prompts/prompt-customization-section.tsx
  • apps/server/src/services/agent-service.ts
  • apps/ui/src/hooks/use-settings-migration.ts
  • libs/types/src/index.ts
  • libs/types/src/prompts.ts
  • libs/prompts/src/merge.ts
  • apps/ui/src/store/app-store.ts
  • apps/ui/src/components/views/settings-view/config/navigation.ts
  • libs/prompts/src/index.ts
  • libs/prompts/src/defaults.ts
  • apps/server/src/services/auto-mode-service.ts
  • apps/server/src/lib/settings-helpers.ts
  • apps/server/tests/unit/services/agent-service.test.ts
  • apps/server/tests/unit/services/auto-mode-service-planning.test.ts
apps/server/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Use createEventEmitter() from lib/events.ts for all server operations to emit events that stream to frontend via WebSocket

Files:

  • apps/server/src/index.ts
  • apps/server/src/routes/enhance-prompt/index.ts
  • apps/server/src/routes/backlog-plan/generate-plan.ts
  • apps/server/src/routes/enhance-prompt/routes/enhance.ts
  • apps/server/src/services/agent-service.ts
  • apps/server/src/services/auto-mode-service.ts
  • apps/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.ts
  • libs/prompts/src/index.ts
  • libs/prompts/src/defaults.ts
  • apps/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 CustomPrompt fields and required Resolved* variants provides good type safety for the merge/resolution flow. The enabled flag 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 importActual and only overrides specific utilities needed for testing. The createLogger stub 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 loadContextFiles in beforeEach ensures 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 promptCustomization field 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 the SettingsViewId union 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/utils mock 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 settingsService to createEnhancePromptRoutes enables 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 getPromptCustomization import 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 getPlanningPromptPrefix method. 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 MessageSquareText icon 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 PromptCustomization type addition to GlobalSettings is well-implemented:

  • Optional field ensures backward compatibility with existing settings files
  • Import follows existing patterns
  • JSDoc clearly documents the purpose

Keeping promptCustomization out of DEFAULT_GLOBAL_SETTINGS is the correct approach since the defaults are handled by the getPromptCustomization merge 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 PromptCustomizationSection integration 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 SettingsService to 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:

  • systemPromptMap approach (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 guidelines

Also 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/prompts package.

libs/prompts/src/merge.ts (2)

34-36: LGTM - Clean prompt resolution logic.

The resolvePrompt helper correctly implements the enable/disable toggle behavior: when enabled is 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*Prompts interface.

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 settingsService is 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/error calls with the structured createLogger from @automaker/utils improves 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/types ensure 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 the critical={true} prop in the settings UI).


402-417: LGTM - Enhancement prompts re-exported without duplication.

Importing from ./enhancement.js and composing into DEFAULT_ENHANCEMENT_PROMPTS avoids duplicating the prompt text while providing a consistent interface through the defaults module.


428-433: LGTM - Combined defaults with as const for type inference.

The as const assertion 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do Not Merge Use this label if something should not be merged. Enhancement Improvements to existing functionality or UI. Work-In-Progress Currently being addressed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants