mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-03-18 22:33:08 +00:00
fix: Remove unused vars and improve type safety. Improve task recovery
This commit is contained in:
@@ -6,7 +6,7 @@ import type { Request, Response } from 'express';
|
||||
import { AgentService } from '../../../services/agent-service.js';
|
||||
import { createLogger } from '@automaker/utils';
|
||||
import { getErrorMessage, logError } from '../common.js';
|
||||
const logger = createLogger('Agent');
|
||||
const _logger = createLogger('Agent');
|
||||
|
||||
export function createStartHandler(agentService: AgentService) {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
|
||||
@@ -128,7 +128,7 @@ export function logAuthStatus(context: string): void {
|
||||
*/
|
||||
export function logError(error: unknown, context: string): void {
|
||||
logger.error(`❌ ${context}:`);
|
||||
logger.error('Error name:', (error as any)?.name);
|
||||
logger.error('Error name:', (error as Error)?.name);
|
||||
logger.error('Error message:', (error as Error)?.message);
|
||||
logger.error('Error stack:', (error as Error)?.stack);
|
||||
logger.error('Full error object:', JSON.stringify(error, Object.getOwnPropertyNames(error), 2));
|
||||
|
||||
@@ -30,7 +30,7 @@ const DEFAULT_MAX_FEATURES = 50;
|
||||
* Timeout for Codex models when generating features (5 minutes).
|
||||
* Codex models are slower and need more time to generate 50+ features.
|
||||
*/
|
||||
const CODEX_FEATURE_GENERATION_TIMEOUT_MS = 300000; // 5 minutes
|
||||
const _CODEX_FEATURE_GENERATION_TIMEOUT_MS = 300000; // 5 minutes
|
||||
|
||||
/**
|
||||
* Type for extracted features JSON response
|
||||
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
updateTechnologyStack,
|
||||
updateRoadmapPhaseStatus,
|
||||
type ImplementedFeature,
|
||||
type RoadmapPhase,
|
||||
} from '../../lib/xml-extractor.js';
|
||||
import { getNotificationService } from '../../services/notification-service.js';
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
import type { EventEmitter } from '../../lib/events.js';
|
||||
import type { Feature, BacklogPlanResult, BacklogChange, DependencyUpdate } from '@automaker/types';
|
||||
import type { Feature, BacklogPlanResult } from '@automaker/types';
|
||||
import {
|
||||
DEFAULT_PHASE_MODELS,
|
||||
isCursorModel,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import type { Request, Response } from 'express';
|
||||
import type { BacklogPlanResult, BacklogChange, Feature } from '@automaker/types';
|
||||
import type { BacklogPlanResult } from '@automaker/types';
|
||||
import { FeatureLoader } from '../../../services/feature-loader.js';
|
||||
import { clearBacklogPlan, getErrorMessage, logError, logger } from '../common.js';
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ interface ExportRequest {
|
||||
};
|
||||
}
|
||||
|
||||
export function createExportHandler(featureLoader: FeatureLoader) {
|
||||
export function createExportHandler(_featureLoader: FeatureLoader) {
|
||||
const exportService = getFeatureExportService();
|
||||
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
|
||||
@@ -34,7 +34,7 @@ export function createGenerateTitleHandler(
|
||||
): (req: Request, res: Response) => Promise<void> {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { description, projectPath } = req.body as GenerateTitleRequestBody;
|
||||
const { description } = req.body as GenerateTitleRequestBody;
|
||||
|
||||
if (!description || typeof description !== 'string') {
|
||||
const response: GenerateTitleErrorResponse = {
|
||||
|
||||
@@ -33,7 +33,7 @@ interface ConflictInfo {
|
||||
hasConflict: boolean;
|
||||
}
|
||||
|
||||
export function createImportHandler(featureLoader: FeatureLoader) {
|
||||
export function createImportHandler(_featureLoader: FeatureLoader) {
|
||||
const exportService = getFeatureExportService();
|
||||
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
|
||||
@@ -35,9 +35,9 @@ export function createMkdirHandler() {
|
||||
error: 'Path exists and is not a directory',
|
||||
});
|
||||
return;
|
||||
} catch (statError: any) {
|
||||
} catch (statError: unknown) {
|
||||
// ENOENT means path doesn't exist - we should create it
|
||||
if (statError.code !== 'ENOENT') {
|
||||
if ((statError as NodeJS.ErrnoException).code !== 'ENOENT') {
|
||||
// Some other error (could be ELOOP in parent path)
|
||||
throw statError;
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export function createMkdirHandler() {
|
||||
await secureFs.mkdir(resolvedPath, { recursive: true });
|
||||
|
||||
res.json({ success: true });
|
||||
} catch (error: any) {
|
||||
} catch (error: unknown) {
|
||||
// Path not allowed - return 403 Forbidden
|
||||
if (error instanceof PathNotAllowedError) {
|
||||
res.status(403).json({ success: false, error: getErrorMessage(error) });
|
||||
@@ -55,7 +55,7 @@ export function createMkdirHandler() {
|
||||
}
|
||||
|
||||
// Handle ELOOP specifically
|
||||
if (error.code === 'ELOOP') {
|
||||
if ((error as NodeJS.ErrnoException).code === 'ELOOP') {
|
||||
logError(error, 'Create directory failed - symlink loop detected');
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
|
||||
@@ -10,7 +10,11 @@ import { getErrorMessage, logError } from '../common.js';
|
||||
export function createResolveDirectoryHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { directoryName, sampleFiles, fileCount } = req.body as {
|
||||
const {
|
||||
directoryName,
|
||||
sampleFiles,
|
||||
fileCount: _fileCount,
|
||||
} = req.body as {
|
||||
directoryName: string;
|
||||
sampleFiles?: string[];
|
||||
fileCount?: number;
|
||||
|
||||
@@ -11,10 +11,9 @@ import { getBoardDir } from '@automaker/platform';
|
||||
export function createSaveBoardBackgroundHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { data, filename, mimeType, projectPath } = req.body as {
|
||||
const { data, filename, projectPath } = req.body as {
|
||||
data: string;
|
||||
filename: string;
|
||||
mimeType: string;
|
||||
projectPath: string;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,10 +12,9 @@ import { sanitizeFilename } from '@automaker/utils';
|
||||
export function createSaveImageHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
const { data, filename, mimeType, projectPath } = req.body as {
|
||||
const { data, filename, projectPath } = req.body as {
|
||||
data: string;
|
||||
filename: string;
|
||||
mimeType: string;
|
||||
projectPath: string;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import type { Request, Response } from 'express';
|
||||
import * as secureFs from '../../../lib/secure-fs.js';
|
||||
import path from 'path';
|
||||
import { isPathAllowed, PathNotAllowedError, getAllowedRootDirectory } from '@automaker/platform';
|
||||
import { isPathAllowed, getAllowedRootDirectory } from '@automaker/platform';
|
||||
import { getErrorMessage, logError } from '../common.js';
|
||||
|
||||
export function createValidatePathHandler() {
|
||||
|
||||
@@ -37,9 +37,12 @@ export function createGeminiRoutes(): Router {
|
||||
const provider = new GeminiProvider();
|
||||
const status = await provider.detectInstallation();
|
||||
|
||||
const authMethod =
|
||||
(status as any).authMethod ||
|
||||
(status.authenticated ? (status.hasApiKey ? 'api_key' : 'cli_login') : 'none');
|
||||
// Derive authMethod from typed InstallationStatus fields
|
||||
const authMethod = status.authenticated
|
||||
? status.hasApiKey
|
||||
? 'api_key'
|
||||
: 'cli_login'
|
||||
: 'none';
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
@@ -48,7 +51,7 @@ export function createGeminiRoutes(): Router {
|
||||
path: status.path || null,
|
||||
authenticated: status.authenticated || false,
|
||||
authMethod,
|
||||
hasCredentialsFile: (status as any).hasCredentialsFile || false,
|
||||
hasCredentialsFile: false,
|
||||
});
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : 'Unknown error';
|
||||
|
||||
@@ -6,7 +6,6 @@ import type { Request, Response } from 'express';
|
||||
import type { EventEmitter } from '../../../lib/events.js';
|
||||
import type { IssueValidationEvent } from '@automaker/types';
|
||||
import {
|
||||
isValidationRunning,
|
||||
getValidationStatus,
|
||||
getRunningValidations,
|
||||
abortValidation,
|
||||
@@ -15,7 +14,6 @@ import {
|
||||
logger,
|
||||
} from './validation-common.js';
|
||||
import {
|
||||
readValidation,
|
||||
getAllValidations,
|
||||
getValidationWithFreshness,
|
||||
deleteValidation,
|
||||
|
||||
@@ -12,7 +12,7 @@ export function createProvidersHandler() {
|
||||
// Get installation status from all providers
|
||||
const statuses = await ProviderFactory.checkAllProviders();
|
||||
|
||||
const providers: Record<string, any> = {
|
||||
const providers: Record<string, Record<string, unknown>> = {
|
||||
anthropic: {
|
||||
available: statuses.claude?.installed || false,
|
||||
hasApiKey: !!process.env.ANTHROPIC_API_KEY,
|
||||
|
||||
@@ -46,16 +46,14 @@ export function createUpdateGlobalHandler(settingsService: SettingsService) {
|
||||
}
|
||||
|
||||
// Minimal debug logging to help diagnose accidental wipes.
|
||||
const projectsLen = Array.isArray((updates as any).projects)
|
||||
? (updates as any).projects.length
|
||||
: undefined;
|
||||
const trashedLen = Array.isArray((updates as any).trashedProjects)
|
||||
? (updates as any).trashedProjects.length
|
||||
const projectsLen = Array.isArray(updates.projects) ? updates.projects.length : undefined;
|
||||
const trashedLen = Array.isArray(updates.trashedProjects)
|
||||
? updates.trashedProjects.length
|
||||
: undefined;
|
||||
logger.info(
|
||||
`[SERVER_SETTINGS_UPDATE] Request received: projects=${projectsLen ?? 'n/a'}, trashedProjects=${trashedLen ?? 'n/a'}, theme=${
|
||||
(updates as any).theme ?? 'n/a'
|
||||
}, localStorageMigrated=${(updates as any).localStorageMigrated ?? 'n/a'}`
|
||||
updates.theme ?? 'n/a'
|
||||
}, localStorageMigrated=${updates.localStorageMigrated ?? 'n/a'}`
|
||||
);
|
||||
|
||||
// Get old settings to detect theme changes
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
|
||||
import type { Request, Response } from 'express';
|
||||
import { getErrorMessage, logError } from '../common.js';
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
export function createAuthClaudeHandler() {
|
||||
return async (_req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
|
||||
@@ -4,13 +4,9 @@
|
||||
|
||||
import type { Request, Response } from 'express';
|
||||
import { logError, getErrorMessage } from '../common.js';
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
export function createAuthOpencodeHandler() {
|
||||
return async (_req: Request, res: Response): Promise<void> => {
|
||||
try {
|
||||
|
||||
@@ -10,9 +10,6 @@ import type { Request, Response } from 'express';
|
||||
import { CopilotProvider } from '../../../providers/copilot-provider.js';
|
||||
import { getErrorMessage, logError } from '../common.js';
|
||||
import type { ModelDefinition } from '@automaker/types';
|
||||
import { createLogger } from '@automaker/utils';
|
||||
|
||||
const logger = createLogger('CopilotModelsRoute');
|
||||
|
||||
// Singleton provider instance for caching
|
||||
let providerInstance: CopilotProvider | null = null;
|
||||
|
||||
@@ -14,9 +14,6 @@ import {
|
||||
} from '../../../providers/opencode-provider.js';
|
||||
import { getErrorMessage, logError } from '../common.js';
|
||||
import type { ModelDefinition } from '@automaker/types';
|
||||
import { createLogger } from '@automaker/utils';
|
||||
|
||||
const logger = createLogger('OpenCodeModelsRoute');
|
||||
|
||||
// Singleton provider instance for caching
|
||||
let providerInstance: OpencodeProvider | null = null;
|
||||
|
||||
@@ -151,7 +151,7 @@ export function createVerifyClaudeAuthHandler() {
|
||||
AuthSessionManager.createSession(sessionId, authMethod || 'api_key', apiKey, 'anthropic');
|
||||
|
||||
// Create temporary environment override for SDK call
|
||||
const cleanupEnv = createTempEnvOverride(authEnv);
|
||||
const _cleanupEnv = createTempEnvOverride(authEnv);
|
||||
|
||||
// Run a minimal query to verify authentication
|
||||
const stream = query({
|
||||
@@ -194,8 +194,10 @@ export function createVerifyClaudeAuthHandler() {
|
||||
}
|
||||
|
||||
// Check specifically for assistant messages with text content
|
||||
if (msg.type === 'assistant' && (msg as any).message?.content) {
|
||||
const content = (msg as any).message.content;
|
||||
const msgRecord = msg as Record<string, unknown>;
|
||||
const msgMessage = msgRecord.message as Record<string, unknown> | undefined;
|
||||
if (msg.type === 'assistant' && msgMessage?.content) {
|
||||
const content = msgMessage.content;
|
||||
if (Array.isArray(content)) {
|
||||
for (const block of content) {
|
||||
if (block.type === 'text' && block.text) {
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
import { randomBytes } from 'crypto';
|
||||
import { createLogger } from '@automaker/utils';
|
||||
import type { Request, Response, NextFunction } from 'express';
|
||||
import { getTerminalService } from '../../services/terminal-service.js';
|
||||
|
||||
const logger = createLogger('Terminal');
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
generateToken,
|
||||
addToken,
|
||||
getTokenExpiryMs,
|
||||
getErrorMessage,
|
||||
} from '../common.js';
|
||||
|
||||
export function createAuthHandler() {
|
||||
|
||||
@@ -31,8 +31,8 @@ export async function getTrackedBranches(projectPath: string): Promise<TrackedBr
|
||||
const content = (await secureFs.readFile(filePath, 'utf-8')) as string;
|
||||
const data: BranchTrackingData = JSON.parse(content);
|
||||
return data.branches || [];
|
||||
} catch (error: any) {
|
||||
if (error.code === 'ENOENT') {
|
||||
} catch (error: unknown) {
|
||||
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
||||
return [];
|
||||
}
|
||||
logger.warn('Failed to read tracked branches:', error);
|
||||
|
||||
@@ -117,7 +117,7 @@ export function createCreatePRHandler() {
|
||||
cwd: worktreePath,
|
||||
env: execEnv,
|
||||
});
|
||||
} catch (error: unknown) {
|
||||
} catch {
|
||||
// If push fails, try with --set-upstream
|
||||
try {
|
||||
await execAsync(`git push --set-upstream origin ${branchName}`, {
|
||||
@@ -195,7 +195,7 @@ export function createCreatePRHandler() {
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Couldn't parse remotes - will try fallback
|
||||
}
|
||||
|
||||
@@ -216,7 +216,7 @@ export function createCreatePRHandler() {
|
||||
originOwner = owner;
|
||||
repoUrl = `https://github.com/${owner}/${repo}`;
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Failed to get repo URL from config
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ export function createDeleteHandler() {
|
||||
// Remove the worktree (using array arguments to prevent injection)
|
||||
try {
|
||||
await execGitCommand(['worktree', 'remove', worktreePath, '--force'], projectPath);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// Try with prune if remove fails
|
||||
await execGitCommand(['worktree', 'prune'], projectPath);
|
||||
}
|
||||
|
||||
@@ -64,31 +64,8 @@ export function createZaiRoutes(
|
||||
router.post('/configure', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { apiToken, apiHost } = req.body;
|
||||
|
||||
if (apiToken !== undefined) {
|
||||
// Set in-memory token
|
||||
usageService.setApiToken(apiToken || '');
|
||||
|
||||
// Persist to credentials (deep merge happens in updateCredentials)
|
||||
try {
|
||||
await settingsService.updateCredentials({
|
||||
apiKeys: { zai: apiToken || '' },
|
||||
} as Parameters<typeof settingsService.updateCredentials>[0]);
|
||||
logger.info('[configure] Saved z.ai API key to credentials');
|
||||
} catch (persistError) {
|
||||
logger.error('[configure] Failed to persist z.ai API key:', persistError);
|
||||
}
|
||||
}
|
||||
|
||||
if (apiHost) {
|
||||
usageService.setApiHost(apiHost);
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'z.ai configuration updated',
|
||||
isAvailable: usageService.isAvailable(),
|
||||
});
|
||||
const result = await usageService.configure({ apiToken, apiHost }, settingsService);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : 'Unknown error';
|
||||
logger.error('Error configuring z.ai:', error);
|
||||
@@ -100,50 +77,8 @@ export function createZaiRoutes(
|
||||
router.post('/verify', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const { apiKey } = req.body;
|
||||
|
||||
if (!apiKey || typeof apiKey !== 'string' || apiKey.trim().length === 0) {
|
||||
res.json({
|
||||
success: false,
|
||||
authenticated: false,
|
||||
error: 'Please provide an API key to test.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Test the key by making a request to z.ai API
|
||||
const quotaUrl =
|
||||
process.env.Z_AI_QUOTA_URL ||
|
||||
`${process.env.Z_AI_API_HOST ? `https://${process.env.Z_AI_API_HOST}` : 'https://api.z.ai'}/api/monitor/usage/quota/limit`;
|
||||
|
||||
logger.info(`[verify] Testing API key against: ${quotaUrl}`);
|
||||
|
||||
const response = await fetch(quotaUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Authorization: `Bearer ${apiKey.trim()}`,
|
||||
Accept: 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
res.json({
|
||||
success: true,
|
||||
authenticated: true,
|
||||
message: 'Connection successful! z.ai API responded.',
|
||||
});
|
||||
} else if (response.status === 401 || response.status === 403) {
|
||||
res.json({
|
||||
success: false,
|
||||
authenticated: false,
|
||||
error: 'Invalid API key. Please check your key and try again.',
|
||||
});
|
||||
} else {
|
||||
res.json({
|
||||
success: false,
|
||||
authenticated: false,
|
||||
error: `API request failed: ${response.status} ${response.statusText}`,
|
||||
});
|
||||
}
|
||||
const result = await usageService.verifyApiKey(apiKey);
|
||||
res.json(result);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : 'Unknown error';
|
||||
logger.error('Error verifying z.ai API key:', error);
|
||||
|
||||
Reference in New Issue
Block a user