Skip to main content
Glama
RULES.yaml18.4 kB
version: '1.0' template: shared description: Shared rules and patterns for all Agiflow templates rules: - pattern: import-standards description: Import organization and standards must_do: - rule: Use clean import paths without file extensions codeExample: | // ✅ GOOD - No file extensions import { UserService } from '../services'; import { myTool } from '../tools/MyTool'; import type { Config } from '../types'; // ❌ BAD - File extensions in imports import { UserService } from '../services/index.js'; import { myTool } from '../tools/MyTool.js'; import type { Config } from '../types.ts'; - rule: Use barrel imports without /index suffix codeExample: | // ✅ GOOD - Clean barrel imports import { UserService } from '../services'; import { myTool } from '../tools'; import type { Config } from '../types'; // ❌ BAD - Explicit /index in path import { UserService } from '../services/index'; import { myTool } from '../tools/index'; - rule: Import from barrel exports, not individual files (except @modelcontextprotocol/sdk) codeExample: | // ✅ GOOD - Import from barrel import { UserService, OrderService } from '../services'; import { MyTool } from '../tools'; // ✅ OK - @modelcontextprotocol/sdk requires .js extension import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'; // ❌ BAD - Direct file imports import { UserService } from '../services/UserService'; import { OrderService } from '../services/OrderService'; should_do: - rule: Use static imports at the top of the file instead of inline dynamic imports codeExample: | // ✅ GOOD import { listScaffoldMethods } from '../hooks/geminiCli/listScaffoldMethods'; const hooks = await listScaffoldMethods(); // ⚠️ AVOID - Unnecessary dynamic import const hooks = await import('../hooks/geminiCli/listScaffoldMethods'); // ✅ OK - Dynamic import when necessary (lazy loading, conditional) if (condition) { const module = await import('./heavy-module'); } must_not_do: - rule: Never use .js or .ts extensions in import paths codeExample: | // ❌ BAD - File extensions import { UserService } from '../services/index.js'; import { myTool } from '../tools/MyTool.js'; import { config } from './config.ts'; // ✅ GOOD - No extensions import { UserService } from '../services'; import { myTool } from '../tools/MyTool'; import { config } from './config'; - rule: Never use inline require() statements - use static imports codeExample: | // ❌ BAD - Inline require const { listScaffoldMethods } = require('../hooks/geminiCli/listScaffoldMethods'); const hooks = require('./hooks'); // ✅ GOOD - Static import import { listScaffoldMethods } from '../hooks/geminiCli/listScaffoldMethods'; import hooks from './hooks'; - pattern: export-standards description: Strict export standards enforced across all TypeScript/JavaScript files must_do: - rule: Use direct exports only - export declarations at point of definition codeExample: | // ✅ GOOD - Direct exports export class UserService { getUser() { /* implementation */ } } export function calculateTotal(items: Item[]): number { return items.reduce((sum, item) => sum + item.price, 0); } export const API_ENDPOINTS = { users: '/api/users', orders: '/api/orders' } as const; export type User = { id: string; email: string; }; - rule: Use barrel exports from collocated files via index.ts codeExample: | // ✅ GOOD - Barrel exports in index.ts export { UserService } from './userService'; export { OrderService } from './orderService'; export { PaymentService } from './paymentService'; export type { User, Order, Payment } from './types'; must_not_do: - rule: Never use default exports codeExample: | // ❌ BAD - Default exports export default class UserService {} export default function calculateTotal() {} export default { users: '/api/users' }; - rule: Never use named exports (export statements) codeExample: | // ❌ BAD - Named exports class UserService {} function calculateTotal() {} const API_ENDPOINTS = {}; export { UserService, calculateTotal, API_ENDPOINTS }; - rule: Never use namespace exports codeExample: | // ❌ BAD - Namespace exports export * as UserUtils from './userUtils'; export * from './services'; - pattern: error-handling description: Consistent error handling patterns across all code must_do: - rule: Always use try-catch blocks for async operations codeExample: | // ✅ GOOD async function fetchUser(id: string) { try { const response = await fetch(`/api/users/${id}`); return await response.json(); } catch (error) { throw new Error(`Failed to fetch user: ${error.message}`); } } - rule: Throw descriptive error messages with context codeExample: | // ✅ GOOD if (!userId) { throw new Error('User ID is required for fetching user data'); } - rule: Handle errors at appropriate abstraction levels codeExample: | // ✅ GOOD - Handle in service, propagate meaningful errors async function createOrder(data: OrderData) { try { return await orderService.create(data); } catch (error) { if (error instanceof ValidationError) { throw new BadRequestError('Invalid order data', error.details); } throw new ServerError('Failed to create order', error); } } must_not_do: - rule: Never use empty catch blocks codeExample: | // ❌ BAD try { await dangerousOperation(); } catch (e) { // Silent failure! } - rule: Never catch errors without proper handling or re-throwing codeExample: | // ❌ BAD try { await operation(); } catch (error) { console.log('Something went wrong'); // Only logging, not handling } - rule: Never expose sensitive error details to clients codeExample: | // ❌ BAD catch (error) { return { error: error.stack }; // Exposing stack trace } - pattern: naming-conventions description: Consistent naming conventions across all code must_do: - rule: Use PascalCase for classes, interfaces, types, and enums codeExample: | // ✅ GOOD class UserService {} interface UserData {} type OrderStatus = 'pending' | 'completed'; enum PaymentMethod { CREDIT_CARD, PAYPAL } - rule: Use camelCase for variables, functions, and methods codeExample: | // ✅ GOOD const userName = 'John'; function getUserById(id: string) {} const handleSubmit = () => {}; - rule: Use UPPER_SNAKE_CASE for constants codeExample: | // ✅ GOOD const MAX_RETRY_ATTEMPTS = 3; const API_BASE_URL = 'https://api.example.com'; - rule: Use camelCase for file names codeExample: | // ✅ GOOD userService.ts paymentProcessor.ts orderValidation.ts must_not_do: - rule: Never mix naming conventions codeExample: | // ❌ BAD class user_service {} // Wrong: should be PascalCase const UserName = 'John'; // Wrong: should be camelCase function GetUserById() {} // Wrong: should be camelCase - rule: Never use abbreviations unless widely recognized codeExample: | // ❌ BAD const usrNm = 'John'; function getUsrByID() {} // ✅ GOOD const userName = 'John'; function getUserById() {} - pattern: constants-usage description: Avoid magic strings and hardcoded values - use constants for maintainability must_do: - rule: Define constants in a dedicated constants file or folder codeExample: | // ✅ GOOD - Constants in dedicated file // src/constants/index.ts export const CONFIG_FILENAME = 'config.yaml'; export const CONFIG_FILENAME_HIDDEN = '.config.yaml'; export const CONFIG_FILENAMES = [CONFIG_FILENAME_HIDDEN, CONFIG_FILENAME] as const; export const DEFAULT_TIMEOUT = 30000; export const MAX_RETRIES = 3; - rule: Import and use constants instead of inline magic strings codeExample: | // ✅ GOOD - Using constants import { CONFIG_FILENAME, DEFAULT_TIMEOUT } from '../constants'; const configPath = path.join(dir, CONFIG_FILENAME); const timeout = options.timeout ?? DEFAULT_TIMEOUT; // ❌ BAD - Magic strings inline const configPath = path.join(dir, 'config.yaml'); const timeout = options.timeout ?? 30000; - rule: Use constants for repeated string literals (filenames, keys, messages) codeExample: | // ✅ GOOD - Constants for filenames export const ARCHITECT_FILENAME = 'architect.yaml'; export const RULES_FILENAME = 'RULES.yaml'; export const SCAFFOLD_FILENAME = 'scaffold.yaml'; // Then use everywhere if (file.endsWith(ARCHITECT_FILENAME)) { } const rulesPath = path.join(dir, RULES_FILENAME); - rule: Group related constants together codeExample: | // ✅ GOOD - Related constants grouped // File patterns export const ARCHITECT_FILENAME = 'architect.yaml'; export const ARCHITECT_FILENAME_HIDDEN = '.architect.yaml'; export const ARCHITECT_FILENAMES = [ARCHITECT_FILENAME_HIDDEN, ARCHITECT_FILENAME] as const; // Timeouts export const DEFAULT_TIMEOUT_MS = 30000; export const MAX_TIMEOUT_MS = 600000; // Limits export const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024; // 10MB export const MAX_RESULTS = 100; must_not_do: - rule: Never use magic strings - inline string literals that have special meaning codeExample: | // ❌ BAD - Magic strings if (filename === 'architect.yaml') { } const path = join(dir, 'RULES.yaml'); await fs.readFile('config.json'); // ✅ GOOD - Use constants import { ARCHITECT_FILENAME, RULES_FILENAME, CONFIG_FILENAME } from '../constants'; if (filename === ARCHITECT_FILENAME) { } const path = join(dir, RULES_FILENAME); await fs.readFile(CONFIG_FILENAME); - rule: Never use magic numbers - inline numeric literals with special meaning codeExample: | // ❌ BAD - Magic numbers setTimeout(callback, 30000); if (retries > 3) { } const maxSize = 10485760; // ✅ GOOD - Named constants import { DEFAULT_TIMEOUT_MS, MAX_RETRIES, MAX_FILE_SIZE_BYTES } from '../constants'; setTimeout(callback, DEFAULT_TIMEOUT_MS); if (retries > MAX_RETRIES) { } const maxSize = MAX_FILE_SIZE_BYTES; - rule: Never duplicate the same literal value across multiple files codeExample: | // ❌ BAD - Same string in multiple files // file1.ts const config = path.join(dir, 'architect.yaml'); // file2.ts if (name.endsWith('architect.yaml')) { } // file3.ts await fs.access(path.join(root, 'architect.yaml')); // ✅ GOOD - Single source of truth // constants/index.ts export const ARCHITECT_FILENAME = 'architect.yaml'; // All files import from constants import { ARCHITECT_FILENAME } from '../constants'; - pattern: type-safety description: Strong type safety standards for TypeScript code must_do: - rule: Always provide explicit return types for functions codeExample: | // ✅ GOOD function calculateTotal(items: Item[]): number { return items.reduce((sum, item) => sum + item.price, 0); } async function fetchUser(id: string): Promise<User> { const response = await fetch(`/api/users/${id}`); return response.json(); } - rule: Define interfaces for object shapes codeExample: | // ✅ GOOD interface User { id: string; email: string; name: string; } function createUser(data: User): User { return { ...data }; } - rule: Use type guards for runtime type checking codeExample: | // ✅ GOOD function isUser(value: unknown): value is User { return ( typeof value === 'object' && value !== null && 'id' in value && 'email' in value ); } must_not_do: - rule: Never use 'any' type unless absolutely necessary codeExample: | // ❌ BAD function processData(data: any) { return data.someProperty; } // ✅ GOOD function processData(data: UserData) { return data.email; } - rule: Never use type assertions to bypass type checking codeExample: | // ❌ BAD const user = response as User; // Unsafe // ✅ GOOD if (isUser(response)) { const user = response; // Type-safe } - rule: Never ignore TypeScript errors with @ts-ignore codeExample: | // ❌ BAD // @ts-ignore const value = dangerousOperation(); - pattern: documentation-standards description: Code documentation standards must_do: - rule: Add JSDoc comments for all public APIs codeExample: | // ✅ GOOD /** * Calculates the total price of items in the cart * @param items - Array of items to calculate total for * @returns The total price as a number */ export function calculateTotal(items: Item[]): number { return items.reduce((sum, item) => sum + item.price, 0); } - rule: Document complex logic with inline comments codeExample: | // ✅ GOOD // Apply discount based on user tier (10% for premium, 5% for standard) const discount = user.tier === 'premium' ? 0.1 : 0.05; const finalPrice = basePrice * (1 - discount); - rule: Keep README.md updated with setup and usage instructions should_do: - rule: Add examples in JSDoc for complex functions - rule: Document edge cases and assumptions - rule: Keep comments up-to-date with code changes must_not_do: - rule: Never leave commented-out code codeExample: | // ❌ BAD function processOrder() { // const oldImplementation = doSomething(); // return oldImplementation; return newImplementation(); } - rule: Never use obvious comments that don't add value codeExample: | // ❌ BAD // Increment counter by 1 counter++; // ✅ GOOD (no comment needed for obvious code) counter++; - pattern: async-await-patterns description: Best practices for asynchronous code must_do: - rule: Always use async/await over raw promises codeExample: | // ✅ GOOD async function fetchUserData(id: string): Promise<User> { const response = await fetch(`/api/users/${id}`); return response.json(); } - rule: Handle promise rejections with try-catch codeExample: | // ✅ GOOD async function saveUser(user: User): Promise<void> { try { await database.save(user); } catch (error) { throw new Error(`Failed to save user: ${error.message}`); } } - rule: Use Promise.all for parallel operations codeExample: | // ✅ GOOD async function fetchMultipleUsers(ids: string[]): Promise<User[]> { const promises = ids.map(id => fetchUser(id)); return Promise.all(promises); } must_not_do: - rule: Never mix async/await with .then/.catch chains codeExample: | // ❌ BAD async function badExample() { await operation() .then(result => process(result)) .catch(error => handle(error)); } // ✅ GOOD async function goodExample() { try { const result = await operation(); return process(result); } catch (error) { handle(error); } } - rule: Never forget to await async functions codeExample: | // ❌ BAD async function badExample() { saveUser(user); // Missing await! return; } // ✅ GOOD async function goodExample() { await saveUser(user); return; } - pattern: test-pattern description: Test pattern description - pattern: duplicate-pattern description: Test pattern description

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AgiFlow/aicode-toolkit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server