Setup
Set up your development environment for contributing to ao-forge.
Overview
This guide will help you set up a development environment for contributing to ao-forge. We'll cover everything from cloning the repository to running tests.
Prerequisites
Before you begin, make sure you have the following installed:
Repository Setup
Clone the Repository
# Clone the repository
git clone https://github.com/ao-forge/ao-forge.git
cd ao-forge
# Add your fork as a remote
git remote add fork https://github.com/YOUR_USERNAME/ao-forge.git
Install Dependencies
# Install dependencies
npm install
# Or using pnpm
pnpm install
# Or using yarn
yarn install
Verify Installation
# Check if everything is working
npm run test
# Check if CLI is working
npm run build
node dist/cli.js --version
Development Environment
VS Code Setup
Recommended Extensions
{
"recommendations": [
"ms-vscode.vscode-typescript-next",
"bradlc.vscode-tailwindcss",
"esbenp.prettier-vscode",
"ms-vscode.vscode-eslint",
"ms-vscode.vscode-json",
"redhat.vscode-yaml",
"ms-vscode.vscode-markdown"
]
}
Workspace Settings
{
"typescript.preferences.importModuleSpecifier": "relative",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"files.associations": {
"*.lua": "lua"
}
}
Environment Variables
Create Environment File
# Copy example environment file
cp .env.example .env
# Edit environment file
nano .env
Environment Configuration
# .env
NODE_ENV=development
AO_ENV=testnet
AO_GATEWAY=https://arweave.net
AO_WALLET_PATH=./wallet.json
Project Structure
Directory Layout
ao-forge/
├── src/ # Source code
│ ├── cli/ # CLI commands
│ ├── managers/ # Manager classes
│ ├── templates/ # Project templates
│ ├── utils/ # Utility functions
│ └── types/ # TypeScript types
├── templates/ # Project templates
├── docs/ # Documentation
├── tests/ # Test files
├── examples/ # Example projects
├── scripts/ # Build and utility scripts
├── .github/ # GitHub workflows
├── package.json # Package configuration
├── tsconfig.json # TypeScript configuration
├── jest.config.js # Jest configuration
└── README.md # Project README
Key Files
src/cli/index.ts
- Main CLI entry pointsrc/managers/
- Manager classes for different functionalitytemplates/
- Project templatestests/
- Test filespackage.json
- Package configuration and scripts
Development Workflow
Running the Development Server
# Start development server
npm run dev
# Watch for changes
npm run watch
# Build the project
npm run build
Running Tests
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
# Run specific test file
npm test -- tests/cli/init.test.ts
Linting and Formatting
# Run linter
npm run lint
# Fix linting issues
npm run lint:fix
# Format code
npm run format
# Check formatting
npm run format:check
Testing
Test Structure
// tests/cli/init.test.ts
import { InitCommand } from '../../src/cli/init'
import { ProjectManager } from '../../src/managers/project'
describe('InitCommand', () => {
let initCommand: InitCommand
let projectManager: ProjectManager
beforeEach(() => {
initCommand = new InitCommand()
projectManager = new ProjectManager()
})
it('should create a new project', async () => {
// Test implementation
})
})
Test Utilities
// tests/utils/test-helpers.ts
import { execSync } from 'child_process'
import { mkdtemp, rm } from 'fs/promises'
import { tmpdir } from 'os'
import { join } from 'path'
export async function createTempDir(): Promise<string> {
const tempDir = await mkdtemp(join(tmpdir(), 'ao-forge-test-'))
return tempDir
}
export async function cleanupTempDir(dir: string): Promise<void> {
await rm(dir, { recursive: true, force: true })
}
export function runCommand(command: string, cwd: string): string {
return execSync(command, { cwd, encoding: 'utf8' })
}
Mocking
// tests/mocks/process-manager.mock.ts
export const mockProcessManager = {
startProcess: jest.fn(),
stopProcess: jest.fn(),
listProcesses: jest.fn(),
getStatus: jest.fn()
}
Building
Build Process
# Build the project
npm run build
# Build with type checking
npm run build:check
# Build for production
npm run build:prod
Build Configuration
{
"scripts": {
"build": "tsc",
"build:check": "tsc --noEmit",
"build:prod": "tsc && npm run optimize",
"optimize": "terser dist/**/*.js -o dist/cli.min.js"
}
}
Debugging
Debug Configuration
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug CLI",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/dist/cli.js",
"args": ["init", "test-project"],
"console": "integratedTerminal",
"skipFiles": ["<node_internals>/**"]
}
]
}
Debug Commands
# Debug with Node.js
node --inspect dist/cli.js init test-project
# Debug with VS Code
# Set breakpoints and use F5 to start debugging
Git Workflow
Branch Strategy
# Create feature branch
git checkout -b feature/new-feature
# Create bugfix branch
git checkout -b bugfix/fix-issue
# Create hotfix branch
git checkout -b hotfix/critical-fix
Commit Messages
# Use conventional commits
git commit -m "feat: add new command for process management"
git commit -m "fix: resolve issue with build process"
git commit -m "docs: update installation guide"
git commit -m "test: add tests for new functionality"
Pull Request Process
- Create feature branch from main
- Make changes and commit
- Run tests and ensure they pass
- Create pull request with description
- Address review feedback
- Merge after approval
Code Style
TypeScript Guidelines
// Use interfaces for object shapes
interface User {
id: string
name: string
email: string
}
// Use type aliases for unions
type Status = 'pending' | 'approved' | 'rejected'
// Use enums for constants
enum ErrorCode {
NOT_FOUND = 'NOT_FOUND',
VALIDATION_ERROR = 'VALIDATION_ERROR'
}
Naming Conventions
// Use PascalCase for classes
class ProjectManager {}
// Use camelCase for functions and variables
const projectName = 'my-project'
function createProject() {}
// Use UPPER_CASE for constants
const DEFAULT_PORT = 3000
Documentation
/**
* Creates a new project with the specified options
* @param options - Project creation options
* @returns Promise that resolves when project is created
* @throws {Error} When project creation fails
*/
async function createProject(options: CreateProjectOptions): Promise<void> {
// Implementation
}
Troubleshooting
Common Issues
Build Failures
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
# Check TypeScript errors
npm run build:check
Test Failures
# Run tests with verbose output
npm test -- --verbose
# Run specific test
npm test -- --testNamePattern="should create project"
Dependency Issues
# Check for outdated packages
npm outdated
# Update dependencies
npm update
# Check for security vulnerabilities
npm audit
Next Steps
- Development Guide - Learn about development practices
- Testing Guide - Learn about testing practices
- Code Review Process - Learn about code review
- Release Process - Learn about releases
Getting Help
Resources
- GitHub Issues - Report bugs and ask questions
- Discord Community - Community support
- Documentation - Comprehensive documentation
- Examples - Example projects and use cases
Contact
- Maintainers: @ao-forge/maintainers
- Discord: ao-forge Discord
- Email: contact@ao-forge.dev