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

@@ -23,6 +23,17 @@ export {
getCredentialsPath,
getProjectSettingsPath,
ensureDataDir,
// Ideation paths
getIdeationDir,
getIdeasDir,
getIdeaDir,
getIdeaPath,
getIdeaAttachmentsDir,
getIdeationSessionsDir,
getIdeationSessionPath,
getIdeationDraftsDir,
getIdeationAnalysisPath,
ensureIdeationDir,
} from './paths.js';
// Subprocess management

View File

@@ -188,6 +188,140 @@ export async function ensureAutomakerDir(projectPath: string): Promise<string> {
return automakerDir;
}
// ============================================================================
// Ideation Paths
// ============================================================================
/**
* Get the ideation directory for a project
*
* Contains ideas, sessions, and drafts for brainstorming.
*
* @param projectPath - Absolute path to project directory
* @returns Absolute path to {projectPath}/.automaker/ideation
*/
export function getIdeationDir(projectPath: string): string {
return path.join(getAutomakerDir(projectPath), 'ideation');
}
/**
* Get the ideas directory for a project
*
* Contains subdirectories for each idea, keyed by ideaId.
*
* @param projectPath - Absolute path to project directory
* @returns Absolute path to {projectPath}/.automaker/ideation/ideas
*/
export function getIdeasDir(projectPath: string): string {
return path.join(getIdeationDir(projectPath), 'ideas');
}
/**
* Get the directory for a specific idea
*
* Contains idea metadata and attachments.
*
* @param projectPath - Absolute path to project directory
* @param ideaId - Idea identifier
* @returns Absolute path to {projectPath}/.automaker/ideation/ideas/{ideaId}
*/
export function getIdeaDir(projectPath: string, ideaId: string): string {
return path.join(getIdeasDir(projectPath), ideaId);
}
/**
* Get the idea metadata file path
*
* Stores the idea JSON data.
*
* @param projectPath - Absolute path to project directory
* @param ideaId - Idea identifier
* @returns Absolute path to {projectPath}/.automaker/ideation/ideas/{ideaId}/idea.json
*/
export function getIdeaPath(projectPath: string, ideaId: string): string {
return path.join(getIdeaDir(projectPath, ideaId), 'idea.json');
}
/**
* Get the idea attachments directory
*
* Stores images and other attachments for an idea.
*
* @param projectPath - Absolute path to project directory
* @param ideaId - Idea identifier
* @returns Absolute path to {projectPath}/.automaker/ideation/ideas/{ideaId}/attachments
*/
export function getIdeaAttachmentsDir(projectPath: string, ideaId: string): string {
return path.join(getIdeaDir(projectPath, ideaId), 'attachments');
}
/**
* Get the ideation sessions directory for a project
*
* Contains conversation history for ideation sessions.
*
* @param projectPath - Absolute path to project directory
* @returns Absolute path to {projectPath}/.automaker/ideation/sessions
*/
export function getIdeationSessionsDir(projectPath: string): string {
return path.join(getIdeationDir(projectPath), 'sessions');
}
/**
* Get the session file path for an ideation session
*
* Stores the session messages and metadata.
*
* @param projectPath - Absolute path to project directory
* @param sessionId - Session identifier
* @returns Absolute path to {projectPath}/.automaker/ideation/sessions/{sessionId}.json
*/
export function getIdeationSessionPath(projectPath: string, sessionId: string): string {
return path.join(getIdeationSessionsDir(projectPath), `${sessionId}.json`);
}
/**
* Get the ideation drafts directory for a project
*
* Stores unsaved conversation drafts.
*
* @param projectPath - Absolute path to project directory
* @returns Absolute path to {projectPath}/.automaker/ideation/drafts
*/
export function getIdeationDraftsDir(projectPath: string): string {
return path.join(getIdeationDir(projectPath), 'drafts');
}
/**
* Get the project analysis result file path
*
* Stores the cached project analysis result.
*
* @param projectPath - Absolute path to project directory
* @returns Absolute path to {projectPath}/.automaker/ideation/analysis.json
*/
export function getIdeationAnalysisPath(projectPath: string): string {
return path.join(getIdeationDir(projectPath), 'analysis.json');
}
/**
* Create the ideation directory structure for a project if it doesn't exist
*
* Creates {projectPath}/.automaker/ideation with all subdirectories.
* Safe to call multiple times - uses recursive: true.
*
* @param projectPath - Absolute path to project directory
* @returns Promise resolving to the created ideation directory path
*/
export async function ensureIdeationDir(projectPath: string): Promise<string> {
const ideationDir = getIdeationDir(projectPath);
await secureFs.mkdir(ideationDir, { recursive: true });
await secureFs.mkdir(getIdeasDir(projectPath), { recursive: true });
await secureFs.mkdir(getIdeationSessionsDir(projectPath), { recursive: true });
await secureFs.mkdir(getIdeationDraftsDir(projectPath), { recursive: true });
return ideationDir;
}
// ============================================================================
// Global Settings Paths (stored in DATA_DIR from app.getPath('userData'))
// ============================================================================

View File

@@ -26,6 +26,15 @@ export type EventType =
| 'project:analysis-error'
| 'suggestions:event'
| 'spec-regeneration:event'
| 'issue-validation:event';
| 'issue-validation:event'
| 'ideation:stream'
| 'ideation:session-started'
| 'ideation:session-ended'
| 'ideation:analysis'
| 'ideation:analysis-started'
| 'ideation:analysis-progress'
| 'ideation:analysis-complete'
| 'ideation:analysis-error'
| 'ideation:suggestions';
export type EventCallback = (type: EventType, payload: unknown) => void;

230
libs/types/src/ideation.ts Normal file
View File

@@ -0,0 +1,230 @@
/**
* Ideation types for AutoMaker brainstorming and idea management
*/
// ============================================================================
// Core Types
// ============================================================================
export type IdeaCategory =
| 'feature'
| 'ux-ui'
| 'dx'
| 'growth'
| 'technical'
| 'security'
| 'performance'
| 'accessibility'
| 'analytics';
export type IdeaStatus = 'raw' | 'refined' | 'ready' | 'archived';
export type ImpactLevel = 'low' | 'medium' | 'high';
export type EffortLevel = 'low' | 'medium' | 'high';
// ============================================================================
// Idea Entity
// ============================================================================
export interface IdeaAttachment {
id: string;
type: 'image' | 'link' | 'reference';
path?: string;
url?: string;
description?: string;
[key: string]: unknown;
}
export interface Idea {
id: string;
title: string;
description: string;
category: IdeaCategory;
status: IdeaStatus;
impact: ImpactLevel;
effort: EffortLevel;
// Conversation context
conversationId?: string;
sourcePromptId?: string;
// Content
attachments?: IdeaAttachment[];
userStories?: string[];
notes?: string;
// Metadata
createdAt: string;
updatedAt: string;
archivedAt?: string;
// Extensibility
[key: string]: unknown;
}
// ============================================================================
// Ideation Session
// ============================================================================
export type IdeationSessionStatus = 'active' | 'completed' | 'abandoned';
export interface IdeationSession {
id: string;
projectPath: string;
promptCategory?: IdeaCategory;
promptId?: string;
status: IdeationSessionStatus;
createdAt: string;
updatedAt: string;
}
export interface IdeationMessage {
id: string;
role: 'user' | 'assistant';
content: string;
timestamp: string;
savedAsIdeaId?: string;
}
export interface IdeationSessionWithMessages extends IdeationSession {
messages: IdeationMessage[];
}
// ============================================================================
// Guided Prompts
// ============================================================================
export interface PromptCategory {
id: IdeaCategory;
name: string;
icon: string;
description: string;
}
export interface IdeationPrompt {
id: string;
category: IdeaCategory;
title: string;
description: string;
prompt: string;
icon?: string;
}
// ============================================================================
// Project Analysis
// ============================================================================
export interface AnalysisFileInfo {
path: string;
type: 'route' | 'component' | 'service' | 'model' | 'config' | 'test' | 'other';
name: string;
}
export interface AnalysisSuggestion {
id: string;
category: IdeaCategory;
title: string;
description: string;
rationale: string;
relatedFiles?: string[];
priority: 'high' | 'medium' | 'low';
}
export interface ProjectAnalysisResult {
projectPath: string;
analyzedAt: string;
// Structure analysis
totalFiles: number;
routes: AnalysisFileInfo[];
components: AnalysisFileInfo[];
services: AnalysisFileInfo[];
// Tech stack detection
framework?: string;
language?: string;
dependencies?: string[];
// AI-generated suggestions
suggestions: AnalysisSuggestion[];
// Summary
summary: string;
}
// ============================================================================
// API Types
// ============================================================================
export interface StartSessionOptions {
promptId?: string;
promptCategory?: IdeaCategory;
initialMessage?: string;
}
export interface SendMessageOptions {
imagePaths?: string[];
model?: string;
}
export interface CreateIdeaInput {
title: string;
description: string;
category: IdeaCategory;
status?: IdeaStatus;
impact?: ImpactLevel;
effort?: EffortLevel;
conversationId?: string;
sourcePromptId?: string;
userStories?: string[];
notes?: string;
}
export interface UpdateIdeaInput {
title?: string;
description?: string;
category?: IdeaCategory;
status?: IdeaStatus;
impact?: ImpactLevel;
effort?: EffortLevel;
userStories?: string[];
notes?: string;
}
export interface ConvertToFeatureOptions {
column?: string;
dependencies?: string[];
tags?: string[];
keepIdea?: boolean;
}
// ============================================================================
// Event Types
// ============================================================================
export type IdeationEventType =
| 'ideation:stream'
| 'ideation:session-started'
| 'ideation:session-ended'
| 'ideation:analysis-started'
| 'ideation:analysis-progress'
| 'ideation:analysis-complete'
| 'ideation:analysis-error';
export interface IdeationStreamEvent {
type: 'ideation:stream';
sessionId: string;
content: string;
done: boolean;
}
export interface IdeationAnalysisEvent {
type:
| 'ideation:analysis-started'
| 'ideation:analysis-progress'
| 'ideation:analysis-complete'
| 'ideation:analysis-error';
projectPath: string;
progress?: number;
message?: string;
result?: ProjectAnalysisResult;
error?: string;
}

View File

@@ -143,3 +143,30 @@ export type {
// Port configuration
export { STATIC_PORT, SERVER_PORT, RESERVED_PORTS } from './ports.js';
// Ideation types
export type {
IdeaCategory,
IdeaStatus,
ImpactLevel,
EffortLevel,
IdeaAttachment,
Idea,
IdeationSessionStatus,
IdeationSession,
IdeationMessage,
IdeationSessionWithMessages,
PromptCategory,
IdeationPrompt,
AnalysisFileInfo,
AnalysisSuggestion,
ProjectAnalysisResult,
StartSessionOptions,
SendMessageOptions,
CreateIdeaInput,
UpdateIdeaInput,
ConvertToFeatureOptions,
IdeationEventType,
IdeationStreamEvent,
IdeationAnalysisEvent,
} from './ideation.js';