mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 20:03:37 +00:00
- Fix 75 ESLint errors by updating eslint.config.mjs: - Add missing browser globals (MouseEvent, AbortController, Response, etc.) - Add Vite define global (__APP_VERSION__) - Configure @ts-nocheck to require descriptions - Add no-unused-vars rule for .mjs scripts - Fix runtime bug in agent-output-modal.tsx (setOutput -> setStreamedContent) - Remove ~120 unused variable warnings across 97 files: - Remove unused imports (React hooks, lucide icons, types) - Remove unused constants and variables - Remove unused function definitions - Prefix intentionally unused parameters with underscore - Add descriptions to all @ts-nocheck comments (25 files) - Clean up misc issues: - Remove invalid deprecation plugin comments - Fix eslint-disable comment placement - Add missing RefreshCw import in code-view.tsx Reduces lint warnings from ~300 to 67 (all remaining are no-explicit-any) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
162 lines
4.5 KiB
TypeScript
162 lines
4.5 KiB
TypeScript
/**
|
|
* GitHub Mutation Hooks
|
|
*
|
|
* React Query mutations for GitHub operations like validating issues.
|
|
*/
|
|
|
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import { getElectronAPI, GitHubIssue, GitHubComment } from '@/lib/electron';
|
|
import { queryKeys } from '@/lib/query-keys';
|
|
import { toast } from 'sonner';
|
|
import type { LinkedPRInfo, ModelId } from '@automaker/types';
|
|
import { resolveModelString } from '@automaker/model-resolver';
|
|
|
|
/**
|
|
* Input for validating a GitHub issue
|
|
*/
|
|
interface ValidateIssueInput {
|
|
issue: GitHubIssue;
|
|
model?: ModelId;
|
|
thinkingLevel?: number;
|
|
reasoningEffort?: string;
|
|
comments?: GitHubComment[];
|
|
linkedPRs?: LinkedPRInfo[];
|
|
}
|
|
|
|
/**
|
|
* Validate a GitHub issue with AI
|
|
*
|
|
* This mutation triggers an async validation process. Results are delivered
|
|
* via WebSocket events (issue_validation_complete, issue_validation_error).
|
|
*
|
|
* @param projectPath - Path to the project
|
|
* @returns Mutation for validating issues
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* const validateMutation = useValidateIssue(projectPath);
|
|
*
|
|
* validateMutation.mutate({
|
|
* issue,
|
|
* model: 'sonnet',
|
|
* comments,
|
|
* linkedPRs,
|
|
* });
|
|
* ```
|
|
*/
|
|
export function useValidateIssue(projectPath: string) {
|
|
return useMutation({
|
|
mutationFn: async (input: ValidateIssueInput) => {
|
|
const { issue, model, thinkingLevel, reasoningEffort, comments, linkedPRs } = input;
|
|
|
|
const api = getElectronAPI();
|
|
if (!api.github?.validateIssue) {
|
|
throw new Error('Validation API not available');
|
|
}
|
|
|
|
const validationInput = {
|
|
issueNumber: issue.number,
|
|
issueTitle: issue.title,
|
|
issueBody: issue.body || '',
|
|
issueLabels: issue.labels.map((l) => l.name),
|
|
comments,
|
|
linkedPRs,
|
|
};
|
|
|
|
// Resolve model alias to canonical model identifier
|
|
const resolvedModel = model ? resolveModelString(model) : undefined;
|
|
|
|
const result = await api.github.validateIssue(
|
|
projectPath,
|
|
validationInput,
|
|
resolvedModel,
|
|
thinkingLevel,
|
|
reasoningEffort
|
|
);
|
|
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Failed to start validation');
|
|
}
|
|
|
|
return { issueNumber: issue.number };
|
|
},
|
|
onSuccess: (_, variables) => {
|
|
toast.info(`Starting validation for issue #${variables.issue.number}`, {
|
|
description: 'You will be notified when the analysis is complete',
|
|
});
|
|
},
|
|
onError: (error) => {
|
|
toast.error('Failed to validate issue', {
|
|
description: error instanceof Error ? error.message : 'Unknown error',
|
|
});
|
|
},
|
|
// Note: We don't invalidate queries here because the actual result
|
|
// comes through WebSocket events which handle cache invalidation
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Mark a validation as viewed
|
|
*
|
|
* @param projectPath - Path to the project
|
|
* @returns Mutation for marking validation as viewed
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* const markViewedMutation = useMarkValidationViewed(projectPath);
|
|
* markViewedMutation.mutate(issueNumber);
|
|
* ```
|
|
*/
|
|
export function useMarkValidationViewed(projectPath: string) {
|
|
const queryClient = useQueryClient();
|
|
|
|
return useMutation({
|
|
mutationFn: async (issueNumber: number) => {
|
|
const api = getElectronAPI();
|
|
if (!api.github?.markValidationViewed) {
|
|
throw new Error('Mark viewed API not available');
|
|
}
|
|
|
|
const result = await api.github.markValidationViewed(projectPath, issueNumber);
|
|
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Failed to mark as viewed');
|
|
}
|
|
|
|
return { issueNumber };
|
|
},
|
|
onSuccess: () => {
|
|
// Invalidate validations cache to refresh the viewed state
|
|
queryClient.invalidateQueries({
|
|
queryKey: queryKeys.github.validations(projectPath),
|
|
});
|
|
},
|
|
// Silent mutation - no toast needed for marking as viewed
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get running validation status
|
|
*
|
|
* @param projectPath - Path to the project
|
|
* @returns Mutation for getting validation status (returns running issue numbers)
|
|
*/
|
|
export function useGetValidationStatus(projectPath: string) {
|
|
return useMutation({
|
|
mutationFn: async () => {
|
|
const api = getElectronAPI();
|
|
if (!api.github?.getValidationStatus) {
|
|
throw new Error('Validation status API not available');
|
|
}
|
|
|
|
const result = await api.github.getValidationStatus(projectPath);
|
|
|
|
if (!result.success) {
|
|
throw new Error(result.error || 'Failed to get validation status');
|
|
}
|
|
|
|
return result.runningIssues ?? [];
|
|
},
|
|
});
|
|
}
|