feat: implement ideation feature for brainstorming and idea management

- 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.
This commit is contained in:
webdevcody
2026-01-03 02:58:43 -05:00
parent 2bbc8113c0
commit ff281e23d0
44 changed files with 4495 additions and 711 deletions

View File

@@ -13,6 +13,16 @@ import type {
AgentModel,
GitHubComment,
IssueCommentsResult,
Idea,
IdeaCategory,
IdeationSession,
IdeationMessage,
ProjectAnalysisResult,
AnalysisSuggestion,
StartSessionOptions,
CreateIdeaInput,
UpdateIdeaInput,
ConvertToFeatureOptions,
} from '@automaker/types';
import { getJSON, setJSON, removeItem } from './storage';
@@ -30,6 +40,94 @@ export type {
IssueCommentsResult,
};
// Re-export ideation types
export type {
Idea,
IdeaCategory,
IdeationSession,
IdeationMessage,
ProjectAnalysisResult,
AnalysisSuggestion,
StartSessionOptions,
CreateIdeaInput,
UpdateIdeaInput,
ConvertToFeatureOptions,
};
// Ideation API interface
export interface IdeationAPI {
// Session management
startSession: (
projectPath: string,
options?: StartSessionOptions
) => Promise<{ success: boolean; session?: IdeationSession; error?: string }>;
getSession: (
projectPath: string,
sessionId: string
) => Promise<{
success: boolean;
session?: IdeationSession;
messages?: IdeationMessage[];
error?: string;
}>;
sendMessage: (
sessionId: string,
message: string,
options?: { imagePaths?: string[]; model?: string }
) => Promise<{ success: boolean; error?: string }>;
stopSession: (sessionId: string) => Promise<{ success: boolean; error?: string }>;
// Ideas CRUD
listIdeas: (projectPath: string) => Promise<{ success: boolean; ideas?: Idea[]; error?: string }>;
createIdea: (
projectPath: string,
idea: CreateIdeaInput
) => Promise<{ success: boolean; idea?: Idea; error?: string }>;
getIdea: (
projectPath: string,
ideaId: string
) => Promise<{ success: boolean; idea?: Idea; error?: string }>;
updateIdea: (
projectPath: string,
ideaId: string,
updates: UpdateIdeaInput
) => Promise<{ success: boolean; idea?: Idea; error?: string }>;
deleteIdea: (
projectPath: string,
ideaId: string
) => Promise<{ success: boolean; error?: string }>;
// Project analysis
analyzeProject: (
projectPath: string
) => Promise<{ success: boolean; analysis?: ProjectAnalysisResult; error?: string }>;
// Generate suggestions from a prompt
generateSuggestions: (
projectPath: string,
promptId: string,
category: IdeaCategory,
count?: number
) => Promise<{ success: boolean; suggestions?: AnalysisSuggestion[]; error?: string }>;
// Convert to feature
convertToFeature: (
projectPath: string,
ideaId: string,
options?: ConvertToFeatureOptions
) => Promise<{ success: boolean; feature?: any; featureId?: string; error?: string }>;
// Add suggestion directly to board as feature
addSuggestionToBoard: (
projectPath: string,
suggestion: AnalysisSuggestion
) => Promise<{ success: boolean; featureId?: string; error?: string }>;
// Event subscriptions
onStream: (callback: (event: any) => void) => () => void;
onAnalysisEvent: (callback: (event: any) => void) => () => void;
}
export interface FileEntry {
name: string;
isDirectory: boolean;
@@ -647,6 +745,7 @@ export interface ElectronAPI {
error?: string;
}>;
};
ideation?: IdeationAPI;
}
// Note: Window interface is declared in @/types/electron.d.ts

View File

@@ -26,6 +26,13 @@ import type {
GitHubPR,
IssueValidationInput,
IssueValidationEvent,
IdeationAPI,
IdeaCategory,
AnalysisSuggestion,
StartSessionOptions,
CreateIdeaInput,
UpdateIdeaInput,
ConvertToFeatureOptions,
} from './electron';
import type { Message, SessionListItem } from '@/types/electron';
import type { Feature, ClaudeUsageResponse } from '@/store/app-store';
@@ -368,7 +375,9 @@ type EventType =
| 'suggestions:event'
| 'spec-regeneration:event'
| 'issue-validation:event'
| 'backlog-plan:event';
| 'backlog-plan:event'
| 'ideation:stream'
| 'ideation:analysis';
type EventCallback = (payload: unknown) => void;
@@ -1640,6 +1649,88 @@ export class HttpApiClient implements ElectronAPI {
},
};
// Ideation API - brainstorming and idea management
ideation: IdeationAPI = {
startSession: (projectPath: string, options?: StartSessionOptions) =>
this.post('/api/ideation/session/start', { projectPath, options }),
getSession: (projectPath: string, sessionId: string) =>
this.post('/api/ideation/session/get', { projectPath, sessionId }),
sendMessage: (
sessionId: string,
message: string,
options?: { imagePaths?: string[]; model?: string }
) => this.post('/api/ideation/session/message', { sessionId, message, options }),
stopSession: (sessionId: string) => this.post('/api/ideation/session/stop', { sessionId }),
listIdeas: (projectPath: string) => this.post('/api/ideation/ideas/list', { projectPath }),
createIdea: (projectPath: string, idea: CreateIdeaInput) =>
this.post('/api/ideation/ideas/create', { projectPath, idea }),
getIdea: (projectPath: string, ideaId: string) =>
this.post('/api/ideation/ideas/get', { projectPath, ideaId }),
updateIdea: (projectPath: string, ideaId: string, updates: UpdateIdeaInput) =>
this.post('/api/ideation/ideas/update', { projectPath, ideaId, updates }),
deleteIdea: (projectPath: string, ideaId: string) =>
this.post('/api/ideation/ideas/delete', { projectPath, ideaId }),
analyzeProject: (projectPath: string) => this.post('/api/ideation/analyze', { projectPath }),
generateSuggestions: (
projectPath: string,
promptId: string,
category: IdeaCategory,
count?: number
) =>
this.post('/api/ideation/suggestions/generate', { projectPath, promptId, category, count }),
convertToFeature: (projectPath: string, ideaId: string, options?: ConvertToFeatureOptions) =>
this.post('/api/ideation/convert', { projectPath, ideaId, ...options }),
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,
};
},
onStream: (callback: (event: any) => void): (() => void) => {
return this.subscribeToEvent('ideation:stream', callback as EventCallback);
},
onAnalysisEvent: (callback: (event: any) => void): (() => void) => {
return this.subscribeToEvent('ideation:analysis', callback as EventCallback);
},
};
// MCP API - Test MCP server connections and list tools
// SECURITY: Only accepts serverId, not arbitrary serverConfig, to prevent
// drive-by command execution attacks. Servers must be saved first.