Skip to content

Conversation

@webdevcody
Copy link
Collaborator

@webdevcody webdevcody commented Jan 4, 2026

  • Introduced a new IdeationService to manage brainstorming sessions, including idea creation, analysis, and conversion to features.
  • Added RESTful API routes for ideation, including session management, idea CRUD operations, and suggestion generation.
  • Created UI components for the ideation dashboard, prompt selection, and category grid to enhance user experience.
  • Integrated keyboard shortcuts and navigation for the ideation feature, improving accessibility and workflow.
  • Updated state management with Zustand to handle ideation-specific data and actions.
  • Added necessary types and paths for ideation functionality, ensuring type safety and clarity in the codebase.

Summary by CodeRabbit

  • New Features

    • Full Ideation feature: guided prompts, dashboard, prompts list, idea CRUD, session-based brainstorming, project analysis, suggestion generation, and idea→feature conversion.
    • UI, keyboard shortcuts, Electron/API and persisted store integrations for ideation workflows.
  • Removals

    • Removed legacy feature-suggestions dialog and related suggestion UI/flows; backlog controls simplified.
  • Tests

    • Comprehensive unit tests added for ideation backend behaviors.
  • Chores

    • Added new ignore rule for a local directory.

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

- Introduced a new IdeationService to manage brainstorming sessions, including idea creation, analysis, and conversion to features.
- Added RESTful API routes for ideation, including session management, idea CRUD operations, and suggestion generation.
- Created UI components for the ideation dashboard, prompt selection, and category grid to enhance user experience.
- Integrated keyboard shortcuts and navigation for the ideation feature, improving accessibility and workflow.
- Updated state management with Zustand to handle ideation-specific data and actions.
- Added necessary types and paths for ideation functionality, ensuring type safety and clarity in the codebase.
…or autonomous mode

- Removed MCP permission settings from the application, including related functions and UI components.
- Updated SDK options to always bypass permissions and allow unrestricted tool access in autonomous mode.
- Adjusted related components and services to reflect the removal of MCP permission configurations, ensuring a cleaner and more efficient codebase.
- Added a new script (dev.mjs) to start the application in development mode with hot reloading using Vite.
- The script includes functionality for installing Playwright browsers, resolving port configurations, and launching either a web or desktop application.
- Removed the old init.mjs script, which was previously responsible for launching the application.
- Updated package.json to reference the new dev.mjs script for the development command.
- Introduced a shared utilities module (launcher-utils.mjs) for common functionalities used in both development and production scripts.
- Revised instructions for starting Automaker, changing from `npm run dev` to `npm run start` for production mode.
- Added a setup wizard for authentication on first run, with options for using Claude Code CLI or entering an API key.
- Clarified development mode instructions, emphasizing the use of `npm run dev` for live reload and hot module replacement.
…ment

- Changed permissionMode settings in enhance and generate title routes to improve edit acceptance and default behavior.
- Refactored performance measurement cleanup in the App component to only execute in development mode, preventing unnecessary operations in production.
- Simplified the startServerAndWait function signature for better readability.
…nd tests

- Changed permissionMode from 'default' to 'bypassPermissions' in sdk-options and claude-provider unit tests.
- Added allowDangerouslySkipPermissions flag in claude-provider test to enhance permission handling.
- Added .claude/hans/ to .gitignore to prevent tracking of specific directory.
- Updated cleanup calls in dev.mjs and start.mjs to use await for proper asynchronous handling.
- Enhanced error handling during cleanup in case of failures.
- Improved server failure handling in startServerAndWait function to ensure proper termination of failed processes.
- Introduced a new option to launch the application in a Docker container (Isolated Mode) from the main menu.
- Added checks for the ANTHROPIC_API_KEY environment variable to ensure proper API functionality.
- Updated process management to include Docker, allowing for better cleanup and handling of spawned processes.
- Enhanced user prompts and logging for improved clarity during the launch process.
@coderabbitai
Copy link

coderabbitai bot commented Jan 4, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

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

Adds a full ideation feature: backend IdeationService and routes, frontend IdeationView and components, types, platform path utilities, store integration, Electron/HTTP API surface, tests, and removes legacy feature-suggestions UI and hooks. Also updates keyboard shortcuts and navigation.

Changes

Cohort / File(s) Summary
Server: core service & wiring
apps/server/src/index.ts, apps/server/src/services/ideation-service.ts, apps/server/src/routes/ideation/common.ts
New IdeationService implemented and registered at /api/ideation; common route utilities (logger, error helpers) added.
Server: route handlers
apps/server/src/routes/ideation/index.ts, apps/server/src/routes/ideation/routes/*
Added route factories for sessions, ideas CRUD, analysis, convert, prompts, and suggestions generation; includes validation, logging, and DI of IdeationService and FeatureLoader.
Frontend: ideation UI & routes
apps/ui/src/components/views/ideation-view/*, apps/ui/src/routes/ideation.tsx
New IdeationView, dashboard, prompt category grid, prompt list components, and route at /ideation.
Frontend: store & keyboard/navigation
apps/ui/src/store/ideation-store.ts, apps/ui/src/store/app-store.ts, apps/ui/src/components/layout/sidebar/hooks/use-navigation.ts, apps/ui/src/components/ui/keyboard-map.tsx, apps/ui/src/hooks/use-keyboard-shortcuts.ts
New Zustand ideation store and persisted state; added ideation view mode and keyboard shortcuts (ideation, githubIssues, githubPrs); sidebar and shortcut mappings updated; keyboard hook now merges defaults.
Frontend: API surface
apps/ui/src/lib/electron.ts, apps/ui/src/lib/http-api-client.ts
Exposed IdeationAPI in ElectronAPI and added ideation methods to HttpApiClient; expanded event types (ideation:stream, ideation:analysis).
Types & platform utilities
libs/types/src/ideation.ts, libs/types/src/event.ts, libs/types/src/index.ts, libs/platform/src/paths.ts, libs/platform/src/index.ts
New ideation TypeScript types and event literals; platform path helpers for ideation data and ensure directory creation; re-exported from libs.
Tests
apps/server/tests/unit/services/ideation-service.test.ts
Comprehensive unit tests for IdeationService covering sessions, ideas CRUD, conversion, analysis, prompts, and suggestions with extensive mocks.
UI removals: legacy feature suggestions
apps/ui/src/components/views/board-view.tsx, apps/ui/src/components/views/board-view/dialogs/feature-suggestions-dialog.tsx, apps/ui/src/components/views/board-view/dialogs/index.ts, apps/ui/src/components/views/board-view/hooks/use-suggestions-state.ts, apps/ui/src/components/views/board-view/hooks/use-board-effects.ts, apps/ui/src/components/views/board-view/kanban-board.tsx
Removed FeatureSuggestionsDialog and related hook/exports; KanbanBoard props and backlog UI simplified (removed suggestions controls).
Misc
.claude/.gitignore
Added hans/ to ignore list.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as IdeationView (frontend)
    participant Store as IdeationStore
    participant API as HttpApiClient / ElectronAPI
    participant Server as IdeationService
    participant AI as AI Provider
    participant Disk as Disk Storage

    User->>UI: choose prompt & generate
    UI->>Store: create generation job (generating)
    UI->>API: generateSuggestions(projectPath, promptId, category)
    API->>Server: POST /api/ideation/suggestions
    activate Server
    Server->>AI: build prompt + send request
    AI-->>Server: suggestions response
    Server->>Disk: persist ideas
    Server-->>API: return suggestions[]
    deactivate Server
    API->>Store: update job (ready, suggestions)
    Store-->>UI: render suggestions in dashboard
    User->>UI: accept suggestion
    UI->>API: convertToFeature(projectPath, ideaId)
    API->>Server: POST /api/ideation/convert
    Server->>Disk: create feature, optionally delete idea
    Server-->>API: featureId
    API->>Store: remove suggestion / update UI
    Store-->>UI: show feature added
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Suggested labels

Enhancement, Tests, Testers-Requested

Poem

🐰 I hopped through code and found a light,

Prompts and ideas to spark the night.
Sessions, stores, and routes aligned,
Features born from a curious mind.
Hop on—let’s make ideas take flight! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 34.88% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: implement ideation feature for brainstorming and idea management' directly and comprehensively describes the main change: the implementation of a complete ideation feature.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @webdevcody, 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 major new 'Ideation' capability, transforming how users can brainstorm and develop new features within the application. It provides a structured environment for generating, refining, and tracking ideas, leveraging AI for project analysis and suggestion generation. This integration aims to streamline the product development workflow from concept to implementation, replacing a more limited prior suggestion mechanism with a dedicated, interactive ideation space.

Highlights

  • New Ideation Feature: Introduced a comprehensive 'Ideation' feature for brainstorming and managing ideas, including AI-powered suggestions and conversion to features.
  • Backend Service and API: Added a new IdeationService and a full suite of RESTful API routes for managing ideation sessions, performing CRUD operations on ideas, analyzing projects, and generating suggestions.
  • Frontend UI and State Management: Developed new UI components for the ideation dashboard, prompt selection, and category grids. Integrated Zustand for ideation-specific state management and added keyboard shortcuts for enhanced accessibility.
  • Replaced Old Suggestion System: The previous 'Feature Suggestions Dialog' has been removed from the board view, as its functionality is now subsumed and expanded upon by the new Ideation feature.

🧠 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 comprehensive ideation feature, including a new IdeationService on the backend, corresponding API routes, and a full set of UI components for managing ideas. The overall structure is well-designed, with a clear separation of concerns. The new IdeationService is robust, handling sessions, CRUD operations, and AI-powered suggestion generation with good error handling and asynchronous processing. The UI is well-organized into a dashboard and a flow for generating new ideas.

However, there are a few areas for improvement. I've identified some instances of data duplication and inconsistent logic between the frontend and backend, particularly concerning the list of guided prompts and the conversion of suggestions into features. Addressing these will improve maintainability and reduce the risk of future bugs. I've also noted a couple of places where backend logic could be enhanced or made more consistent. My detailed comments provide specific suggestions to resolve these points.

Comment on lines 29 to 33
const validCategories: IdeaCategory[] = ['feature', 'ux-ui', 'dx', 'growth', 'technical'];
if (!validCategories.includes(category as IdeaCategory)) {
res.status(400).json({ success: false, error: 'Invalid category' });
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The list of validCategories is hardcoded and incomplete. It's missing categories like 'security', 'performance', etc., which are present in IdeationService. This will cause valid categories to be rejected. Instead of hardcoding, you should get the list of valid categories directly from the ideationService to ensure it's always up-to-date.

Suggested change
const validCategories: IdeaCategory[] = ['feature', 'ux-ui', 'dx', 'growth', 'technical'];
if (!validCategories.includes(category as IdeaCategory)) {
res.status(400).json({ success: false, error: 'Invalid category' });
return;
}
const validCategories = ideationService.getPromptCategories().map((c) => c.id);
if (!validCategories.includes(category as IdeaCategory)) {
res.status(400).json({ success: false, error: 'Invalid category' });
return;
}


/**
* Get all guided prompts
* NOTE: Keep in sync with apps/ui/src/components/views/ideation-view/data/guided-prompts.ts
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The comment "NOTE: Keep in sync with apps/ui/src/components/views/ideation-view/data/guided-prompts.ts" indicates that the list of guided prompts is duplicated in both the backend and frontend. This is a maintenance risk and can lead to inconsistencies. The backend should be the single source of truth for this data. The frontend should fetch the prompts using the /api/ideation/prompts endpoint, which is already implemented. Please remove the duplicated data from the frontend.

Comment on lines 1695 to 1723
addSuggestionToBoard: async (projectPath: string, suggestion: AnalysisSuggestion) => {
// Create a feature directly from the suggestion
const result = await this.post<{ success: boolean; feature?: Feature; error?: string }>(
'/api/features/create',
{
projectPath,
feature: {
title: suggestion.title,
description:
suggestion.description +
(suggestion.rationale ? `\n\n**Rationale:** ${suggestion.rationale}` : ''),
category:
suggestion.category === 'ux-ui'
? 'enhancement'
: suggestion.category === 'dx'
? 'chore'
: suggestion.category === 'technical'
? 'refactor'
: 'feature',
status: 'backlog',
},
}
);
return {
success: result.success,
featureId: result.feature?.id,
error: result.error,
};
},
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The addSuggestionToBoard method implements logic to convert an AnalysisSuggestion into a Feature on the client-side. This logic is duplicated and inconsistent with the mapIdeaCategoryToFeatureCategory method in apps/server/src/services/ideation-service.ts. The category mapping here is incomplete. This logic should reside on the backend to ensure consistency and a single source of truth. I suggest creating a new endpoint, for example /api/ideation/add-suggestion, that accepts a suggestion and handles the conversion to a feature on the server.

Comment on lines 7 to 9
import { createLogger } from '@automaker/utils';

const logger = createLogger('ideation:suggestions-generate');
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For consistency with other route files in this module, you should use the shared logError and getErrorMessage utilities from ../common.js instead of creating a local logger.

Suggested change
import { createLogger } from '@automaker/utils';
const logger = createLogger('ideation:suggestions-generate');
import { getErrorMessage, logError } from '../common.js';

Comment on lines 48 to 53
logger.error('Failed to generate suggestions:', error);
res.status(500).json({
success: false,
error: (error as Error).message,
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

To maintain consistency in error handling across the ideation routes, please use the shared logError and getErrorMessage utilities here.

Suggested change
logger.error('Failed to generate suggestions:', error);
res.status(500).json({
success: false,
error: (error as Error).message,
});
}
logError(error, 'Failed to generate suggestions');
res.status(500).json({
success: false,
error: getErrorMessage(error),
});

Comment on lines +1575 to +1609
private async generateAnalysisSuggestions(
_projectPath: string,
structure: Awaited<ReturnType<typeof this.gatherProjectStructure>>
): Promise<AnalysisSuggestion[]> {
// Generate basic suggestions based on project structure analysis
const suggestions: AnalysisSuggestion[] = [];

if (structure.routes.length > 0 && structure.routes.length < 5) {
suggestions.push({
id: this.generateId('sug'),
category: 'feature',
title: 'Expand Core Functionality',
description: 'The app has a small number of routes. Consider adding more features.',
rationale: `Only ${structure.routes.length} routes detected. Most apps benefit from additional navigation options.`,
priority: 'medium',
});
}

if (
!structure.dependencies?.includes('react-query') &&
!structure.dependencies?.includes('@tanstack/react-query')
) {
suggestions.push({
id: this.generateId('sug'),
category: 'technical',
title: 'Add Data Fetching Library',
description: 'Consider adding React Query or similar for better data management.',
rationale:
'Data fetching libraries provide caching, background updates, and better loading states.',
priority: 'low',
});
}

return suggestions;
}
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 generateAnalysisSuggestions method currently returns hardcoded, generic suggestions. This seems like a placeholder. For this feature to be useful, this method should use an AI model to analyze the project structure and generate more context-specific and valuable suggestions.

- Introduced `dev.mjs` for development mode with hot reloading using Vite.
- Added `start.mjs` for production mode, serving pre-built static files without hot reloading.
- Created a new utility module `launcher-utils.mjs` for shared functions across scripts.
- Updated package.json scripts to reflect new launch commands.
- Removed deprecated `init.mjs` and associated MCP permission settings from the codebase.
- Added `.dockerignore` and updated `.gitignore` for better environment management.
- Enhanced README with updated usage instructions for starting the application.
@webdevcody
Copy link
Collaborator Author

@claude increase coverage for test suite tests

@claude
Copy link

claude bot commented Jan 4, 2026

Claude finished @webdevcody's task in 4m 7s —— View job


Increasing Test Coverage for Ideation Feature ✅

I've successfully added comprehensive unit tests for the ideation feature introduced in this PR.

Analysis

The ideation feature adds:

  • IdeationService - Core service with session management, idea CRUD, AI chat, project analysis
  • API routes in apps/server/src/routes/ideation/ (13 route files)
  • Previously no tests existed for any ideation functionality

Based on the vitest config, routes are excluded from coverage, so I focused on comprehensive unit tests for the IdeationService.

What I've Added

Created comprehensive unit tests in apps/server/tests/unit/services/ideation-service.test.ts covering:

Session Management (5 tests)

  • Creating sessions with default and custom options
  • Starting sessions with initial messages
  • Retrieving sessions from memory and disk
  • Stopping sessions
  • Checking session running state

Ideas CRUD (11 tests)

  • Creating ideas with required and optional fields
  • Loading all ideas from disk with sorting
  • Handling missing ideas directory
  • Skipping invalid idea files
  • Getting individual ideas
  • Updating idea fields
  • Deleting ideas
  • Archiving ideas

Idea to Feature Conversion (4 tests)

  • Converting ideas to features with basic fields
  • Including user stories in feature descriptions
  • Including notes in feature descriptions
  • Error handling for non-existent ideas

Project Analysis (3 tests)

  • Analyzing project structure and generating suggestions
  • Emitting progress events
  • Caching analysis results
  • Error handling with event emission

Prompt Management (3 tests)

  • Getting prompt categories
  • Getting all prompts
  • Filtering prompts by category

Suggestion Generation (2 tests)

  • Generating AI-powered suggestions from prompts
  • Error handling for invalid prompts

Total: 28 comprehensive unit tests covering all major functionality of the IdeationService.

Testing

Please run npm run test:server to verify all tests pass. The tests mock all external dependencies (filesystem, platform utilities, AI providers) to ensure fast, reliable unit testing.

Changes Committed

  • ✅ Added apps/server/tests/unit/services/ideation-service.test.ts (763 lines)
  • ✅ Committed and pushed to the ideation branch

--- |

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: 5

♻️ Duplicate comments (7)
apps/server/src/routes/ideation/routes/prompts.ts (1)

29-33: Incomplete category validation - matches previous review.

The hardcoded validCategories array is missing 4 valid categories from the IdeaCategory type: 'security', 'performance', 'accessibility', and 'analytics'. This will cause valid requests to be rejected with a 400 error.

As suggested in the previous review, fetch the valid categories dynamically from ideationService.getPromptCategories() to ensure consistency with the type definition.

🔎 Proposed fix
-      const validCategories: IdeaCategory[] = ['feature', 'ux-ui', 'dx', 'growth', 'technical'];
+      const validCategories = ideationService.getPromptCategories().map((c) => c.id);
       if (!validCategories.includes(category as IdeaCategory)) {
         res.status(400).json({ success: false, error: 'Invalid category' });
         return;
       }
apps/server/src/routes/ideation/routes/suggestions-generate.ts (2)

7-9: Use shared error utilities for consistency.

This file should use the shared logError and getErrorMessage utilities from ../common.js instead of creating a separate logger instance, as noted in previous review comments and as implemented in other ideation route files.

🔎 Recommended refactor to use shared utilities
-import { createLogger } from '@automaker/utils';
-
-const logger = createLogger('ideation:suggestions-generate');
+import { getErrorMessage, logError } from '../common.js';

34-34: Replace local logging with shared utilities.

Replace the local logger calls with the shared error handling utilities for consistency with other ideation routes.

🔎 Recommended refactor
-      logger.info(`Generating ${suggestionCount} suggestions for prompt: ${promptId}`);
+      // Optional: If info logging is needed, use the shared logger from common.js
-      logger.error('Failed to generate suggestions:', error);
+      logError(error, 'Failed to generate suggestions');
       res.status(500).json({
         success: false,
-        error: (error as Error).message,
+        error: getErrorMessage(error),
       });

Also applies to: 48-52

apps/ui/src/components/views/ideation-view/components/prompt-list.tsx (1)

8-29: Avoid duplicating guided prompts between frontend and backend

This component pulls prompts from ../data/guided-prompts, while the backend IdeationService.getAllPrompts() maintains an almost identical list (and even has a “Keep in sync” comment). That duplication is the same maintenance risk previously flagged in the server file.

Consider making the backend the single source of truth for guided prompts (e.g., via /api/ideation/prompts or the existing ideation API) and have the UI fetch by category instead of importing static data here. That will prevent future drift between server and UI prompt sets.

Also applies to: 103-159

apps/server/src/services/ideation-service.ts (2)

861-910: Guided prompts are still duplicated between backend and frontend

getPromptCategories/getAllPrompts define a full catalog of guided prompts and carry the same “NOTE: Keep in sync with apps/ui/.../guided-prompts.ts” comment that was previously flagged. The new PromptList UI still imports prompts from the frontend data module, so you now have two copies of the same catalogue.

This remains a maintenance and consistency risk:

  • Adding/editing prompts requires touching two files.
  • It’s easy for the backend prompts used by analysis/suggestions to diverge from what the UI displays.

Prefer the backend as the single source of truth for guided prompts:

  • Keep the prompt definitions here in IdeationService, and
  • Expose them via the existing ideation routes,
  • Then update the UI to consume /api/ideation/prompts (or the Electron ideation API) instead of static guided-prompts.ts.

Once that’s wired, you can delete the duplicated prompt data from the frontend module.

Also applies to: 989-1225


1575-1609: generateAnalysisSuggestions is still a placeholder heuristic

This method still returns a couple of generic, structure-based suggestions (routes count and a missing data-fetching library), which matches the prior feedback that it’s a placeholder:

if (structure.routes.length > 0 && structure.routes.length < 5) {  }
if (!deps.includes('react-query') && !deps.includes('@tanstack/react-query')) {  }

For the analysis feature to be genuinely useful, this should eventually:

  • Either call into the same provider/SDK stack with a dedicated analysis prompt, or
  • At least generate a richer, more context-aware set of AnalysisSuggestions based on the discovered structure and dependencies.

Not a correctness bug, but worth tracking so this doesn’t ship as “final” behavior.

apps/ui/src/lib/http-api-client.ts (1)

1650-1730: Move addSuggestionToBoard conversion logic to the backend and align category mapping

ideation.addSuggestionToBoard is still converting AnalysisSuggestionFeature entirely on the client and reimplements its own category mapping:

  • 'ux-ui' → 'enhancement'
  • 'dx' → 'chore'
  • 'technical' → 'refactor'
  • everything else → 'feature'

This duplicates and partially contradicts mapIdeaCategoryToFeatureCategory in apps/server/src/services/ideation-service.ts, which also handles security, performance, accessibility, and analytics (mapping security to bug, etc.). That’s exactly the duplication/inconsistency called out in the earlier review.

To avoid drift and ensure a single source of truth:

  • Move this conversion into the ideation backend (e.g., a dedicated /api/ideation/add-suggestion or by extending the existing convert/feature routes), and
  • Change addSuggestionToBoard here to just POST { projectPath, suggestion } to that endpoint and return its response.

At minimum, if you keep a temporary client-side path, mirror the full mapping used in mapIdeaCategoryToFeatureCategory so security/performance/accessibility/analytics suggestions don’t silently get misclassified as plain 'feature'.

🧹 Nitpick comments (11)
apps/ui/src/components/views/ideation-view/data/guided-prompts.ts (1)

65-391: Consider fetching prompts from the server API instead of hardcoding.

The static GUIDED_PROMPTS data duplicates prompt data that also exists server-side (via IdeationService) with corresponding API endpoints (GET /prompts, GET /prompts/:category from apps/server/src/routes/ideation/routes/prompts.ts).

This duplication creates a maintenance burden—prompts must be updated in both locations to stay synchronized. Since API routes exist specifically for fetching prompts, consider removing the hardcoded client-side data and fetching from the server instead.

If offline support or faster initial load is required, the hardcoded data could serve as a fallback, but this should be explicitly documented.

💡 Alternative approach

Remove the static GUIDED_PROMPTS and fetch from the API:

// Fetch prompts from server instead of hardcoding
export async function fetchPrompts(): Promise<IdeationPrompt[]> {
  const response = await apiClient.get('/api/ideation/prompts');
  return response.data.prompts;
}

export async function fetchPromptsByCategory(category: IdeaCategory): Promise<IdeationPrompt[]> {
  const response = await apiClient.get(`/api/ideation/prompts/${category}`);
  return response.data.prompts;
}

If you need offline fallback, keep the static data but document its purpose:

/**
 * Static fallback prompts for offline usage or initial load.
 * Production data should be fetched from the server API.
 */
export const GUIDED_PROMPTS_FALLBACK: IdeationPrompt[] = [
  // ... existing prompts
];
apps/server/src/routes/ideation/routes/ideas-delete.ts (1)

27-28: Consider returning 404 for non-existent ideas.

The delete operation always returns { success: true } even if the idea doesn't exist (since deleteIdea silently ignores missing ideas). This differs from the update handler which returns 404 for non-existent ideas.

While idempotent deletes are valid, returning success without confirmation may mask bugs where clients delete the wrong ideaId. Consider aligning with the update handler's behavior for consistency.

🔎 Proposed change for explicit existence check
-      await ideationService.deleteIdea(projectPath, ideaId);
-      res.json({ success: true });
+      const deleted = await ideationService.deleteIdea(projectPath, ideaId);
+      if (!deleted) {
+        res.status(404).json({ success: false, error: 'Idea not found' });
+        return;
+      }
+      res.json({ success: true });

This would require modifying deleteIdea to return a boolean indicating whether the idea existed.

libs/types/src/event.ts (1)

36-36: Inconsistent event naming: analysis-complete vs analysis-completed.

The existing event uses project:analysis-completed (line 25), but the new ideation event uses ideation:analysis-complete. Consider using ideation:analysis-completed for consistency across the codebase.

🔎 Suggested fix
-  | 'ideation:analysis-complete'
+  | 'ideation:analysis-completed'
apps/server/src/routes/ideation/routes/session-get.ts (1)

35-39: Duplicate messages field in response.

The session object (of type IdeationSessionWithMessages) already contains messages. Adding messages: session.messages at line 38 duplicates this field at the top level of the response, which increases payload size unnecessarily and may cause confusion for API consumers.

🔎 Suggested fix
       res.json({
         success: true,
         session: { ...session, isRunning },
-        messages: session.messages,
       });
apps/ui/src/store/ideation-store.ts (2)

176-176: substr is deprecated; use substring instead.

String.prototype.substr() is deprecated. Replace with substring() for the same behavior.

🔎 Suggested fix
-        const jobId = `job-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
+        const jobId = `job-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;

192-205: Potential issue with falsy error values.

Line 200 uses error: error || null, which converts an empty string '' to null. If an empty string error is intentionally passed, it will be lost. Consider using nullish coalescing (??) if you want to preserve empty strings, or keep || if empty strings should be treated as "no error."

🔎 Suggested fix (if empty strings should be preserved)
               ? {
                   ...job,
                   status,
                   suggestions: suggestions || job.suggestions,
-                  error: error || null,
+                  error: error ?? null,
                   completedAt: status !== 'generating' ? new Date().toISOString() : null,
                 }
apps/ui/src/components/views/ideation-view/components/ideation-dashboard.tsx (1)

238-240: Unsafe type assertion for error object.

(error as Error).message assumes error is an Error instance, but caught exceptions can be any type. This could throw if someone throws a non-Error value.

🔎 Suggested fix
     } catch (error) {
       console.error('Failed to add to board:', error);
-      toast.error((error as Error).message);
+      toast.error(error instanceof Error ? error.message : 'Failed to add to board');
     } finally {
libs/types/src/ideation.ts (1)

203-218: Align IdeationStreamEvent with the actual event payload shape

The current definition:

export interface IdeationStreamEvent {
  type: 'ideation:stream';
  sessionId: string;
  content: string;
  done: boolean;
}

doesn’t match what IdeationService.sendMessage actually emits on the 'ideation:stream' channel, where the payload looks like:

  • { sessionId, type: 'message', message: IdeationMessage }
  • { sessionId, type: 'stream', content, done: false }
  • { sessionId, type: 'message-complete', message, content, done: true }
  • { sessionId, type: 'aborted' }
  • { sessionId, type: 'error', error }

To avoid misleading consumers, consider modeling this as a discriminated union over the inner type field, e.g.:

Example refactor
-export interface IdeationStreamEvent {
-  type: 'ideation:stream';
-  sessionId: string;
-  content: string;
-  done: boolean;
-}
+export type IdeationStreamEvent =
+  | {
+      type: 'message';
+      sessionId: string;
+      message: IdeationMessage;
+    }
+  | {
+      type: 'stream' | 'message-complete';
+      sessionId: string;
+      content: string;
+      done: boolean;
+      message?: IdeationMessage;
+    }
+  | {
+      type: 'aborted';
+      sessionId: string;
+    }
+  | {
+      type: 'error';
+      sessionId: string;
+      error: string;
+    };

This keeps EventType as 'ideation:stream' at the transport level while giving callers an accurate payload type.

apps/ui/src/lib/electron.ts (1)

16-26: Ideation API surface is consistent; consider tightening convertToFeature typing

The new IdeationAPI interface and ideation?: IdeationAPI addition on ElectronAPI line up with the HTTP client implementation and the server routes; method shapes and payload types look coherent.

One minor improvement: convertToFeature currently returns feature?: any. Since you already have a Feature type in this module (and in @automaker/types), you can make this safer and more self-documenting by returning feature?: Feature instead of any, while still keeping featureId?: string for convenience.

Also, ensure the actual Electron IPC bridge (main process) is updated to implement this ideation interface; otherwise, browser code relying on the real Electron API (not just the HTTP client) will see ideation as undefined.

Also applies to: 43-55, 57-129, 748-749

apps/server/src/services/ideation-service.ts (2)

758-787: Harden suggestion parsing: normalize priority and reduce JSON brittleness

parseSuggestionsFromResponse and the text fallback do a good job of salvaging non-JSON responses, but there are a couple of robustness gaps:

  • You trust item.priority as-is, even though the model may emit "High"/"MEDIUM" or other variants. That can silently break any downstream code that expects 'high' | 'medium' | 'low'.
  • The JSON extraction regex grabs the first [...] substring; if the model ever wraps JSON in prose with other bracketed content, you could parse the wrong segment.

Suggested improvements:

  • Normalize priority to your union type and default safely:

    const raw = typeof item.priority === 'string' ? item.priority.toLowerCase() : '';
    const priority: 'high' | 'medium' | 'low' =
      raw === 'high' || raw === 'low' ? raw : 'medium';
  • Optionally, tighten JSON extraction by preferring the last [...] block or by instructing the model even more strongly (you already do some of this in the system prompt).

Even just the priority normalization would prevent subtle filtering bugs later.

Also applies to: 793-854


446-450: Consider recording archivedAt when archiving ideas

archiveIdea currently only flips the status:

return this.updateIdea(projectPath, ideaId, {
  status: 'archived' as IdeaStatus,
});

Given the Idea type includes an archivedAt?: string field, it would be useful to also stamp the archive time here so clients can sort/filter by when an idea was archived.

Example:

return this.updateIdea(projectPath, ideaId, {
  status: 'archived' as IdeaStatus,
  archivedAt: new Date().toISOString(),
});
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b1f7139 and 3512749.

📒 Files selected for processing (43)
  • .claude/.gitignore
  • apps/server/src/index.ts
  • apps/server/src/routes/ideation/common.ts
  • apps/server/src/routes/ideation/index.ts
  • apps/server/src/routes/ideation/routes/analyze.ts
  • apps/server/src/routes/ideation/routes/convert.ts
  • apps/server/src/routes/ideation/routes/ideas-create.ts
  • apps/server/src/routes/ideation/routes/ideas-delete.ts
  • apps/server/src/routes/ideation/routes/ideas-get.ts
  • apps/server/src/routes/ideation/routes/ideas-list.ts
  • apps/server/src/routes/ideation/routes/ideas-update.ts
  • apps/server/src/routes/ideation/routes/prompts.ts
  • apps/server/src/routes/ideation/routes/session-get.ts
  • apps/server/src/routes/ideation/routes/session-message.ts
  • apps/server/src/routes/ideation/routes/session-start.ts
  • apps/server/src/routes/ideation/routes/session-stop.ts
  • apps/server/src/routes/ideation/routes/suggestions-generate.ts
  • apps/server/src/services/ideation-service.ts
  • apps/ui/src/components/layout/sidebar/hooks/use-navigation.ts
  • apps/ui/src/components/ui/keyboard-map.tsx
  • apps/ui/src/components/views/board-view.tsx
  • apps/ui/src/components/views/board-view/dialogs/feature-suggestions-dialog.tsx
  • apps/ui/src/components/views/board-view/dialogs/index.ts
  • apps/ui/src/components/views/board-view/hooks/index.ts
  • apps/ui/src/components/views/board-view/hooks/use-board-effects.ts
  • apps/ui/src/components/views/board-view/hooks/use-suggestions-state.ts
  • apps/ui/src/components/views/board-view/kanban-board.tsx
  • apps/ui/src/components/views/ideation-view/components/ideation-dashboard.tsx
  • apps/ui/src/components/views/ideation-view/components/prompt-category-grid.tsx
  • apps/ui/src/components/views/ideation-view/components/prompt-list.tsx
  • apps/ui/src/components/views/ideation-view/data/guided-prompts.ts
  • apps/ui/src/components/views/ideation-view/index.tsx
  • apps/ui/src/hooks/use-keyboard-shortcuts.ts
  • apps/ui/src/lib/electron.ts
  • apps/ui/src/lib/http-api-client.ts
  • apps/ui/src/routes/ideation.tsx
  • apps/ui/src/store/app-store.ts
  • apps/ui/src/store/ideation-store.ts
  • libs/platform/src/index.ts
  • libs/platform/src/paths.ts
  • libs/types/src/event.ts
  • libs/types/src/ideation.ts
  • libs/types/src/index.ts
💤 Files with no reviewable changes (6)
  • apps/ui/src/components/views/board-view/hooks/index.ts
  • apps/ui/src/components/views/board-view/hooks/use-suggestions-state.ts
  • apps/ui/src/components/views/board-view.tsx
  • apps/ui/src/components/views/board-view/dialogs/feature-suggestions-dialog.tsx
  • apps/ui/src/components/views/board-view/hooks/use-board-effects.ts
  • apps/ui/src/components/views/board-view/dialogs/index.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/routes/ideation/routes/convert.ts
  • apps/server/src/routes/ideation/routes/session-message.ts
  • apps/server/src/routes/ideation/routes/ideas-list.ts
  • apps/server/src/routes/ideation/common.ts
  • apps/server/src/routes/ideation/routes/ideas-create.ts
  • apps/server/src/routes/ideation/routes/session-start.ts
  • apps/server/src/routes/ideation/routes/session-stop.ts
  • apps/server/src/routes/ideation/routes/suggestions-generate.ts
  • apps/ui/src/routes/ideation.tsx
  • apps/ui/src/store/ideation-store.ts
  • libs/types/src/event.ts
  • apps/server/src/routes/ideation/index.ts
  • apps/ui/src/components/ui/keyboard-map.tsx
  • apps/ui/src/components/views/ideation-view/components/prompt-category-grid.tsx
  • apps/ui/src/components/views/ideation-view/components/ideation-dashboard.tsx
  • apps/ui/src/components/layout/sidebar/hooks/use-navigation.ts
  • libs/platform/src/paths.ts
  • apps/server/src/routes/ideation/routes/session-get.ts
  • apps/server/src/routes/ideation/routes/ideas-delete.ts
  • apps/server/src/routes/ideation/routes/ideas-update.ts
  • apps/server/src/routes/ideation/routes/ideas-get.ts
  • apps/server/src/index.ts
  • apps/ui/src/components/views/ideation-view/components/prompt-list.tsx
  • apps/ui/src/store/app-store.ts
  • libs/types/src/index.ts
  • apps/ui/src/lib/http-api-client.ts
  • apps/ui/src/components/views/ideation-view/data/guided-prompts.ts
  • apps/ui/src/hooks/use-keyboard-shortcuts.ts
  • apps/server/src/routes/ideation/routes/analyze.ts
  • apps/server/src/routes/ideation/routes/prompts.ts
  • apps/ui/src/components/views/ideation-view/index.tsx
  • apps/server/src/services/ideation-service.ts
  • libs/platform/src/index.ts
  • libs/types/src/ideation.ts
  • apps/ui/src/components/views/board-view/kanban-board.tsx
  • apps/ui/src/lib/electron.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/routes/ideation/routes/convert.ts
  • apps/server/src/routes/ideation/routes/session-message.ts
  • apps/server/src/routes/ideation/routes/ideas-list.ts
  • apps/server/src/routes/ideation/common.ts
  • apps/server/src/routes/ideation/routes/ideas-create.ts
  • apps/server/src/routes/ideation/routes/session-start.ts
  • apps/server/src/routes/ideation/routes/session-stop.ts
  • apps/server/src/routes/ideation/routes/suggestions-generate.ts
  • apps/server/src/routes/ideation/index.ts
  • apps/server/src/routes/ideation/routes/session-get.ts
  • apps/server/src/routes/ideation/routes/ideas-delete.ts
  • apps/server/src/routes/ideation/routes/ideas-update.ts
  • apps/server/src/routes/ideation/routes/ideas-get.ts
  • apps/server/src/index.ts
  • apps/server/src/routes/ideation/routes/analyze.ts
  • apps/server/src/routes/ideation/routes/prompts.ts
  • apps/server/src/services/ideation-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/routes/ideation/routes/convert.ts
  • apps/server/src/routes/ideation/routes/session-message.ts
  • apps/server/src/routes/ideation/routes/ideas-list.ts
  • apps/server/src/routes/ideation/common.ts
  • apps/server/src/routes/ideation/routes/ideas-create.ts
  • apps/server/src/routes/ideation/routes/session-start.ts
  • apps/server/src/routes/ideation/routes/session-stop.ts
  • apps/server/src/routes/ideation/routes/suggestions-generate.ts
  • apps/ui/src/routes/ideation.tsx
  • apps/ui/src/store/ideation-store.ts
  • libs/types/src/event.ts
  • apps/server/src/routes/ideation/index.ts
  • apps/ui/src/components/ui/keyboard-map.tsx
  • apps/ui/src/components/views/ideation-view/components/prompt-category-grid.tsx
  • apps/ui/src/components/views/ideation-view/components/ideation-dashboard.tsx
  • apps/ui/src/components/layout/sidebar/hooks/use-navigation.ts
  • libs/platform/src/paths.ts
  • apps/server/src/routes/ideation/routes/session-get.ts
  • apps/server/src/routes/ideation/routes/ideas-delete.ts
  • apps/server/src/routes/ideation/routes/ideas-update.ts
  • apps/server/src/routes/ideation/routes/ideas-get.ts
  • apps/server/src/index.ts
  • apps/ui/src/components/views/ideation-view/components/prompt-list.tsx
  • apps/ui/src/store/app-store.ts
  • libs/types/src/index.ts
  • apps/ui/src/lib/http-api-client.ts
  • apps/ui/src/components/views/ideation-view/data/guided-prompts.ts
  • apps/ui/src/hooks/use-keyboard-shortcuts.ts
  • apps/server/src/routes/ideation/routes/analyze.ts
  • apps/server/src/routes/ideation/routes/prompts.ts
  • apps/ui/src/components/views/ideation-view/index.tsx
  • apps/server/src/services/ideation-service.ts
  • libs/platform/src/index.ts
  • libs/types/src/ideation.ts
  • apps/ui/src/components/views/board-view/kanban-board.tsx
  • apps/ui/src/lib/electron.ts
🧠 Learnings (3)
📚 Learning: 2025-12-28T05:07:48.147Z
Learnt from: CR
Repo: AutoMaker-Org/automaker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T05:07:48.147Z
Learning: Frontend UI must use TanStack Router for file-based routing, organize components in components/views/, implement stores with Zustand, and use custom hooks in hooks/ directory

Applied to files:

  • apps/ui/src/routes/ideation.tsx
📚 Learning: 2025-12-30T01:02:07.114Z
Learnt from: illia1f
Repo: AutoMaker-Org/automaker PR: 324
File: apps/ui/src/components/views/board-view/components/kanban-card/kanban-card.tsx:122-131
Timestamp: 2025-12-30T01:02:07.114Z
Learning: Tailwind CSS v4 uses postfix syntax for the important modifier: append ! at the end of the utility class (e.g., backdrop-blur-[0px]! or hover:bg-red-500!). The older v3 style used a prefix (!) at the start (e.g., !backdrop-blur-[0px]); prefer the postfix form for consistency across TSX files.

Applied to files:

  • apps/ui/src/routes/ideation.tsx
  • apps/ui/src/components/ui/keyboard-map.tsx
  • apps/ui/src/components/views/ideation-view/components/prompt-category-grid.tsx
  • apps/ui/src/components/views/ideation-view/components/ideation-dashboard.tsx
  • apps/ui/src/components/views/ideation-view/components/prompt-list.tsx
  • apps/ui/src/components/views/ideation-view/index.tsx
  • apps/ui/src/components/views/board-view/kanban-board.tsx
📚 Learning: 2025-12-28T05:07:48.147Z
Learnt from: CR
Repo: AutoMaker-Org/automaker PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-28T05:07:48.147Z
Learning: Applies to apps/server/src/**/*.{ts,tsx} : Use `createEventEmitter()` from `lib/events.ts` for all server operations to emit events that stream to frontend via WebSocket

Applied to files:

  • libs/types/src/event.ts
🧬 Code graph analysis (19)
apps/server/src/routes/ideation/routes/session-message.ts (3)
apps/server/src/services/ideation-service.ts (1)
  • IdeationService (52-1679)
libs/types/src/ideation.ts (1)
  • SendMessageOptions (163-166)
apps/server/src/routes/ideation/common.ts (1)
  • logError (12-12)
apps/server/src/routes/ideation/routes/ideas-list.ts (1)
apps/server/src/routes/ideation/common.ts (1)
  • logError (12-12)
apps/server/src/routes/ideation/common.ts (1)
apps/server/src/routes/common.ts (1)
  • createLogError (34-38)
apps/server/src/routes/ideation/routes/session-start.ts (1)
libs/types/src/ideation.ts (1)
  • StartSessionOptions (157-161)
apps/ui/src/routes/ideation.tsx (1)
apps/ui/src/components/views/ideation-view/index.tsx (1)
  • IdeationView (129-208)
libs/platform/src/paths.ts (1)
apps/server/src/lib/secure-fs.ts (1)
  • secureFs (8-39)
apps/server/src/routes/ideation/routes/session-get.ts (2)
apps/server/src/services/dev-server-service.ts (1)
  • isRunning (415-417)
apps/server/src/routes/ideation/common.ts (1)
  • logError (12-12)
apps/server/src/routes/ideation/routes/ideas-delete.ts (1)
apps/server/src/routes/ideation/common.ts (1)
  • logError (12-12)
apps/server/src/routes/ideation/routes/ideas-get.ts (1)
apps/server/src/routes/ideation/common.ts (1)
  • logError (12-12)
apps/ui/src/components/views/ideation-view/components/prompt-list.tsx (7)
apps/ui/src/lib/electron.ts (2)
  • IdeaCategory (46-46)
  • getElectronAPI (827-836)
libs/types/src/ideation.ts (2)
  • IdeaCategory (9-18)
  • IdeationPrompt (102-109)
libs/types/src/index.ts (2)
  • IdeaCategory (149-149)
  • IdeationPrompt (160-160)
apps/ui/src/store/ideation-store.ts (1)
  • useIdeationStore (143-324)
apps/server/src/services/ideation-service.ts (1)
  • getPromptsByCategory (901-904)
apps/ui/src/components/views/ideation-view/data/guided-prompts.ts (1)
  • getPromptsByCategory (381-383)
apps/ui/src/components/ui/card.tsx (2)
  • Card (84-84)
  • CardContent (84-84)
apps/ui/src/lib/http-api-client.ts (3)
apps/ui/src/lib/electron.ts (7)
  • IdeationAPI (58-129)
  • StartSessionOptions (51-51)
  • CreateIdeaInput (52-52)
  • UpdateIdeaInput (53-53)
  • IdeaCategory (46-46)
  • ConvertToFeatureOptions (54-54)
  • AnalysisSuggestion (50-50)
libs/types/src/ideation.ts (6)
  • StartSessionOptions (157-161)
  • CreateIdeaInput (168-179)
  • UpdateIdeaInput (181-190)
  • IdeaCategory (9-18)
  • ConvertToFeatureOptions (192-197)
  • AnalysisSuggestion (121-129)
libs/types/src/event.ts (1)
  • EventCallback (40-40)
apps/ui/src/components/views/ideation-view/data/guided-prompts.ts (3)
libs/types/src/ideation.ts (3)
  • PromptCategory (95-100)
  • IdeationPrompt (102-109)
  • IdeaCategory (9-18)
libs/types/src/index.ts (3)
  • PromptCategory (159-159)
  • IdeationPrompt (160-160)
  • IdeaCategory (149-149)
apps/server/src/services/ideation-service.ts (1)
  • getPromptsByCategory (901-904)
apps/ui/src/hooks/use-keyboard-shortcuts.ts (2)
apps/ui/src/store/app-store.ts (1)
  • DEFAULT_KEYBOARD_SHORTCUTS (184-219)
libs/types/src/index.ts (1)
  • DEFAULT_KEYBOARD_SHORTCUTS (88-88)
apps/server/src/routes/ideation/routes/analyze.ts (1)
apps/server/src/routes/ideation/common.ts (1)
  • logError (12-12)
apps/server/src/routes/ideation/routes/prompts.ts (3)
apps/server/src/routes/ideation/common.ts (1)
  • logError (12-12)
libs/types/src/ideation.ts (1)
  • IdeaCategory (9-18)
libs/types/src/index.ts (1)
  • IdeaCategory (149-149)
apps/ui/src/components/views/ideation-view/index.tsx (5)
apps/ui/src/store/ideation-store.ts (2)
  • IdeationMode (36-36)
  • useIdeationStore (143-324)
libs/types/src/ideation.ts (1)
  • IdeaCategory (9-18)
apps/ui/src/components/views/ideation-view/data/guided-prompts.ts (1)
  • getCategoryById (389-391)
apps/ui/src/components/views/ideation-view/components/prompt-category-grid.tsx (1)
  • PromptCategoryGrid (38-78)
apps/ui/src/components/views/ideation-view/components/prompt-list.tsx (1)
  • PromptList (21-162)
apps/server/src/services/ideation-service.ts (4)
libs/types/src/ideation.ts (15)
  • IdeationSession (69-77)
  • IdeationMessage (79-85)
  • StartSessionOptions (157-161)
  • IdeationSessionWithMessages (87-89)
  • SendMessageOptions (163-166)
  • CreateIdeaInput (168-179)
  • Idea (36-61)
  • UpdateIdeaInput (181-190)
  • IdeaStatus (19-19)
  • ProjectAnalysisResult (131-151)
  • IdeaCategory (9-18)
  • AnalysisSuggestion (121-129)
  • PromptCategory (95-100)
  • IdeationPrompt (102-109)
  • AnalysisFileInfo (115-119)
apps/server/src/lib/sdk-options.ts (2)
  • validateWorkingDirectory (37-49)
  • createChatOptions (500-535)
libs/platform/src/paths.ts (7)
  • ensureIdeationDir (316-323)
  • getIdeaDir (228-230)
  • getIdeaPath (241-243)
  • getIdeasDir (215-217)
  • getIdeationAnalysisPath (303-305)
  • getIdeationSessionsDir (266-268)
  • getIdeationSessionPath (279-281)
apps/server/src/providers/provider-factory.ts (1)
  • ProviderFactory (13-108)
libs/types/src/ideation.ts (2)
apps/ui/src/lib/electron.ts (10)
  • IdeaCategory (46-46)
  • Idea (45-45)
  • IdeationSession (47-47)
  • IdeationMessage (48-48)
  • AnalysisSuggestion (50-50)
  • ProjectAnalysisResult (49-49)
  • StartSessionOptions (51-51)
  • CreateIdeaInput (52-52)
  • UpdateIdeaInput (53-53)
  • ConvertToFeatureOptions (54-54)
libs/types/src/index.ts (23)
  • IdeaCategory (149-149)
  • IdeaStatus (150-150)
  • ImpactLevel (151-151)
  • EffortLevel (152-152)
  • IdeaAttachment (153-153)
  • Idea (154-154)
  • IdeationSessionStatus (155-155)
  • IdeationSession (156-156)
  • IdeationMessage (157-157)
  • IdeationSessionWithMessages (158-158)
  • PromptCategory (159-159)
  • IdeationPrompt (160-160)
  • AnalysisFileInfo (161-161)
  • AnalysisSuggestion (162-162)
  • ProjectAnalysisResult (163-163)
  • StartSessionOptions (164-164)
  • SendMessageOptions (165-165)
  • CreateIdeaInput (166-166)
  • UpdateIdeaInput (167-167)
  • ConvertToFeatureOptions (168-168)
  • IdeationEventType (169-169)
  • IdeationStreamEvent (170-170)
  • IdeationAnalysisEvent (171-171)
apps/ui/src/components/views/board-view/kanban-board.tsx (1)
apps/ui/src/components/ui/hotkey-button.tsx (1)
  • HotkeyButton (169-288)
⏰ 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 (33)
.claude/.gitignore (1)

1-1: Clarify the purpose of the hans/ directory being ignored.

The pattern is syntactically correct, but the PR description doesn't explain why this directory should be ignored. Please clarify:

  • What does the hans/ directory contain?
  • Why is it being added to .gitignore in this PR?
  • Should this have been ignored previously?

This helps ensure the change aligns with repository conventions and doesn't accidentally hide important artifacts or source files.

apps/ui/src/components/views/board-view/kanban-board.tsx (2)

8-8: LGTM: Import cleanup aligns with removed suggestions feature.

The removal of the Lightbulb icon import is consistent with eliminating the legacy feature suggestions UI.


129-142: No action needed - hotkey is correctly registered at parent level.

The hotkeyActive={false} is intentional. The shortcuts.startNext hotkey is registered globally in the parent board-view.tsx component via the useBoardKeyboardShortcuts hook (lines 800-804), which calls useKeyboardShortcuts() to listen for the key event. The HotkeyButton here is purely a UI indicator showing the available shortcut; setting hotkeyActive={false} prevents duplicate key handling. This is the correct pattern.

apps/server/src/routes/ideation/common.ts (1)

1-12: LGTM!

Clean utility module that follows the established pattern for scoped logging and error handling. The re-export approach keeps error handling consistent across ideation routes.

apps/server/src/routes/ideation/routes/prompts.ts (1)

11-22: LGTM!

The prompts handler follows best practices with proper error handling and clean response format.

libs/platform/src/paths.ts (2)

191-305: LGTM!

The ideation path utilities follow the established patterns in this module with clear documentation and proper path hierarchy. All functions are pure path builders with no I/O side effects.


316-323: LGTM!

The directory creation follows the established pattern used by ensureAutomakerDir and safely creates all necessary subdirectories with proper path validation via secureFs.

libs/platform/src/index.ts (1)

26-36: LGTM!

The new ideation path exports follow the established pattern and properly expose the utilities added to paths.ts.

apps/ui/src/components/views/ideation-view/data/guided-prompts.ts (1)

8-63: LGTM!

The PROMPT_CATEGORIES array correctly includes all 9 categories defined in the IdeaCategory type with appropriate metadata (name, icon, description).

apps/ui/src/components/ui/keyboard-map.tsx (2)

93-95: LGTM!

The new shortcut labels for ideation, githubIssues, and githubPrs are consistent with the existing naming patterns and provide clear human-readable descriptions.


121-123: LGTM!

Correctly categorized as 'navigation' shortcuts, consistent with similar navigation items like board, agent, and terminal.

apps/ui/src/routes/ideation.tsx (1)

1-6: LGTM!

Clean route definition following TanStack Router's file-based routing pattern. The component import and route configuration are correct. Based on learnings, this properly uses TanStack Router as required for frontend routing.

apps/server/src/routes/ideation/routes/ideas-list.ts (1)

9-25: LGTM!

The handler follows the established pattern for ideation routes with proper input validation and error handling. The read-only list operation correctly delegates to ideationService.getIdeas() without needing event emission.

apps/server/src/routes/ideation/routes/ideas-update.ts (1)

10-45: LGTM!

The handler follows the consistent CRUD pattern with thorough input validation for all required fields (projectPath, ideaId, updates). The 404 handling for non-existent ideas is appropriate.

apps/ui/src/components/layout/sidebar/hooks/use-navigation.ts (4)

13-13: LGTM!

Lightbulb icon is an appropriate choice for the Ideation feature.


34-36: LGTM!

Interface extension for the new shortcuts is consistent with the existing pattern.


99-104: LGTM!

The Ideation nav item is correctly structured and positioned at the top of the Tools section. The integration with the shortcuts system is properly wired.


185-192: LGTM!

GitHub navigation items now have keyboard shortcuts properly assigned, improving keyboard accessibility for the GitHub section.

apps/ui/src/components/views/ideation-view/components/prompt-category-grid.tsx (1)

1-78: LGTM!

Well-structured component with:

  • Correct use of @automaker/types for shared types (per coding guidelines)
  • Responsive grid layout with appropriate breakpoints
  • Graceful fallback to Zap icon when category icon isn't in the map
  • Clean navigation with back button
apps/ui/src/store/app-store.ts (1)

32-33: LGTM!

The addition of 'ideation' to the ViewMode union is correct and aligns with the new ideation feature being introduced.

apps/server/src/routes/ideation/routes/ideas-get.ts (1)

9-39: LGTM!

The handler implementation is correct:

  • Properly validates required fields (projectPath and ideaId)
  • Handles the not-found case with appropriate 404 response
  • Uses centralized error handling utilities
  • Response structure aligns with API conventions
apps/server/src/index.ts (1)

167-167: LGTM!

The IdeationService instantiation correctly includes the events parameter, enabling event emissions for ideation operations.

apps/server/src/routes/ideation/routes/ideas-create.ts (1)

10-42: LGTM! Clean validation and error handling.

The handler follows good practices:

  • Thorough input validation with explicit error messages
  • Consistent use of shared error utilities (logError, getErrorMessage)
  • Proper separation of concerns (delegates business logic to the service layer)

Note: Per coding guidelines, event emission for streaming to the frontend should occur within IdeationService.createIdea rather than in the route handler itself.

apps/server/src/routes/ideation/routes/session-message.ts (1)

29-34: Verify error handling for immediate failures in sendMessage.

The fire-and-forget pattern responds with { success: true } immediately, but if ideationService.sendMessage throws synchronously (e.g., session validation failure), that error will only be logged asynchronously and won't reach the client in the HTTP response.

Consider whether immediate validation errors (like invalid sessionId) should be caught and returned to the client before responding with success.

Based on coding guidelines, verify that IdeationService.sendMessage emits appropriate error events via the WebSocket connection so clients can handle failures through that channel.

apps/server/src/routes/ideation/routes/analyze.ts (2)

9-30: LGTM! Consistent async pattern for streaming operations.

The fire-and-forget pattern for analyzeProject is appropriate for long-running operations that stream results via WebSocket. Error handling uses shared utilities consistently.

Note: Similar to session-message.ts, immediate synchronous validation errors in analyzeProject won't reach the HTTP response, but this appears to be an intentional architectural pattern for streaming operations.


32-49: LGTM! Clean synchronous fetch handler.

The getCachedAnalysis handler properly awaits the result and uses consistent error handling with shared utilities.

apps/ui/src/hooks/use-keyboard-shortcuts.ts (1)

240-253: Excellent improvement for forward compatibility!

Merging with DEFAULT_KEYBOARD_SHORTCUTS ensures that newly added shortcuts (like the ideation: 'I' shortcut) are available even for users with older persisted state. The use of useMemo with proper dependencies is correct and prevents unnecessary recalculations.

The merge order { ...DEFAULT_KEYBOARD_SHORTCUTS, ...keyboardShortcuts } correctly allows user customizations to override defaults.

apps/server/src/routes/ideation/routes/session-start.ts (1)

1-30: LGTM!

The handler follows the established pattern correctly: validates required input, delegates to the service, and handles errors consistently. Import from @automaker/types aligns with coding guidelines.

apps/ui/src/components/views/ideation-view/index.tsx (1)

129-208: LGTM!

The IdeationView component is well-structured with clean navigation logic, appropriate memoization of callbacks, and good handling of the no-project state. The breadcrumb and header components provide consistent navigation patterns.

apps/server/src/routes/ideation/index.ts (1)

37-38: The handlers for /session/message and /session/stop do not expect projectPath. These endpoints work with sessionId only, which is already validated within the handlers themselves. Unlike /session/start and /session/get which operate on projects, these session-level endpoints operate on existing sessions identified by sessionId and do not require path parameter validation.

Likely an incorrect or invalid review comment.

libs/types/src/index.ts (1)

147-172: Ideation type re-exports look consistent

The new export block cleanly surfaces all ideation types from ./ideation.js and matches the definitions used across server/UI. No issues from a typing or module-resolution perspective.

apps/ui/src/components/views/ideation-view/components/prompt-list.tsx (1)

21-89: Prompt selection, job lifecycle, and error handling are solid

The prompt-selection flow (project presence check, per-prompt loading guard, generation job creation, state updates, and toast UX) is well-structured and integrates cleanly with useIdeationStore and the Electron/HTTP ideation API. The optional chaining on api.ideation plus the generic error branch keeps failures graceful.

Also applies to: 103-155

libs/types/src/ideation.ts (1)

9-61: Core ideation domain types are cohesive and match usage

The Idea/Session/Prompt/Analysis/CRUD option types are well-factored and line up with how the server and UI are using them (categories, status enums, analysis structures, etc.). No structural issues stand out here.

Also applies to: 69-151

app.use('/api/backlog-plan', createBacklogPlanRoutes(events, settingsService));
app.use('/api/mcp', createMCPRoutes(mcpTestService));
app.use('/api/pipeline', createPipelineRoutes(pipelineService));
app.use('/api/ideation', createIdeationRoutes(ideationService, featureLoader));
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check createIdeationRoutes signature and how it wires route handlers

echo "=== Checking createIdeationRoutes signature ==="
ast-grep --pattern 'export function createIdeationRoutes($$$) {
  $$$
}'

echo ""
echo "=== Checking how convert handler is wired ==="
rg -n -A5 'createConvertHandler'

echo ""
echo "=== Checking how session-stop handler is wired ==="
rg -n -A5 'createSessionStopHandler'

Repository: AutoMaker-Org/automaker

Length of output: 3553


🏁 Script executed:

#!/bin/bash
# Get full createIdeationRoutes signature
echo "=== Full createIdeationRoutes signature and start of implementation ==="
sed -n '25,35p' apps/server/src/routes/ideation/index.ts

echo ""
echo "=== Check if convert.ts uses events or createEventEmitter ==="
rg -n 'createEventEmitter|events|emit' apps/server/src/routes/ideation/routes/convert.ts

echo ""
echo "=== Check if session-stop.ts uses events or createEventEmitter ==="
rg -n 'createEventEmitter|events|emit' apps/server/src/routes/ideation/routes/session-stop.ts

echo ""
echo "=== Check entire createIdeationRoutes function parameters ==="
head -40 apps/server/src/routes/ideation/index.ts | tail -20

Repository: AutoMaker-Org/automaker

Length of output: 1350


🏁 Script executed:

#!/bin/bash
# Check context around line 221 in index.ts
echo "=== Context around line 221 in apps/server/src/index.ts ==="
sed -n '210,230p' apps/server/src/index.ts

echo ""
echo "=== Check ideationService type definition ==="
rg -A10 'class IdeationService|interface IdeationService' apps/server/src/

echo ""
echo "=== Check if events is created and available in index.ts ==="
rg -n 'const events|createEventEmitter' apps/server/src/index.ts | head -20

Repository: AutoMaker-Org/automaker

Length of output: 2278


Ensure ideation route handlers emit events to frontend via WebSocket.

The createIdeationRoutes factory should receive the events parameter and pass it to route handlers (convert, session-stop, session-start, session-message, etc.), enabling them to emit events as required by the coding guideline. While ideationService has events available, the handlers are not currently emitting any events. See how createBacklogPlanRoutes(events, settingsService) on line 219 and createGitHubRoutes(events, settingsService) on line 218 receive events explicitly.

Comment on lines 11 to 61
export function createConvertHandler(
ideationService: IdeationService,
featureLoader: FeatureLoader
) {
return async (req: Request, res: Response): Promise<void> => {
try {
const { projectPath, ideaId, keepIdea, column, dependencies, tags } = req.body as {
projectPath: string;
ideaId: string;
} & ConvertToFeatureOptions;

if (!projectPath) {
res.status(400).json({ success: false, error: 'projectPath is required' });
return;
}

if (!ideaId) {
res.status(400).json({ success: false, error: 'ideaId is required' });
return;
}

// Convert idea to feature structure
const featureData = await ideationService.convertToFeature(projectPath, ideaId);

// Apply any options from the request
if (column) {
featureData.status = column;
}
if (dependencies && dependencies.length > 0) {
featureData.dependencies = dependencies;
}
if (tags && tags.length > 0) {
featureData.tags = tags;
}

// Create the feature using FeatureLoader
const feature = await featureLoader.create(projectPath, featureData);

// Delete the idea unless keepIdea is explicitly true
if (!keepIdea) {
await ideationService.deleteIdea(projectPath, ideaId);
}

// Return featureId as expected by the frontend API interface
res.json({ success: true, featureId: feature.id });
} catch (error) {
logError(error, 'Convert to feature failed');
res.status(500).json({ success: false, error: getErrorMessage(error) });
}
};
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing event emissions for convert operation.

According to the coding guidelines, all server operations should use createEventEmitter() to emit events that stream to the frontend via WebSocket. This handler performs significant operations (converting idea to feature, creating the feature, and optionally deleting the idea) but doesn't emit any events to notify the frontend of these changes.

As per coding guidelines, "Use createEventEmitter() from lib/events.ts for all server operations to emit events that stream to frontend via WebSocket."

🔎 Proposed fix to add event emissions
 export function createConvertHandler(
   ideationService: IdeationService,
-  featureLoader: FeatureLoader
+  featureLoader: FeatureLoader,
+  events: EventEmitter
 ) {
   return async (req: Request, res: Response): Promise<void> => {
     try {
       const { projectPath, ideaId, keepIdea, column, dependencies, tags } = req.body as {
         projectPath: string;
         ideaId: string;
       } & ConvertToFeatureOptions;

       if (!projectPath) {
         res.status(400).json({ success: false, error: 'projectPath is required' });
         return;
       }

       if (!ideaId) {
         res.status(400).json({ success: false, error: 'ideaId is required' });
         return;
       }

       // Convert idea to feature structure
       const featureData = await ideationService.convertToFeature(projectPath, ideaId);

       // Apply any options from the request
       if (column) {
         featureData.status = column;
       }
       if (dependencies && dependencies.length > 0) {
         featureData.dependencies = dependencies;
       }
       if (tags && tags.length > 0) {
         featureData.tags = tags;
       }

       // Create the feature using FeatureLoader
       const feature = await featureLoader.create(projectPath, featureData);
+
+      // Emit event for feature creation
+      events.emit('feature:created', { projectPath, feature });

       // Delete the idea unless keepIdea is explicitly true
       if (!keepIdea) {
         await ideationService.deleteIdea(projectPath, ideaId);
+        // Emit event for idea deletion
+        events.emit('ideation:idea:deleted', { projectPath, ideaId });
       }

       // Return featureId as expected by the frontend API interface
       res.json({ success: true, featureId: feature.id });
     } catch (error) {
       logError(error, 'Convert to feature failed');
       res.status(500).json({ success: false, error: getErrorMessage(error) });
     }
   };
 }

Note: You'll also need to update the route wiring in apps/server/src/routes/ideation/index.ts to pass the events parameter.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines 9 to 26
export function createSessionStopHandler(ideationService: IdeationService) {
return async (req: Request, res: Response): Promise<void> => {
try {
const { sessionId } = req.body as { sessionId: string };

if (!sessionId) {
res.status(400).json({ success: false, error: 'sessionId is required' });
return;
}

await ideationService.stopSession(sessionId);
res.json({ success: true });
} catch (error) {
logError(error, 'Stop session failed');
res.status(500).json({ success: false, error: getErrorMessage(error) });
}
};
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Missing event emissions for session stop operation.

According to the coding guidelines, all server operations should use createEventEmitter() to emit events that stream to the frontend via WebSocket. This handler stops an ideation session but doesn't emit any events to notify the frontend of this state change.

As per coding guidelines, "Use createEventEmitter() from lib/events.ts for all server operations to emit events that stream to frontend via WebSocket."

🔎 Proposed fix to add event emission
-export function createSessionStopHandler(ideationService: IdeationService) {
+export function createSessionStopHandler(ideationService: IdeationService, events: EventEmitter) {
   return async (req: Request, res: Response): Promise<void> => {
     try {
       const { sessionId } = req.body as { sessionId: string };

       if (!sessionId) {
         res.status(400).json({ success: false, error: 'sessionId is required' });
         return;
       }

       await ideationService.stopSession(sessionId);
+      
+      // Emit event for session stop
+      events.emit('ideation:session:stopped', { sessionId });
+      
       res.json({ success: true });
     } catch (error) {
       logError(error, 'Stop session failed');
       res.status(500).json({ success: false, error: getErrorMessage(error) });
     }
   };
 }

Note: You'll also need to update the route wiring in apps/server/src/routes/ideation/index.ts to pass the events parameter.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/server/src/routes/ideation/routes/session-stop.ts around lines 9 to 26,
the handler stops a session but does not emit any events; update the handler to
create an event emitter via createEventEmitter() (imported from lib/events.ts),
use it to emit a session-stopped event (including sessionId and relevant
metadata) after ideationService.stopSession(sessionId) succeeds, and ensure
errors still log and respond as before; also update
apps/server/src/routes/ideation/index.ts to accept and pass the events emitter
into this route when wiring handlers.

Comment on lines 145 to 223
async sendMessage(
sessionId: string,
message: string,
options?: SendMessageOptions
): Promise<void> {
const activeSession = this.activeSessions.get(sessionId);
if (!activeSession) {
throw new Error(`Session ${sessionId} not found`);
}

if (activeSession.isRunning) {
throw new Error('Session is already processing a message');
}

activeSession.isRunning = true;
activeSession.abortController = new AbortController();

// Add user message
const userMessage: IdeationMessage = {
id: this.generateId('msg'),
role: 'user',
content: message,
timestamp: new Date().toISOString(),
};
activeSession.messages.push(userMessage);

// Emit user message
this.events.emit('ideation:stream', {
sessionId,
type: 'message',
message: userMessage,
});

try {
const projectPath = activeSession.session.projectPath;

// Build conversation history
const conversationHistory = activeSession.messages.slice(0, -1).map((msg) => ({
role: msg.role,
content: msg.content,
}));

// Load context files
const contextResult = await loadContextFiles({
projectPath,
fsModule: secureFs as Parameters<typeof loadContextFiles>[0]['fsModule'],
});

// Gather existing features and ideas to prevent duplicate suggestions
const existingWorkContext = await this.gatherExistingWorkContext(projectPath);

// Build system prompt for ideation
const systemPrompt = this.buildIdeationSystemPrompt(
contextResult.formattedPrompt,
activeSession.session.promptCategory,
existingWorkContext
);

// Create SDK options
const sdkOptions = createChatOptions({
cwd: projectPath,
model: options?.model || 'sonnet',
systemPrompt,
abortController: activeSession.abortController!,
});

const effectiveModel = sdkOptions.model!;
const provider = ProviderFactory.getProviderForModel(effectiveModel);

const executeOptions: ExecuteOptions = {
prompt: message,
model: effectiveModel,
cwd: projectPath,
systemPrompt: sdkOptions.systemPrompt,
maxTurns: 1, // Single turn for ideation
abortController: activeSession.abortController!,
conversationHistory: conversationHistory.length > 0 ? conversationHistory : undefined,
};

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Normalize model aliases with resolveModelString before creating chat options

Both sendMessage and generateSuggestions currently pass raw aliases like 'sonnet' into createChatOptions:

const sdkOptions = createChatOptions({
  cwd: projectPath,
  model: options?.model || 'sonnet', // sendMessage
  ...
});

// and

const sdkOptions = createChatOptions({
  cwd: projectPath,
  model: 'sonnet', // generateSuggestions
  ...
});

Per the repo guidelines for *.ts files, you should resolve aliases (haiku, sonnet, opus, etc.) via resolveModelString() from @automaker/model-resolver before handing them to the SDK/provider. That also guarantees ProviderFactory.getProviderForModel(effectiveModel) always sees a canonical model ID.

Consider something along the lines of:

import { resolveModelString } from '@automaker/model-resolver';

// …

const modelId = resolveModelString(options?.model ?? 'sonnet');

const sdkOptions = createChatOptions({
  cwd: projectPath,
  model: modelId,
  systemPrompt,
  abortController: activeSession.abortController!,
});

and similarly for generateSuggestions, using a resolved default model.

Also applies to: 598-669

🤖 Prompt for AI Agents
In apps/server/src/services/ideation-service.ts around lines 145 to 223 (and
also apply same fix at ~598-669), the code passes raw model aliases like
'sonnet' into createChatOptions and ProviderFactory; resolveModelString from
@automaker/model-resolver should be used first. Import resolveModelString,
compute const modelId = resolveModelString(options?.model ?? 'sonnet') (or
resolve default for generateSuggestions), pass modelId into createChatOptions,
and then use the resolved modelId when calling
ProviderFactory.getProviderForModel and setting executeOptions.model so the SDK
and provider always receive a canonical model identifier.

Comment on lines +158 to +160
ideation: string;
githubIssues: string;
githubPrs: string;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, locate and examine the app-store.ts file
find . -name "app-store.ts" -type f

Repository: AutoMaker-Org/automaker

Length of output: 99


🏁 Script executed:

cat -n ./apps/ui/src/store/app-store.ts | head -250

Repository: AutoMaker-Org/automaker

Length of output: 8421


🏁 Script executed:

# Search for keyboard shortcut usage - where githubIssues and startNext are actually bound/handled
echo "=== Searching for keyboard shortcut binding/event handling ==="
rg -n --type=ts --type=tsx "githubIssues|startNext" --context=5 | head -100

Repository: AutoMaker-Org/automaker

Length of output: 174


🏁 Script executed:

# Search for githubIssues and startNext usage without file type restrictions
echo "=== Searching for githubIssues usage ==="
rg -n "githubIssues" --context=3 | head -80

echo ""
echo "=== Searching for startNext usage ==="
rg -n "startNext" --context=3 | head -80

Repository: AutoMaker-Org/automaker

Length of output: 8959


🏁 Script executed:

# Search for keyboard event handling hooks and where shortcuts are actually bound
echo "=== Searching for useKeyboardShortcuts hook ==="
fd -t f "use.*keyboard" --type f | xargs head -100

echo ""
echo "=== Searching for keyboard event listeners and context handling ==="
rg -n "addEventListener.*keydown|onKeyDown|useEffect.*keyboard" --context=2 | head -100

Repository: AutoMaker-Org/automaker

Length of output: 13694


🏁 Script executed:

# Read the full use-keyboard-shortcuts.ts file to understand the global keyboard handler
cat -n apps/ui/src/hooks/use-keyboard-shortcuts.ts | tail -150

Repository: AutoMaker-Org/automaker

Length of output: 5707


🏁 Script executed:

# Search for where navigation items and their shortcuts are used to handle keyboard events
echo "=== Searching for navigation shortcut handling ==="
rg -n "use-navigation" --type ts | head -20

echo ""
echo "=== Searching for handler of github navigation shortcuts ==="
rg -n "github|Issues.*navigate|viewMode.*github" --context=3 | head -100

echo ""
echo "=== Checking if there's a global keyboard shortcut handler for navigation ==="
rg -n "useKeyboardShortcuts.*navigation|navigation.*shortcut" --context=5 | head -80

Repository: AutoMaker-Org/automaker

Length of output: 7778


🏁 Script executed:

# Find where navigationShortcuts is defined in use-navigation
cat -n apps/ui/src/components/layout/sidebar/hooks/use-navigation.ts | head -250

Repository: AutoMaker-Org/automaker

Length of output: 8156


🏁 Script executed:

# Continue reading use-navigation.ts to see where githubIssues shortcut is registered
cat -n apps/ui/src/components/layout/sidebar/hooks/use-navigation.ts | sed -n '250,350p'

Repository: AutoMaker-Org/automaker

Length of output: 1339


Add context restriction for githubIssues shortcut to prevent conflict with startNext.

Both githubIssues (line 194) and startNext (line 205) use the 'G' key. While startNext is explicitly documented as "Only active in board view" (line 205), githubIssues is registered globally whenever a project has a GitHub remote. When in the board view with a GitHub-enabled project, both shortcuts fire simultaneously, creating unpredictable behavior.

Either restrict githubIssues to activate only outside board view, change its key binding, or add a modifier. Update the default shortcut assignment (lines 193-195) and add a clarifying comment to document the context restriction.

- Add 28 unit tests covering all major IdeationService functionality
- Test session management (start, get, stop, running state)
- Test idea CRUD operations (create, read, update, delete, archive)
- Test idea to feature conversion with user stories and notes
- Test project analysis and caching
- Test prompt management and filtering
- Test AI-powered suggestion generation
- Mock all external dependencies (fs, platform, utils, providers)

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

Co-authored-by: Web Dev Cody <webdevcody@users.noreply.github.com>
@webdevcody webdevcody changed the base branch from main to v0.8.0rc January 4, 2026 05:17
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: 1

🧹 Nitpick comments (3)
apps/server/tests/unit/services/ideation-service.test.ts (3)

23-29: Consider using a model constant for the mock.

The hardcoded model string 'claude-sonnet-4-20250514' in the mock is acceptable for test context, but consider extracting it to a constant if this model string is used elsewhere in tests to ease future updates.


127-155: Avoid flaky setTimeout for async coordination.

Using setTimeout(resolve, 10) to wait for async processing is fragile and can cause intermittent test failures. Consider using vi.waitFor() or returning/awaiting the actual promise from the service method.

🔎 Suggested improvement using vi.waitFor
         await service.startSession(testProjectPath, options);

-        // Give time for the async message to process
-        await new Promise((resolve) => setTimeout(resolve, 10));
+        // Wait for the async message to be processed
+        await vi.waitFor(() => {
+          expect(mockProvider.executeQuery).toHaveBeenCalled();
+        });

-        expect(mockProvider.executeQuery).toHaveBeenCalled();
       });

302-305: Type assertions for mock directory entries are acceptable.

The as any assertions for mock Dirent objects are a pragmatic approach when only specific properties (name, isDirectory) are needed. For improved type safety, you could create a helper function that returns properly typed mock directory entries.

🔎 Optional: Helper for typed mock directory entries
// Add at top of describe block or in a test utilities file
const mockDirent = (name: string, isDir: boolean) => ({
  name,
  isDirectory: () => isDir,
  isFile: () => !isDir,
  isBlockDevice: () => false,
  isCharacterDevice: () => false,
  isSymbolicLink: () => false,
  isFIFO: () => false,
  isSocket: () => false,
} as import('fs').Dirent);

Also applies to: 344-347

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3512749 and abddfad.

📒 Files selected for processing (1)
  • apps/server/tests/unit/services/ideation-service.test.ts
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always import from shared packages (@automaker/*), never from old relative paths

Files:

  • apps/server/tests/unit/services/ideation-service.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:

  • apps/server/tests/unit/services/ideation-service.test.ts
🪛 GitHub Actions: Format Check
apps/server/tests/unit/services/ideation-service.test.ts

[warning] 1-1: Prettier reported code style issues in this file. Run 'prettier --write' to fix.

⏰ 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 (8)
apps/server/tests/unit/services/ideation-service.test.ts (8)

1-16: Imports follow appropriate patterns.

The imports correctly use @automaker/* packages for shared code (platform, utils, types) and path aliases (@/) for internal server modules. This aligns with the coding guidelines to avoid old relative paths.


38-86: Test setup is well-structured.

The beforeEach properly clears mocks, creates mock dependencies, and configures platform/utils mocks. The afterEach correctly restores mocks. Good separation of concerns.


92-230: Session management tests are comprehensive.

Good coverage of session lifecycle including start, get, stop, and running state checks. Tests appropriately verify event emissions, persistence, and edge cases (non-existent sessions).


236-487: Ideas CRUD tests provide solid coverage.

Tests cover creation with required/optional fields, retrieval (including sorting by updatedAt), updates, deletion, and archiving. Edge cases for invalid files and non-existent ideas are handled well.


493-575: Conversion tests verify the idea-to-feature mapping thoroughly.

Tests confirm category mapping, user stories inclusion, notes inclusion, and error handling for non-existent ideas. Good validation of the transformed feature structure.


581-654: Project analysis tests verify event lifecycle and caching.

Tests confirm analysis-started/complete events are emitted, error events on failure, and cache retrieval behavior. Good coverage.


660-704: Prompt management tests are adequate.

Tests verify category retrieval, all prompts retrieval, and filtering by category. The as any assertion on line 699 is appropriate for testing non-existent category behavior.


710-762: Suggestion generation tests cover the happy path and error case.

Tests verify event emission on generation start and proper error handling for non-existent prompts.

@@ -0,0 +1,763 @@
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix Prettier formatting issues.

The pipeline reports formatting violations. Run prettier --write on this file to resolve the code style issues before merging.

#!/bin/bash
# Check current Prettier violations in this file
npx prettier --check "apps/server/tests/unit/services/ideation-service.test.ts" 2>&1 || true
🧰 Tools
🪛 GitHub Actions: Format Check

[warning] 1-1: Prettier reported code style issues in this file. Run 'prettier --write' to fix.

🤖 Prompt for AI Agents
In apps/server/tests/unit/services/ideation-service.test.ts around lines 1 to 1,
the file fails Prettier formatting checks; run Prettier to fix style violations
by executing a format command (e.g., npx prettier --write
apps/server/tests/unit/services/ideation-service.test.ts) or integrate your
editor/IDE formatter, then stage the formatted file and re-run the pipeline to
ensure the formatting errors are resolved.

…tionService

- Changed the category mapping for 'feature' from 'feature' to 'ui'.
- Updated ID generation format to use hyphens instead of underscores for better readability.
- Enhanced unit tests to reflect the updated category and ensure proper functionality.
…feature

- Updated the ideation routes to include an EventEmitter for better event management.
- Added a new endpoint to handle adding suggestions to the board, ensuring consistent category mapping.
- Modified existing routes to emit events for idea creation, update, and deletion, improving frontend notifications.
- Refactored the convert and create idea handlers to utilize the new event system.
- Removed static guided prompts data in favor of dynamic fetching from the backend API.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant