Merge remote-tracking branch 'upstream/v0.13.0rc' into feat/react-query

# Conflicts:
#	apps/ui/src/components/views/board-view.tsx
#	apps/ui/src/components/views/board-view/dialogs/agent-output-modal.tsx
#	apps/ui/src/components/views/board-view/hooks/use-board-features.ts
#	apps/ui/src/components/views/board-view/worktree-panel/worktree-panel.tsx
#	apps/ui/src/hooks/use-project-settings-loader.ts
This commit is contained in:
DhanushSantosh
2026-01-20 19:19:21 +05:30
76 changed files with 5995 additions and 492 deletions

View File

@@ -28,6 +28,7 @@ import type {
UpdateIdeaInput,
ConvertToFeatureOptions,
} from '@automaker/types';
import { DEFAULT_MAX_CONCURRENCY } from '@automaker/types';
import { getJSON, setJSON, removeItem } from './storage';
// Re-export issue validation types for use in components
@@ -479,20 +480,26 @@ export interface FeaturesAPI {
featureId: string
) => Promise<{ success: boolean; content?: string | null; error?: string }>;
generateTitle: (
description: string
description: string,
projectPath?: string
) => Promise<{ success: boolean; title?: string; error?: string }>;
}
export interface AutoModeAPI {
start: (
projectPath: string,
branchName?: string | null,
maxConcurrency?: number
) => Promise<{ success: boolean; error?: string }>;
stop: (
projectPath: string
projectPath: string,
branchName?: string | null
) => Promise<{ success: boolean; error?: string; runningFeatures?: number }>;
stopFeature: (featureId: string) => Promise<{ success: boolean; error?: string }>;
status: (projectPath?: string) => Promise<{
status: (
projectPath?: string,
branchName?: string | null
) => Promise<{
success: boolean;
isRunning?: boolean;
isAutoLoopRunning?: boolean;
@@ -706,7 +713,8 @@ export interface ElectronAPI {
originalText: string,
enhancementMode: string,
model?: string,
thinkingLevel?: string
thinkingLevel?: string,
projectPath?: string
) => Promise<{
success: boolean;
enhancedText?: string;
@@ -2016,6 +2024,20 @@ function createMockWorktreeAPI(): WorktreeAPI {
console.log('[Mock] Unsubscribing from init script events');
};
},
discardChanges: async (worktreePath: string) => {
console.log('[Mock] Discarding changes:', { worktreePath });
return {
success: true,
result: {
discarded: true,
filesDiscarded: 0,
filesRemaining: 0,
branch: 'main',
message: 'Mock: Changes discarded successfully',
},
};
},
};
}
@@ -2060,7 +2082,9 @@ function createMockAutoModeAPI(): AutoModeAPI {
}
mockAutoModeRunning = true;
console.log(`[Mock] Auto mode started with maxConcurrency: ${maxConcurrency || 3}`);
console.log(
`[Mock] Auto mode started with maxConcurrency: ${maxConcurrency || DEFAULT_MAX_CONCURRENCY}`
);
const featureId = 'auto-mode-0';
mockRunningFeatures.add(featureId);
@@ -3173,7 +3197,7 @@ function createMockFeaturesAPI(): FeaturesAPI {
return { success: true, content: content || null };
},
generateTitle: async (description: string) => {
generateTitle: async (description: string, _projectPath?: string) => {
console.log('[Mock] Generating title for:', description.substring(0, 50));
// Mock title generation - just take first few words
const words = description.split(/\s+/).slice(0, 6).join(' ');
@@ -3349,6 +3373,13 @@ export interface Project {
isFavorite?: boolean; // Pin project to top of dashboard
icon?: string; // Lucide icon name for project identification
customIconPath?: string; // Path to custom uploaded icon image in .automaker/images/
/**
* Override the active Claude API profile for this project.
* - undefined: Use global setting (activeClaudeApiProfileId)
* - null: Explicitly use Direct Anthropic API (no profile)
* - string: Use specific profile by ID
*/
activeClaudeApiProfileId?: string | null;
}
export interface TrashedProject extends Project {

View File

@@ -1657,8 +1657,8 @@ export class HttpApiClient implements ElectronAPI {
this.post('/api/features/delete', { projectPath, featureId }),
getAgentOutput: (projectPath: string, featureId: string) =>
this.post('/api/features/agent-output', { projectPath, featureId }),
generateTitle: (description: string) =>
this.post('/api/features/generate-title', { description }),
generateTitle: (description: string, projectPath?: string) =>
this.post('/api/features/generate-title', { description, projectPath }),
bulkUpdate: (projectPath: string, featureIds: string[], updates: Partial<Feature>) =>
this.post('/api/features/bulk-update', { projectPath, featureIds, updates }),
bulkDelete: (projectPath: string, featureIds: string[]) =>
@@ -1667,11 +1667,13 @@ export class HttpApiClient implements ElectronAPI {
// Auto Mode API
autoMode: AutoModeAPI = {
start: (projectPath: string, maxConcurrency?: number) =>
this.post('/api/auto-mode/start', { projectPath, maxConcurrency }),
stop: (projectPath: string) => this.post('/api/auto-mode/stop', { projectPath }),
start: (projectPath: string, branchName?: string | null, maxConcurrency?: number) =>
this.post('/api/auto-mode/start', { projectPath, branchName, maxConcurrency }),
stop: (projectPath: string, branchName?: string | null) =>
this.post('/api/auto-mode/stop', { projectPath, branchName }),
stopFeature: (featureId: string) => this.post('/api/auto-mode/stop-feature', { featureId }),
status: (projectPath?: string) => this.post('/api/auto-mode/status', { projectPath }),
status: (projectPath?: string, branchName?: string | null) =>
this.post('/api/auto-mode/status', { projectPath, branchName }),
runFeature: (
projectPath: string,
featureId: string,
@@ -1743,13 +1745,15 @@ export class HttpApiClient implements ElectronAPI {
originalText: string,
enhancementMode: string,
model?: string,
thinkingLevel?: string
thinkingLevel?: string,
projectPath?: string
): Promise<EnhancePromptResult> =>
this.post('/api/enhance-prompt', {
originalText,
enhancementMode,
model,
thinkingLevel,
projectPath,
}),
};
@@ -1847,6 +1851,8 @@ export class HttpApiClient implements ElectronAPI {
this.httpDelete('/api/worktree/init-script', { projectPath }),
runInitScript: (projectPath: string, worktreePath: string, branch: string) =>
this.post('/api/worktree/run-init-script', { projectPath, worktreePath, branch }),
discardChanges: (worktreePath: string) =>
this.post('/api/worktree/discard-changes', { worktreePath }),
onInitScriptEvent: (
callback: (event: {
type: 'worktree:init-started' | 'worktree:init-output' | 'worktree:init-completed';