Merge v0.8.0rc into feat/cursor-cli

Resolved conflicts:
- sdk-options.ts: kept HEAD (MCP & thinking level features)
- auto-mode-service.ts: kept HEAD (MCP features + fallback code)
- agent-output-modal.tsx: used v0.8.0rc (effectiveViewMode + pr-8 spacing)
- feature-suggestions-dialog.tsx: accepted deletion
- electron.ts: used v0.8.0rc (Ideation types)
- package-lock.json: regenerated

Fixed sdk-options.test.ts to expect 'default' permissionMode for read-only operations.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Kacper
2026-01-04 13:12:45 +01:00
81 changed files with 6933 additions and 1958 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,19 @@ 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'
| 'ideation:idea-created'
| 'ideation:idea-updated'
| 'ideation:idea-deleted'
| 'ideation:idea-converted';
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

@@ -167,3 +167,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';

View File

@@ -73,8 +73,6 @@ export interface ExecuteOptions {
maxTurns?: number;
allowedTools?: string[];
mcpServers?: Record<string, McpServerConfig>;
mcpAutoApproveTools?: boolean; // Auto-approve MCP tool calls without permission prompts
mcpUnrestrictedTools?: boolean; // Allow unrestricted tools when MCP servers are enabled
abortController?: AbortController;
conversationHistory?: ConversationMessage[]; // Previous messages for context
sdkSessionId?: string; // Claude SDK session ID for resuming conversations

View File

@@ -482,10 +482,6 @@ export interface GlobalSettings {
// MCP Server Configuration
/** List of configured MCP servers for agent use */
mcpServers: MCPServerConfig[];
/** Auto-approve MCP tool calls without permission prompts (uses bypassPermissions mode) */
mcpAutoApproveTools?: boolean;
/** Allow unrestricted tools when MCP servers are enabled (don't filter allowedTools) */
mcpUnrestrictedTools?: boolean;
// Prompt Customization
/** Custom prompts for Auto Mode, Agent Runner, Backlog Planning, and Enhancements */
@@ -679,10 +675,6 @@ export const DEFAULT_GLOBAL_SETTINGS: GlobalSettings = {
enableSandboxMode: false,
skipSandboxWarning: false,
mcpServers: [],
// Default to true for autonomous workflow. Security is enforced when adding servers
// via the security warning dialog that explains the risks.
mcpAutoApproveTools: true,
mcpUnrestrictedTools: true,
};
/** Default credentials (empty strings - user must provide API keys) */