Skip to main content

Contributing to Project AIRI

Thank you for your interest in contributing to Project AIRI! This guide will help you get started with development, understand our workflows, and make your first contribution.
We welcome all types of contributions: code, documentation, translations, bug reports, feature requests, and community support!

Prerequisites

Before you begin, make sure you have the following installed:

Git

Version control systemDownload Git

Node.js 23+

JavaScript runtimeDownload Node.js

pnpm

Fast, disk space efficient package manager
corepack enable
corepack prepare pnpm@latest --activate

corepack

Package manager manager (comes with Node.js)Already included with Node.js 16+

Platform-Specific Setup

1

Install Visual Studio

2

Install Scoop

Open PowerShell:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
3

Install Dependencies

scoop install git nodejs rustup

# For Rust dependencies (optional, only for crates/)
scoop install main/rust-msvc
rustup toolchain install stable-x86_64-pc-windows-msvc
rustup default stable-x86_64-pc-windows-msvc
4

Install pnpm

corepack enable
corepack prepare pnpm@latest --activate

Optional: Install @antfu/ni

For a simpler development experience:
npm i -g @antfu/ni
With ni installed, you can:
  • Use ni instead of pnpm install, npm install, yarn install
  • Use nr instead of pnpm run, npm run, yarn run

Getting Started

Fork and Clone

1

Fork the Repository

Click the Fork button on the moeru-ai/airi repository page.
2

Clone Your Fork

git clone https://github.com/<your-github-username>/airi.git
cd airi
3

Add Upstream Remote

git remote add upstream https://github.com/moeru-ai/airi.git

Install Dependencies

corepack enable
pnpm install

# For Rust dependencies (optional, only if working on crates/)
cargo fetch

Create a Working Branch

git checkout -b <your-username>/<feature|fix>/<short-description>

# Examples:
git checkout -b alice/feat/add-weather-widget
git checkout -b bob/fix/memory-leak
Branch naming convention: <username>/<type>/<description>Types: feat, fix, docs, refactor, test, chore

Development Workflow

Choose Your Application

Browser version for airi.moeru.ai
pnpm dev
# or with ni:
nr dev
Opens at: http://localhost:5173

Monorepo Commands

Workspace Filters

Use pnpm filters to scope commands to specific packages:
# Run command in specific workspace
pnpm -F <package-name> <command>

# Examples:
pnpm -F @proj-airi/stage-web dev
pnpm -F @proj-airi/stage-tamagotchi build
pnpm -F @proj-airi/stage-ui typecheck

Common Commands

# Run all apps in parallel
pnpm dev:apps

# Run all packages in dev mode
pnpm dev:packages

# Specific apps
pnpm dev              # Stage Web
pnpm dev:tamagotchi   # Desktop
pnpm dev:pocket       # Mobile
pnpm dev:docs         # Documentation
pnpm dev:ui           # UI Storybook
# Build everything
pnpm build

# Build packages only
pnpm build:packages

# Build apps only
pnpm build:apps

# Build specific workspace
pnpm -F @proj-airi/stage-web build

# Build Rust crates (optional)
pnpm build:crates
# Typecheck all workspaces
pnpm typecheck

# Typecheck specific workspace
pnpm -F @proj-airi/stage-tamagotchi typecheck

# Split checks for Electron
pnpm -F @proj-airi/stage-tamagotchi typecheck:node
pnpm -F @proj-airi/stage-tamagotchi typecheck:web
# Lint all files
pnpm lint

# Lint and fix
pnpm lint:fix

# Lint Rust code
pnpm lint:rust

# Lint Swift code (mobile)
pnpm lint:swift
# Run all tests
pnpm test:run

# Run tests with coverage
pnpm test

# Run specific test file
pnpm exec vitest run <path-to-test-file>

# Run tests in specific workspace
pnpm -F @proj-airi/stage-tamagotchi exec vitest run

Development Services

cd services/discord-bot

# Configure environment
cp .env .env.local
# Edit .env.local with your credentials

# Run the bot
pnpm -F @proj-airi/discord-bot start

Code Style and Conventions

TypeScript

Use kebab-case for all files:
✅ my-component.vue
✅ user-store.ts
✅ fetch-data.ts

❌ MyComponent.vue
❌ UserStore.ts
❌ fetchData.ts

Vue Components

<script setup lang="ts">
import { ref, computed } from 'vue'

// Props
interface Props {
  title: string
  count?: number
}

const props = withDefaults(defineProps<Props>(), {
  count: 0,
})

// Emits
interface Emits {
  update: [value: number]
}

const emit = defineEmits<Emits>()

// State
const localCount = ref(props.count)

// Computed
const displayText = computed(() => `${props.title}: ${localCount.value}`)

// Methods
function increment() {
  localCount.value++
  emit('update', localCount.value)
}
</script>

<template>
  <div :class="[
    'p-4',
    'bg-white dark:bg-black',
    'rounded-lg',
  ]">
    <h2 class="text-xl font-bold mb-2">
      {{ displayText }}
    </h2>
    <button 
      :class="[
        'px-4 py-2',
        'bg-blue-500 hover:bg-blue-600',
        'text-white',
        'rounded',
      ]"
      @click="increment"
    >
      Increment
    </button>
  </div>
</template>

<style scoped>
/* Prefer UnoCSS over scoped styles */
</style>

Comments

Add clear comments for complex logic:
/**
 * Calculates the optimal path using A* algorithm
 * @param start - Starting position
 * @param end - Target position
 * @param obstacles - List of impassable positions
 * @returns Array of positions representing the path
 */
export function findPath(
  start: Position,
  end: Position,
  obstacles: Position[]
): Position[] {
  // Implementation
}

Commit Guidelines

Before Committing

Always run lint and typecheck before committing!
# Lint and fix issues
pnpm lint:fix

# Type check
pnpm typecheck

# Run tests
pnpm test:run

Image Optimization

If committing images, convert to AVIF:
pnpm to-avif <PATH_TO_IMAGE_OR_DIRECTORY>

# Example:
pnpm to-avif docs/images/screenshot.png

Commit Messages

Use Conventional Commits:
# Format
<type>(<scope>): <description>

# Examples
feat(stage-ui): add weather widget component
fix(server-runtime): resolve memory leak in peer registry
docs: update plugin development guide
refactor(stage-web): improve chat message rendering
test(stage-tamagotchi): add tests for settings store
chore: update dependencies
Types:
  • feat: New feature
  • fix: Bug fix
  • docs: Documentation changes
  • style: Code style changes (formatting, etc.)
  • refactor: Code refactoring
  • test: Adding or updating tests
  • chore: Maintenance tasks
  • perf: Performance improvements
Optional: Use gitmoji (emoji prefix)
 feat(stage-ui): add weather widget component
🐛 fix(server-runtime): resolve memory leak
📝 docs: update plugin development guide

Making the Commit

# Stage changes
git add .

# Commit with message
git commit -m "feat(stage-ui): add weather widget component"

# Push to your fork
git push origin <your-branch-name> -u

Creating a Pull Request

1

Push Your Branch

git push origin <your-branch-name> -u
2

Open Pull Request

  1. Navigate to moeru-ai/airi
  2. Click Pull requests tab
  3. Click New pull request
  4. Click Compare across forks
  5. Select your fork and branch
3

Fill PR Template

Provide:
  • Clear title and description
  • What changes were made
  • Why the changes were needed
  • How to test the changes
  • Screenshots/videos if UI changes
  • Related issues (if any)
4

Wait for Review

Maintainers will review your PR and may request changes.

PR Checklist

  • Code follows project style guidelines
  • All tests pass (pnpm test:run)
  • Types are correct (pnpm typecheck)
  • Code is linted (pnpm lint)
  • Commits follow conventional commit format
  • PR description is clear and complete
  • Related documentation updated (if needed)
  • Breaking changes documented (if any)

Keeping Your Fork Updated

# Fetch latest changes
git fetch --all

# Switch to main branch
git checkout main

# Pull latest from upstream
git pull upstream main --rebase

# Update your fork
git push origin main

# Rebase your feature branch (optional)
git checkout <your-branch-name>
git rebase main

Development Best Practices

Module Boundaries

Keep clear module boundaries. Shared logic goes in packages/, app-specific code stays in apps/.

DI Pattern

Use dependency injection (injeca) for better testability and modularity.

Type Safety

Use TypeScript strictly. Avoid any type unless absolutely necessary.

Progressive Refactoring

Improve code you touch. Small refactors are better than big rewrites.

When to Refactor

  • When touching legacy code
  • To improve readability
  • To remove duplication
  • To fix code smells
  • Alongside feature work

Testing Your Changes

Manual Testing

  1. Build the project: pnpm build
  2. Run the app: pnpm dev or pnpm dev:tamagotchi
  3. Test your changes: Follow the test scenarios from your PR description
  4. Test edge cases: Try to break your implementation
  5. Test on different browsers/platforms: If applicable

Automated Testing

# Run unit tests
pnpm test:run

# Run tests with coverage
pnpm test

# Run specific test
pnpm exec vitest run path/to/test.test.ts

# Watch mode (during development)
pnpm exec vitest

Community Guidelines

Communication

Discord

Join our Discord server for real-time chat

GitHub Discussions

Ask questions and share ideas

GitHub Issues

Report bugs and request features

Twitter/X

Follow for project updates

Code of Conduct

  • Be respectful and inclusive
  • Welcome newcomers
  • Assume good intentions
  • Give constructive feedback
  • Focus on the code, not the person
  • Follow project guidelines

Getting Help

  1. Check the prerequisites section
  2. Make sure you’re using Node.js 23+
  3. Try rm -rf node_modules && pnpm install
  4. Ask in Discord #help channel
Don’t worry! Rejection doesn’t mean your contribution isn’t valuable:
  1. Read the review feedback carefully
  2. Ask clarifying questions if needed
  3. Make the requested changes
  4. Push updates to your branch
  5. The PR will be re-reviewed automatically
  1. Check Good First Issues
  2. Look for issues labeled help wanted
  3. Ask in Discord what needs help
  4. Improve documentation (always needed!)
  5. Fix bugs you encounter
Absolutely! We need:
  • Documentation writers: Improve guides and tutorials
  • Translators: Help with i18n on Crowdin
  • Designers: UI/UX improvements, Live2D models, VRM models
  • Testers: Report bugs, test PRs
  • Community helpers: Answer questions, help newcomers
  • Artists: Create promotional materials, screenshots

Non-Code Contributions

Translations

We use Crowdin for translations:
  1. Create a Crowdin account
  2. Join the Project AIRI project
  3. Select your language
  4. Translate strings
  5. Translations will be synced automatically

Documentation

Improve documentation in docs/:
# Start docs dev server
pnpm dev:docs

# Edit MDX files in docs/content/
# Create new pages as needed
# Follow Mintlify syntax

Bug Reports

Good bug reports include:
  • Clear title and description
  • Steps to reproduce
  • Expected vs actual behavior
  • Environment (OS, browser, version)
  • Screenshots/videos
  • Error messages/logs

Feature Requests

Good feature requests include:
  • Clear use case
  • Why it’s valuable
  • How it should work
  • Alternatives considered
  • Willingness to implement (optional)

Resources

Architecture Guide

Understand the codebase structure

Plugin Development

Learn to build plugins

AGENTS.md

Agent development guide

Discord Community

Join the community

Congratulations!

You’re now ready to contribute to Project AIRI! Remember:
  • Start small
  • Ask questions
  • Learn from feedback
  • Help others
  • Have fun!
Thank you for contributing to Project AIRI! Every contribution, no matter how small, helps make AIRI better for everyone.

Build docs developers (and LLMs) love