mirror of
https://github.com/actualbudget/actual.git
synced 2026-04-30 01:40:02 -05:00
docs: add AGENTS.md guide for AI agents (#5942)
This commit is contained in:
committed by
GitHub
parent
2bce9d707c
commit
7c19a6333c
@@ -1,12 +0,0 @@
|
||||
---
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
When running yarn commands - always run them in the root directory. Do not run them in child workspaces.
|
||||
|
||||
The following commands can be useful:
|
||||
|
||||
- `yarn typecheck` to run typechecker
|
||||
- `yarn lint` to run the code linter and formatter
|
||||
- `yarn lint:fix` to fix some of the code lint issues (running this is preferred over `yarn lint`)
|
||||
- `yarn test` to run all the tests
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
description:
|
||||
globs: *.ts,*.tsx
|
||||
alwaysApply: false
|
||||
---
|
||||
|
||||
You are an expert in TypeScript and React.
|
||||
|
||||
Code Style and Structure
|
||||
|
||||
- Write concise, technical TypeScript code.
|
||||
- Use functional and declarative programming patterns; avoid classes.
|
||||
- Prefer iteration and modularization over code duplication.
|
||||
- Use descriptive variable names with auxiliary verbs (e.g., isLoaded, hasError).
|
||||
- Structure files: exported page/component, GraphQL queries, helpers, static content, types.
|
||||
- When creating a new component, place it in its own file rather than grouping multiple components in a single file.
|
||||
|
||||
Naming Conventions
|
||||
|
||||
- Favor named exports for components and utilities.
|
||||
|
||||
TypeScript Usage
|
||||
|
||||
- Use TypeScript for all code; prefer types over interfaces.
|
||||
- Avoid enums; use objects or maps instead.
|
||||
- Avoid using `any` or `unknown` unless absolutely necessary. Look for type definitions in the codebase instead.
|
||||
- Avoid type assertions with `as` or `!`; prefer using `satisfies`.
|
||||
|
||||
Syntax and Formatting
|
||||
|
||||
- Use the "function" keyword for pure functions.
|
||||
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements.
|
||||
- Use declarative JSX, keeping JSX minimal and readable.
|
||||
|
||||
Change validation
|
||||
|
||||
- Run `yarn typecheck` in the root directory to validate that the generated TypeScript code is correct
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
description:
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
Vitest test runner is used for unit tests.
|
||||
|
||||
When running unit tests, always include the flag `--watch=false` to prevent watch mode.
|
||||
|
||||
To run unit tests for a specific package in the monorepo, use the following command:
|
||||
|
||||
`yarn workspace <workspaceNameFromPackageJson> run test <pathToTest>`
|
||||
|
||||
Recommendation: Minimize the number of dependencies you mock. The fewer dependencies you mock, the better.
|
||||
538
AGENTS.md
Normal file
538
AGENTS.md
Normal file
@@ -0,0 +1,538 @@
|
||||
# AGENTS.md - Guide for AI Agents Working with Actual Budget
|
||||
|
||||
This guide provides comprehensive information for AI agents (like Cursor) working with the Actual Budget codebase.
|
||||
|
||||
## Project Overview
|
||||
|
||||
**Actual Budget** is a local-first personal finance tool written in TypeScript/JavaScript. It's 100% free and open-source with synchronization capabilities across devices.
|
||||
|
||||
- **Repository**: https://github.com/actualbudget/actual
|
||||
- **Community Docs**: https://github.com/actualbudget/docs or https://actualbudget.org/docs
|
||||
- **License**: MIT
|
||||
- **Primary Language**: TypeScript (with React)
|
||||
- **Build System**: Yarn 4 workspaces (monorepo)
|
||||
|
||||
## Quick Start Commands
|
||||
|
||||
### Essential Commands (Run from Root)
|
||||
|
||||
```bash
|
||||
# Type checking (ALWAYS run before committing)
|
||||
yarn typecheck
|
||||
|
||||
# Linting and formatting (with auto-fix)
|
||||
yarn lint:fix
|
||||
|
||||
# Run all tests
|
||||
yarn test
|
||||
|
||||
# Start development server (browser)
|
||||
yarn start
|
||||
|
||||
# Start with sync server
|
||||
yarn start:server-dev
|
||||
|
||||
# Start desktop app development
|
||||
yarn start:desktop
|
||||
```
|
||||
|
||||
### Important Rules
|
||||
|
||||
- **ALWAYS run yarn commands from the root directory** - never run them in child workspaces
|
||||
- Use `yarn workspace <workspace-name> run <command>` for workspace-specific tasks
|
||||
- Include `--watch=false` flag when running unit tests to prevent watch mode
|
||||
|
||||
## Architecture & Package Structure
|
||||
|
||||
### Core Packages
|
||||
|
||||
#### 1. **loot-core** (`packages/loot-core/`)
|
||||
|
||||
The core application logic that runs on any platform.
|
||||
|
||||
- Business logic, database operations, and calculations
|
||||
- Platform-agnostic code
|
||||
- Exports for both browser and node environments
|
||||
- Test commands:
|
||||
```bash
|
||||
yarn workspace loot-core run test --watch=false
|
||||
```
|
||||
|
||||
#### 2. **desktop-client** (`packages/desktop-client/` - aliased as `@actual-app/web`)
|
||||
|
||||
The React-based UI for web and desktop.
|
||||
|
||||
- React components using functional programming patterns
|
||||
- E2E tests using Playwright
|
||||
- Vite for bundling
|
||||
- Commands:
|
||||
|
||||
```bash
|
||||
# Development
|
||||
yarn workspace @actual-app/web start:browser
|
||||
|
||||
# Build
|
||||
yarn workspace @actual-app/web build
|
||||
|
||||
# E2E tests
|
||||
yarn workspace @actual-app/web e2e
|
||||
|
||||
# Visual regression tests
|
||||
yarn workspace @actual-app/web vrt
|
||||
```
|
||||
|
||||
#### 3. **desktop-electron** (`packages/desktop-electron/`)
|
||||
|
||||
Electron wrapper for the desktop application.
|
||||
|
||||
- Window management and native OS integration
|
||||
- E2E tests for Electron-specific features
|
||||
|
||||
#### 4. **api** (`packages/api/` - aliased as `@actual-app/api`)
|
||||
|
||||
Public API for programmatic access to Actual.
|
||||
|
||||
- Node.js API
|
||||
- Designed for integrations and automation
|
||||
- Commands:
|
||||
```bash
|
||||
yarn workspace @actual-app/api build
|
||||
yarn workspace @actual-app/api test --watch=false
|
||||
```
|
||||
|
||||
#### 5. **sync-server** (`packages/sync-server/` - aliased as `@actual-app/sync-server`)
|
||||
|
||||
Synchronization server for multi-device support.
|
||||
|
||||
- Express-based server
|
||||
- Currently transitioning to TypeScript (mostly JavaScript)
|
||||
- Commands:
|
||||
```bash
|
||||
yarn workspace @actual-app/sync-server start
|
||||
```
|
||||
|
||||
#### 6. **component-library** (`packages/component-library/` - aliased as `@actual-app/components`)
|
||||
|
||||
Reusable React UI components.
|
||||
|
||||
- Shared components like Button, Input, Menu, etc.
|
||||
- Theme system and design tokens
|
||||
- Icons (375+ icons in SVG/TSX format)
|
||||
|
||||
#### 7. **crdt** (`packages/crdt/` - aliased as `@actual-app/crdt`)
|
||||
|
||||
CRDT (Conflict-free Replicated Data Type) implementation for data synchronization.
|
||||
|
||||
- Protocol buffers for serialization
|
||||
- Core sync logic
|
||||
|
||||
#### 8. **plugins-service** (`packages/plugins-service/`)
|
||||
|
||||
Service for handling plugins/extensions.
|
||||
|
||||
#### 9. **eslint-plugin-actual** (`packages/eslint-plugin-actual/`)
|
||||
|
||||
Custom ESLint rules specific to Actual.
|
||||
|
||||
- `no-untranslated-strings`: Enforces i18n usage
|
||||
- `prefer-trans-over-t`: Prefers Trans component over t() function
|
||||
- `prefer-logger-over-console`: Enforces using logger instead of console
|
||||
- `typography`: Typography rules
|
||||
- `prefer-if-statement`: Prefers explicit if statements
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### 1. Making Changes
|
||||
|
||||
When implementing changes:
|
||||
|
||||
1. Read relevant files to understand current implementation
|
||||
2. Make focused, incremental changes
|
||||
3. Run type checking: `yarn typecheck`
|
||||
4. Run linting: `yarn lint:fix`
|
||||
5. Run relevant tests
|
||||
6. Fix any linter errors that are introduced
|
||||
|
||||
### 2. Testing Strategy
|
||||
|
||||
**Unit Tests (Vitest)**
|
||||
|
||||
```bash
|
||||
# All tests
|
||||
yarn test
|
||||
|
||||
# Specific package
|
||||
yarn workspace loot-core run test --watch=false
|
||||
|
||||
# Specific test file
|
||||
yarn workspace loot-core run test path/to/test.test.ts --watch=false
|
||||
```
|
||||
|
||||
**E2E Tests (Playwright)**
|
||||
|
||||
```bash
|
||||
# Desktop client E2E
|
||||
yarn workspace @actual-app/web e2e
|
||||
|
||||
# Desktop Electron E2E
|
||||
yarn e2e:desktop
|
||||
|
||||
# Visual regression tests
|
||||
yarn vrt
|
||||
|
||||
# Visual regression in Docker (consistent environment)
|
||||
yarn vrt:docker
|
||||
```
|
||||
|
||||
**Testing Best Practices:**
|
||||
|
||||
- Minimize mocked dependencies - prefer real implementations
|
||||
- Use descriptive test names
|
||||
- Vitest globals are available: `describe`, `it`, `expect`, `beforeEach`, etc.
|
||||
- For sync-server tests, globals are explicitly defined in config
|
||||
|
||||
### 3. Type Checking
|
||||
|
||||
TypeScript configuration uses:
|
||||
|
||||
- Incremental compilation
|
||||
- Strict type checking with `typescript-strict-plugin`
|
||||
- Platform-specific exports in `loot-core` (node vs browser)
|
||||
|
||||
Always run `yarn typecheck` before committing.
|
||||
|
||||
### 4. Internationalization (i18n)
|
||||
|
||||
- Use `Trans` component instead of `t()` function when possible
|
||||
- All user-facing strings must be translated
|
||||
- Generate i18n files: `yarn generate:i18n`
|
||||
- Custom ESLint rules enforce translation usage
|
||||
|
||||
## Code Style & Conventions
|
||||
|
||||
### TypeScript Guidelines
|
||||
|
||||
**Type Usage:**
|
||||
|
||||
- Use TypeScript for all code
|
||||
- Prefer `type` over `interface`
|
||||
- Avoid `enum` - use objects or maps
|
||||
- Avoid `any` or `unknown` unless absolutely necessary
|
||||
- Look for existing type definitions in the codebase
|
||||
- Avoid type assertions (`as`, `!`) - prefer `satisfies`
|
||||
- Use inline type imports: `import { type MyType } from '...'`
|
||||
|
||||
**Naming:**
|
||||
|
||||
- Use descriptive variable names with auxiliary verbs (e.g., `isLoaded`, `hasError`)
|
||||
- Named exports for components and utilities (avoid default exports except in specific cases)
|
||||
|
||||
**Code Structure:**
|
||||
|
||||
- Functional and declarative programming patterns - avoid classes
|
||||
- Use the `function` keyword for pure functions
|
||||
- Prefer iteration and modularization over code duplication
|
||||
- Structure files: exported component/page, helpers, static content, types
|
||||
- Create new components in their own files
|
||||
|
||||
**React Patterns:**
|
||||
|
||||
- Don't use `React.FunctionComponent` or `React.FC` - type props directly
|
||||
- Don't use `React.*` patterns - use named imports instead
|
||||
- Use `<Link>` instead of `<a>` tags
|
||||
- Use custom hooks from `src/hooks` (not react-router directly):
|
||||
- `useNavigate()` from `src/hooks` (not react-router)
|
||||
- `useDispatch()`, `useSelector()`, `useStore()` from `src/redux` (not react-redux)
|
||||
- Avoid unstable nested components
|
||||
- Use `satisfies` for type narrowing
|
||||
|
||||
**JSX Style:**
|
||||
|
||||
- Declarative JSX, minimal and readable
|
||||
- Avoid unnecessary curly braces in conditionals
|
||||
- Use concise syntax for simple statements
|
||||
- Prefer explicit expressions (`condition && <Component />`)
|
||||
|
||||
### Import Organization
|
||||
|
||||
Imports are automatically organized by ESLint with the following order:
|
||||
|
||||
1. React imports (first)
|
||||
2. Built-in Node.js modules
|
||||
3. External packages
|
||||
4. Actual packages (`loot-core`, `@actual-app/components` - legacy pattern `loot-design` may appear in old code)
|
||||
5. Parent imports
|
||||
6. Sibling imports
|
||||
7. Index imports
|
||||
|
||||
Always maintain newlines between import groups.
|
||||
|
||||
### Platform-Specific Code
|
||||
|
||||
- Don't directly reference platform-specific imports (`.api`, `.web`, `.electron`)
|
||||
- Use conditional exports in `loot-core` for platform-specific code
|
||||
- Platform resolution happens at build time via package.json exports
|
||||
|
||||
### Restricted Patterns
|
||||
|
||||
**Never:**
|
||||
|
||||
- Use `console.*` (use logger instead - enforced by ESLint)
|
||||
- Import from `uuid` without destructuring: use `import { v4 as uuidv4 } from 'uuid'`
|
||||
- Import colors directly - use theme instead
|
||||
- Import `@actual-app/web/*` in `loot-core`
|
||||
|
||||
**Git Commands:**
|
||||
|
||||
- Never update git config
|
||||
- Never run destructive git operations (force push, hard reset) unless explicitly requested
|
||||
- Never skip hooks (--no-verify, --no-gpg-sign)
|
||||
- Never force push to main/master
|
||||
- Never commit unless explicitly asked
|
||||
|
||||
## File Structure Patterns
|
||||
|
||||
### Typical Component File
|
||||
|
||||
```typescript
|
||||
import { type ComponentType } from 'react';
|
||||
// ... other imports
|
||||
|
||||
type MyComponentProps = {
|
||||
// Props definition
|
||||
};
|
||||
|
||||
export function MyComponent({ prop1, prop2 }: MyComponentProps) {
|
||||
// Component logic
|
||||
return (
|
||||
// JSX
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Test File
|
||||
|
||||
```typescript
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
// ... imports
|
||||
|
||||
describe('ComponentName', () => {
|
||||
it('should behave as expected', () => {
|
||||
// Test logic
|
||||
expect(result).toBe(expected);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Important Directories & Files
|
||||
|
||||
### Configuration Files
|
||||
|
||||
- `/package.json` - Root workspace configuration, scripts
|
||||
- `/eslint.config.mjs` - ESLint configuration (flat config format)
|
||||
- `/tsconfig.json` - Root TypeScript configuration
|
||||
- `/.cursorignore`, `/.gitignore` - Ignored files
|
||||
- `/yarn.lock` - Dependency lockfile (Yarn 4)
|
||||
|
||||
### Documentation
|
||||
|
||||
- `/README.md` - Project overview
|
||||
- `/CONTRIBUTING.md` - Points to community docs
|
||||
- `/upcoming-release-notes/` - Release notes for next version
|
||||
- `/CODEOWNERS` - Code ownership definitions
|
||||
|
||||
### Build Artifacts (Don't Edit)
|
||||
|
||||
- `packages/*/lib-dist/` - Built output
|
||||
- `packages/*/dist/` - Built output
|
||||
- `packages/*/build/` - Built output
|
||||
- `packages/desktop-client/playwright-report/` - Test reports
|
||||
- `packages/desktop-client/test-results/` - Test results
|
||||
|
||||
### Key Source Directories
|
||||
|
||||
- `packages/loot-core/src/client/` - Client-side core logic
|
||||
- `packages/loot-core/src/server/` - Server-side core logic
|
||||
- `packages/loot-core/src/shared/` - Shared utilities
|
||||
- `packages/loot-core/src/types/` - Type definitions
|
||||
- `packages/desktop-client/src/components/` - React components
|
||||
- `packages/desktop-client/src/hooks/` - Custom React hooks
|
||||
- `packages/desktop-client/e2e/` - End-to-end tests
|
||||
- `packages/component-library/src/` - Reusable components
|
||||
- `packages/component-library/src/icons/` - Icon components (auto-generated, don't edit)
|
||||
|
||||
## Common Development Tasks
|
||||
|
||||
### Running Specific Tests
|
||||
|
||||
```bash
|
||||
# Unit test for a specific file in loot-core
|
||||
yarn workspace loot-core run test src/path/to/file.test.ts --watch=false
|
||||
|
||||
# E2E test for a specific file
|
||||
yarn workspace @actual-app/web run playwright test accounts.test.ts --browser=chromium
|
||||
```
|
||||
|
||||
### Building for Production
|
||||
|
||||
```bash
|
||||
# Browser build
|
||||
yarn build:browser
|
||||
|
||||
# Desktop build
|
||||
yarn build:desktop
|
||||
|
||||
# API build
|
||||
yarn build:api
|
||||
|
||||
# Sync server build
|
||||
yarn build:server
|
||||
```
|
||||
|
||||
### Type Checking Specific Packages
|
||||
|
||||
TypeScript uses project references. Run `yarn typecheck` from root to check all packages.
|
||||
|
||||
### Debugging Tests
|
||||
|
||||
```bash
|
||||
# Run tests in debug mode (without parallelization)
|
||||
yarn test:debug
|
||||
|
||||
# Run specific E2E test with headed browser
|
||||
yarn workspace @actual-app/web run playwright test --headed --debug accounts.test.ts
|
||||
```
|
||||
|
||||
### Working with Icons
|
||||
|
||||
Icons in `packages/component-library/src/icons/` are auto-generated. Don't manually edit them.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Type Errors
|
||||
|
||||
1. Run `yarn typecheck` to see all type errors
|
||||
2. Check if types are imported correctly
|
||||
3. Look for existing type definitions in `packages/loot-core/src/types/`
|
||||
4. Use `satisfies` instead of `as` for type narrowing
|
||||
|
||||
### Linter Errors
|
||||
|
||||
1. Run `yarn lint:fix` to auto-fix many issues
|
||||
2. Check ESLint output for specific rule violations
|
||||
3. Custom rules:
|
||||
- `actual/no-untranslated-strings` - Add i18n
|
||||
- `actual/prefer-trans-over-t` - Use Trans component
|
||||
- `actual/prefer-logger-over-console` - Use logger
|
||||
- Check `eslint.config.mjs` for complete rules
|
||||
|
||||
### Test Failures
|
||||
|
||||
1. Check if test is running in correct environment (node vs web)
|
||||
2. For Vitest: check `vitest.config.ts` or `vitest.web.config.ts`
|
||||
3. For Playwright: check `playwright.config.ts`
|
||||
4. Ensure mock minimization - prefer real implementations
|
||||
|
||||
### Import Resolution Issues
|
||||
|
||||
1. Check `tsconfig.json` for path mappings
|
||||
2. Check package.json `exports` field (especially for loot-core)
|
||||
3. Verify platform-specific imports (`.web`, `.electron`, `.api`)
|
||||
4. Use absolute imports in `desktop-client` (enforced by ESLint)
|
||||
|
||||
### Build Failures
|
||||
|
||||
1. Clean build artifacts: `rm -rf packages/*/dist packages/*/lib-dist packages/*/build`
|
||||
2. Reinstall dependencies: `yarn install`
|
||||
3. Check Node.js version (requires >=20)
|
||||
4. Check Yarn version (requires ^4.9.1)
|
||||
|
||||
## Testing Patterns
|
||||
|
||||
### Unit Tests
|
||||
|
||||
- Located alongside source files or in `__tests__` directories
|
||||
- Use `.test.ts`, `.test.tsx`, `.spec.js` extensions
|
||||
- Vitest is the test runner
|
||||
- Minimize mocking - prefer real implementations
|
||||
|
||||
### E2E Tests
|
||||
|
||||
- Located in `packages/desktop-client/e2e/`
|
||||
- Use Playwright test runner
|
||||
- Visual regression snapshots in `*-snapshots/` directories
|
||||
- Page models in `e2e/page-models/` for reusable page interactions
|
||||
- Mobile tests have `.mobile.test.ts` suffix
|
||||
|
||||
### Visual Regression Tests (VRT)
|
||||
|
||||
- Run with `VRT=true` environment variable
|
||||
- Snapshots stored per test file
|
||||
- Use Docker for consistent environment: `yarn vrt:docker`
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- **Community Documentation**: https://actualbudget.org/docs/contributing/
|
||||
- **Discord Community**: https://discord.gg/pRYNYr4W5A
|
||||
- **GitHub Issues**: https://github.com/actualbudget/actual/issues
|
||||
- **Feature Requests**: Label "needs votes" sorted by reactions
|
||||
|
||||
## Code Quality Checklist
|
||||
|
||||
Before committing changes, ensure:
|
||||
|
||||
- [ ] `yarn typecheck` passes
|
||||
- [ ] `yarn lint:fix` has been run
|
||||
- [ ] Relevant tests pass
|
||||
- [ ] No new console.\* usage (use logger)
|
||||
- [ ] User-facing strings are translated
|
||||
- [ ] Prefer `type` over `interface`
|
||||
- [ ] Named exports used (not default exports)
|
||||
- [ ] Imports are properly ordered
|
||||
- [ ] Platform-specific code uses proper exports
|
||||
- [ ] No unnecessary type assertions
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
When creating pull requests:
|
||||
|
||||
- **AI-Generated PRs**: If you create a PR using AI assistance, add the **"AI generated"** label to the pull request. This helps maintainers understand the nature of the contribution.
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- **Bundle Size**: Check with rollup-plugin-visualizer
|
||||
- **Type Checking**: Uses incremental compilation
|
||||
- **Testing**: Tests run in parallel by default
|
||||
- **Linting**: ESLint caches results for faster subsequent runs
|
||||
|
||||
## Workspace Commands Reference
|
||||
|
||||
```bash
|
||||
# List all workspaces
|
||||
yarn workspaces list
|
||||
|
||||
# Run command in specific workspace
|
||||
yarn workspace <workspace-name> run <command>
|
||||
|
||||
# Run command in all workspaces
|
||||
yarn workspaces foreach --all run <command>
|
||||
|
||||
# Install production dependencies only (for server deployment)
|
||||
yarn install:server
|
||||
```
|
||||
|
||||
## Environment Requirements
|
||||
|
||||
- **Node.js**: >=20
|
||||
- **Yarn**: ^4.9.1 (managed by packageManager field)
|
||||
- **Browser Targets**: Electron >= 35.0, modern browsers (see browserslist)
|
||||
|
||||
## Migration Notes
|
||||
|
||||
The codebase is actively being migrated:
|
||||
|
||||
- **JavaScript → TypeScript**: sync-server is in progress
|
||||
- **Classes → Functions**: Prefer functional patterns
|
||||
- **React.\* → Named Imports**: Legacy React.\* patterns being removed
|
||||
|
||||
When working with older code, follow the newer patterns described in this guide.
|
||||
6
upcoming-release-notes/5942.md
Normal file
6
upcoming-release-notes/5942.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Maintenance
|
||||
authors: [MatissJanis]
|
||||
---
|
||||
|
||||
Add AGENTS.md file for Cursor, Windsurf, Claud, etc. - AI agents
|
||||
Reference in New Issue
Block a user