mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 06:42:03 +00:00
- STACK.md - Technologies and dependencies - ARCHITECTURE.md - System design and patterns - STRUCTURE.md - Directory layout - CONVENTIONS.md - Code style and patterns - TESTING.md - Test structure - INTEGRATIONS.md - External services - CONCERNS.md - Technical debt and issues
9.4 KiB
9.4 KiB
Coding Conventions
Analysis Date: 2026-01-27
Naming Patterns
Files:
- PascalCase for class/service files:
auto-mode-service.ts,feature-loader.ts,claude-provider.ts - kebab-case for route/handler directories:
auto-mode/,features/,event-history/ - kebab-case for utility files:
secure-fs.ts,sdk-options.ts,settings-helpers.ts - kebab-case for React components:
card.tsx,ansi-output.tsx,count-up-timer.tsx - kebab-case for hooks:
use-board-background-settings.ts,use-responsive-kanban.ts,use-test-logs.ts - kebab-case for store files:
app-store.ts,auth-store.ts,setup-store.ts - Organized by functionality:
routes/features/routes/list.ts,routes/features/routes/get.ts
Functions:
- camelCase for all function names:
createEventEmitter(),getAutomakerDir(),executeQuery() - Verb-first for action functions:
buildPrompt(),classifyError(),loadContextFiles(),atomicWriteJson() - Prefix with
usefor React hooks:useBoardBackgroundSettings(),useAppStore(),useUpdateProjectSettings() - Private methods prefixed with underscore:
_deleteOrphanedImages(),_migrateImages()
Variables:
- camelCase for constants and variables:
featureId,projectPath,modelId,tempDir - UPPER_SNAKE_CASE for global constants/enums:
DEFAULT_MAX_CONCURRENCY,DEFAULT_PHASE_MODELS - Meaningful naming over abbreviations:
featureDirectorynotfd,featureImagesnotimg - Prefixes for computed values:
is*for booleans:isClaudeModel,isContainerized,isAutoLoginEnabled
Types:
- PascalCase for interfaces and types:
Feature,ExecuteOptions,EventEmitter,ProviderConfig - Type files suffixed with
.d.ts:paths.d.ts,types.d.ts - Organized by domain:
src/store/types/,src/lib/ - Re-export pattern from main package indexes:
export type { Feature };
Code Style
Formatting:
- Tool: Prettier 3.7.4
- Print width: 100 characters
- Tab width: 2 spaces
- Single quotes for strings
- Semicolons required
- Trailing commas: es5 (trailing in arrays/objects, not in params)
- Arrow functions always include parentheses:
(x) => x * 2 - Line endings: LF (Unix)
- Bracket spacing:
{ key: value }
Linting:
- Tool: ESLint (flat config in
apps/ui/eslint.config.mjs) - TypeScript ESLint plugin for
.ts/.tsxfiles - Recommended configs:
@eslint/js,@typescript-eslint/recommended - Unused variables warning with exception for parameters starting with
_ - Type assertions are allowed with description when using
@ts-ignore @typescript-eslint/no-explicit-anyis warn-level (allow with caution)
Import Organization
Order:
- Node.js standard library:
import fs from 'fs/promises',import path from 'path' - Third-party packages:
import { describe, it } from 'vitest',import { Router } from 'express' - Shared packages (monorepo):
import type { Feature } from '@automaker/types',import { createLogger } from '@automaker/utils' - Local relative imports:
import { FeatureLoader } from './feature-loader.js',import * as secureFs from '../lib/secure-fs.js' - Type imports: separated with
import type { ... } from
Path Aliases:
@/- resolves to./srcin both UI (apps/ui/) and server (apps/server/)- Shared packages prefixed with
@automaker/:@automaker/types- core TypeScript definitions@automaker/utils- logging, errors, utilities@automaker/prompts- AI prompt templates@automaker/platform- path management, security, processes@automaker/model-resolver- model alias resolution@automaker/dependency-resolver- feature dependency ordering@automaker/git-utils- git operations
- Extensions:
.jsextension used in imports for ESM imports
Import Rules:
- Always import from shared packages, never from old paths
- No circular dependencies between layers
- Services import from providers and utilities
- Routes import from services
- Shared packages have strict dependency hierarchy (types → utils → platform → git-utils → server/ui)
Error Handling
Patterns:
- Use
try-catchblocks for async operations: wraps feature execution, file operations, git commands - Throw
new Error(message)with descriptive messages:throw new Error('already running'),throw new Error('Feature ${featureId} not found') - Classify errors with
classifyError()from@automaker/utilsfor categorization - Log errors with context using
createLogger(): includes error classification - Return error info objects:
{ valid: false, errors: [...], warnings: [...] } - Validation returns structured result:
{ valid, errors, warnings }from providervalidateConfig()
Error Types:
- Authentication errors: distinguish from validation/runtime errors
- Path validation errors: caught by middleware in Express routes
- File system errors: logged and recovery attempted with backups
- SDK/API errors: classified and wrapped with context
- Abort/cancellation errors: handled without stack traces (graceful shutdown)
Error Messages:
- Descriptive and actionable: not vague error codes
- Include context when helpful: file paths, feature IDs, model names
- User-friendly messages via
getUserFriendlyErrorMessage()for client display
Logging
Framework:
- Built-in
createLogger()from@automaker/utils - Each module creates logger:
const logger = createLogger('ModuleName') - Logger functions:
info(),warn(),error(),debug()
Patterns:
- Log operation start and completion for significant operations
- Log warnings for non-critical issues: file deletion failures, missing optional configs
- Log errors with full error object:
logger.error('operation failed', error) - Use module name as logger context:
createLogger('AutoMode'),createLogger('HttpClient') - Avoid logging sensitive data (API keys, passwords)
- No console.log in production code - use logger
What to Log:
- Feature execution start/completion
- Error classification and recovery attempts
- File operations (create, delete, migrate)
- API calls and responses (in debug mode)
- Async operation start/end
- Warnings for deprecated patterns
Comments
When to Comment:
- Complex algorithms or business logic: explain the "why" not the "what"
- Integration points: explain how modules communicate
- Workarounds: explain the constraint that made the workaround necessary
- Non-obvious performance implications
- Edge cases and their handling
JSDoc/TSDoc:
- Used for public functions and classes
- Document parameters with
@param - Document return types with
@returns - Document exceptions with
@throws - Used for service classes:
/**\n * Module description\n * Manages: ...\n */ - Not required for simple getters/setters
Example JSDoc Pattern:
/**
* Delete images that were removed from a feature
*/
private async deleteOrphanedImages(
projectPath: string,
oldPaths: Array<string>,
newPaths: Array<string>
): Promise<void> {
// Implementation
}
Function Design
Size:
- Keep functions under 100 lines when possible
- Large services split into multiple related methods
- Private helper methods extracted for complex logic
Parameters:
- Use destructuring for object parameters with multiple properties
- Document parameter types with TypeScript types
- Optional parameters marked with
? - Use
Record<string, unknown>for flexible object parameters
Return Values:
- Explicit return types required for all public functions
- Return structured objects for multiple values
- Use
Promise<T>for async functions - Async generators use
AsyncGenerator<T>for streaming responses - Never implicitly return
undefined(explicit return or throw)
Module Design
Exports:
- Default export for class instantiation:
export default class FeatureLoader {} - Named exports for functions:
export function createEventEmitter() {} - Type exports separated:
export type { Feature }; - Barrel files (index.ts) re-export from module
Barrel Files:
- Used in routes:
routes/features/index.tscreates router and exports - Used in stores:
store/index.tsexports all store hooks - Pattern: group related exports for easier importing
Service Classes:
- Instantiated once and dependency injected
- Public methods for API surface
- Private methods prefixed with
_ - No static methods - prefer instances or functions
- Constructor takes dependencies:
constructor(config?: ProviderConfig)
Provider Pattern:
- Abstract base class:
BaseProviderwith abstract methods - Concrete implementations:
ClaudeProvider,CodexProvider,CursorProvider - Common interface:
executeQuery(),detectInstallation(),validateConfig() - Factory for instantiation:
ProviderFactory.create()
TypeScript Specific
Strict Mode: Always enabled globally
strict: truein all tsconfigs- No implicit
any- declare types explicitly - No optional chaining on base types without narrowing
Type Definitions:
- Interface for shapes:
interface Feature { ... } - Type for unions/aliases:
type ModelAlias = 'haiku' | 'sonnet' | 'opus' - Type guards for narrowing:
if (typeof x === 'string') { ... } - Generic types for reusable patterns:
EventCallback<T>
React Specific (UI):
- Functional components only
- React 19 with hooks
- Type props interface:
interface CardProps extends React.ComponentProps<'div'> { ... } - Zustand stores for state management
- Custom hooks for shared logic
Convention analysis: 2026-01-27