> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/moeru-ai/airi/llms.txt
> Use this file to discover all available pages before exploring further.

# Contributing Guide

> How to contribute to Project AIRI

# 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.

<Info>
  We welcome all types of contributions: code, documentation, translations, bug reports, feature requests, and community support!
</Info>

## Prerequisites

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

<CardGroup cols={2}>
  <Card title="Git" icon="git-alt">
    Version control system

    [Download Git](https://git-scm.com/downloads)
  </Card>

  <Card title="Node.js 23+" icon="node">
    JavaScript runtime

    [Download Node.js](https://nodejs.org/en/download/)
  </Card>

  <Card title="pnpm" icon="package">
    Fast, disk space efficient package manager

    ```bash theme={null}
    corepack enable
    corepack prepare pnpm@latest --activate
    ```
  </Card>

  <Card title="corepack" icon="box">
    Package manager manager (comes with Node.js)

    Already included with Node.js 16+
  </Card>
</CardGroup>

### Platform-Specific Setup

<Tabs>
  <Tab title="Windows">
    <Steps>
      <Step title="Install Visual Studio">
        Download [Visual Studio](https://visualstudio.microsoft.com/downloads/) and install:

        * Windows SDK
        * C++ build tools

        Follow: [https://rust-lang.github.io/rustup/installation/windows-msvc.html#walkthrough-installing-visual-studio-2022](https://rust-lang.github.io/rustup/installation/windows-msvc.html#walkthrough-installing-visual-studio-2022)
      </Step>

      <Step title="Install Scoop">
        Open PowerShell:

        ```powershell theme={null}
        Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
        Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
        ```
      </Step>

      <Step title="Install Dependencies">
        ```powershell theme={null}
        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
        ```
      </Step>

      <Step title="Install pnpm">
        ```powershell theme={null}
        corepack enable
        corepack prepare pnpm@latest --activate
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="macOS">
    <Steps>
      <Step title="Open Terminal">
        Use Terminal, iTerm2, Ghostty, Kitty, or your preferred terminal.
      </Step>

      <Step title="Install Homebrew">
        If you don't have Homebrew:

        ```bash theme={null}
        /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
        ```
      </Step>

      <Step title="Install Dependencies">
        ```bash theme={null}
        brew install git node
        ```
      </Step>

      <Step title="Install pnpm">
        ```bash theme={null}
        corepack enable
        corepack prepare pnpm@latest --activate
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Linux">
    <Steps>
      <Step title="Install Node.js">
        Follow [NodeSource distributions](https://github.com/nodesource/distributions?tab=readme-ov-file#table-of-contents)
      </Step>

      <Step title="Install Git">
        Follow [Git installation guide](https://git-scm.com/downloads/linux)
      </Step>

      <Step title="Install pnpm">
        ```bash theme={null}
        corepack enable
        corepack prepare pnpm@latest --activate
        ```
      </Step>

      <Step title="Desktop Development Dependencies (Optional)">
        For developing the desktop version:

        ```bash theme={null}
        sudo apt install \
          libssl-dev \
          libglib2.0-dev \
          libgtk-3-dev \
          libjavascriptcoregtk-4.1-dev \
          libwebkit2gtk-4.1-dev
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

### Optional: Install @antfu/ni

For a simpler development experience:

```bash theme={null}
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

<Steps>
  <Step title="Fork the Repository">
    Click the **Fork** button on the [moeru-ai/airi](https://github.com/moeru-ai/airi) repository page.
  </Step>

  <Step title="Clone Your Fork">
    ```bash theme={null}
    git clone https://github.com/<your-github-username>/airi.git
    cd airi
    ```
  </Step>

  <Step title="Add Upstream Remote">
    ```bash theme={null}
    git remote add upstream https://github.com/moeru-ai/airi.git
    ```
  </Step>
</Steps>

### Install Dependencies

```bash theme={null}
corepack enable
pnpm install

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

### Create a Working Branch

```bash theme={null}
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
```

<Info>
  Branch naming convention: `<username>/<type>/<description>`

  Types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`
</Info>

## Development Workflow

### Choose Your Application

<Tabs>
  <Tab title="Stage Web">
    Browser version for [airi.moeru.ai](https://airi.moeru.ai)

    ```bash theme={null}
    pnpm dev
    # or with ni:
    nr dev
    ```

    Opens at: [http://localhost:5173](http://localhost:5173)
  </Tab>

  <Tab title="Stage Tamagotchi">
    Desktop version (Electron)

    ```bash theme={null}
    pnpm dev:tamagotchi
    # or with ni:
    nr dev:tamagotchi
    ```

    Launches Electron app
  </Tab>

  <Tab title="Stage Pocket">
    Mobile version (Capacitor)

    ```bash theme={null}
    # Start dev server
    pnpm dev:pocket

    # Note your IP address from output
    # Then in another terminal:
    CAPACITOR_DEV_SERVER_URL=https://<your-ip>:5273 pnpm open:ios
    ```
  </Tab>

  <Tab title="Documentation">
    Documentation site

    ```bash theme={null}
    pnpm dev:docs
    # or with ni:
    nr dev:docs
    ```

    Opens at: [http://localhost:3000](http://localhost:3000)
  </Tab>
</Tabs>

### Monorepo Commands

#### Workspace Filters

Use pnpm filters to scope commands to specific packages:

```bash theme={null}
# 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

<AccordionGroup>
  <Accordion title="Development">
    ```bash theme={null}
    # 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
    ```
  </Accordion>

  <Accordion title="Build">
    ```bash theme={null}
    # 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
    ```
  </Accordion>

  <Accordion title="Type Checking">
    ```bash theme={null}
    # 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
    ```
  </Accordion>

  <Accordion title="Linting">
    ```bash theme={null}
    # Lint all files
    pnpm lint

    # Lint and fix
    pnpm lint:fix

    # Lint Rust code
    pnpm lint:rust

    # Lint Swift code (mobile)
    pnpm lint:swift
    ```
  </Accordion>

  <Accordion title="Testing">
    ```bash theme={null}
    # 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
    ```
  </Accordion>
</AccordionGroup>

### Development Services

<Tabs>
  <Tab title="Discord Bot">
    ```bash theme={null}
    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
    ```
  </Tab>

  <Tab title="Telegram Bot">
    ```bash theme={null}
    cd services/telegram-bot

    # Start PostgreSQL
    docker compose up -d

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

    # Migrate database
    pnpm -F @proj-airi/telegram-bot db:generate
    pnpm -F @proj-airi/telegram-bot db:push

    # Run the bot
    pnpm -F @proj-airi/telegram-bot start
    ```
  </Tab>

  <Tab title="Minecraft Agent">
    ```bash theme={null}
    cd services/minecraft

    # Configure environment
    cp .env .env.local
    # Edit .env.local with Minecraft server details

    # Run the agent
    pnpm -F @proj-airi/minecraft-bot start
    ```
  </Tab>
</Tabs>

## Code Style and Conventions

### TypeScript

<Tabs>
  <Tab title="File Naming">
    Use **kebab-case** for all files:

    ```
    ✅ my-component.vue
    ✅ user-store.ts
    ✅ fetch-data.ts

    ❌ MyComponent.vue
    ❌ UserStore.ts
    ❌ fetchData.ts
    ```
  </Tab>

  <Tab title="Functions">
    Prefer functional patterns over classes:

    ```typescript theme={null}
    // ✅ Good: Functional
    export function calculateDistance(a: Point, b: Point): number {
      return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2)
    }

    // ❌ Bad: Class (unless extending browser APIs)
    export class DistanceCalculator {
      calculate(a: Point, b: Point): number {
        return Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2)
      }
    }
    ```
  </Tab>

  <Tab title="Imports">
    Organize imports logically:

    ```typescript theme={null}
    // External dependencies
    import { ref, computed } from 'vue'
    import { useRoute } from 'vue-router'

    // Internal dependencies
    import { useCharacter } from '@proj-airi/stage-ui'
    import { Client } from '@proj-airi/server-sdk'

    // Local imports
    import { formatDate } from './utils'
    import type { User } from './types'
    ```
  </Tab>
</Tabs>

### Vue Components

```vue theme={null}
<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

<Tabs>
  <Tab title="Documentation">
    Add clear comments for complex logic:

    ```typescript theme={null}
    /**
     * 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
    }
    ```
  </Tab>

  <Tab title="Markers">
    Use standard markers:

    ```typescript theme={null}
    // TODO: Implement caching for better performance

    // REVIEW: This might cause memory leaks

    // NOTICE: Workaround for Electron IPC limitation
    // See: https://github.com/electron/electron/issues/12345
    ```
  </Tab>

  <Tab title="Workarounds">
    Document workarounds with context:

    ```typescript theme={null}
    // NOTICE: Using setTimeout instead of requestIdleCallback
    // because Safari doesn't support requestIdleCallback as of 2026
    // Root cause: WebKit bug #123456
    // Reference: https://bugs.webkit.org/show_bug.cgi?id=123456
    setTimeout(doWork, 0)
    ```
  </Tab>
</Tabs>

## Commit Guidelines

### Before Committing

<Warning>
  Always run lint and typecheck before committing!
</Warning>

```bash theme={null}
# Lint and fix issues
pnpm lint:fix

# Type check
pnpm typecheck

# Run tests
pnpm test:run
```

### Image Optimization

If committing images, convert to AVIF:

```bash theme={null}
pnpm to-avif <PATH_TO_IMAGE_OR_DIRECTORY>

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

### Commit Messages

Use [Conventional Commits](https://www.conventionalcommits.org/):

```bash theme={null}
# 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)

```bash theme={null}
✨ feat(stage-ui): add weather widget component
🐛 fix(server-runtime): resolve memory leak
📝 docs: update plugin development guide
```

### Making the Commit

```bash theme={null}
# 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

<Steps>
  <Step title="Push Your Branch">
    ```bash theme={null}
    git push origin <your-branch-name> -u
    ```
  </Step>

  <Step title="Open Pull Request">
    1. Navigate to [moeru-ai/airi](https://github.com/moeru-ai/airi)
    2. Click **Pull requests** tab
    3. Click **New pull request**
    4. Click **Compare across forks**
    5. Select your fork and branch
  </Step>

  <Step title="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)
  </Step>

  <Step title="Wait for Review">
    Maintainers will review your PR and may request changes.
  </Step>
</Steps>

### 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

```bash theme={null}
# 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

<CardGroup cols={2}>
  <Card title="Module Boundaries" icon="box">
    Keep clear module boundaries. Shared logic goes in `packages/`, app-specific code stays in `apps/`.
  </Card>

  <Card title="DI Pattern" icon="plug">
    Use dependency injection (`injeca`) for better testability and modularity.
  </Card>

  <Card title="Type Safety" icon="shield-check">
    Use TypeScript strictly. Avoid `any` type unless absolutely necessary.
  </Card>

  <Card title="Progressive Refactoring" icon="arrows-rotate">
    Improve code you touch. Small refactors are better than big rewrites.
  </Card>
</CardGroup>

### When to Refactor

<Tabs>
  <Tab title="Do Refactor">
    * When touching legacy code
    * To improve readability
    * To remove duplication
    * To fix code smells
    * Alongside feature work
  </Tab>

  <Tab title="Don't Refactor">
    * Just because you prefer a different style
    * Without tests to verify behavior
    * As a separate, large-scale effort (discuss first)
    * Code that works and isn't being maintained
  </Tab>
</Tabs>

## 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

```bash theme={null}
# 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

<CardGroup cols={2}>
  <Card title="Discord" icon="discord" href="https://discord.gg/TgQ3Cu2F7A">
    Join our Discord server for real-time chat
  </Card>

  <Card title="GitHub Discussions" icon="comments" href="https://github.com/moeru-ai/airi/discussions">
    Ask questions and share ideas
  </Card>

  <Card title="GitHub Issues" icon="circle-exclamation" href="https://github.com/moeru-ai/airi/issues">
    Report bugs and request features
  </Card>

  <Card title="Twitter/X" icon="twitter" href="https://x.com/proj_airi">
    Follow for project updates
  </Card>
</CardGroup>

### 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

<AccordionGroup>
  <Accordion title="I'm stuck on setup">
    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
  </Accordion>

  <Accordion title="My PR was rejected">
    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
  </Accordion>

  <Accordion title="How do I find something to work on?">
    1. Check [Good First Issues](https://github.com/moeru-ai/airi/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
    2. Look for issues labeled `help wanted`
    3. Ask in Discord what needs help
    4. Improve documentation (always needed!)
    5. Fix bugs you encounter
  </Accordion>

  <Accordion title="Can I contribute without coding?">
    Absolutely! We need:

    * **Documentation writers**: Improve guides and tutorials
    * **Translators**: Help with i18n on [Crowdin](https://crowdin.com/project/proj-airi)
    * **Designers**: UI/UX improvements, Live2D models, VRM models
    * **Testers**: Report bugs, test PRs
    * **Community helpers**: Answer questions, help newcomers
    * **Artists**: Create promotional materials, screenshots
  </Accordion>
</AccordionGroup>

## Non-Code Contributions

### Translations

We use [Crowdin](https://crowdin.com/project/proj-airi) 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/`:

```bash theme={null}
# 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

<CardGroup cols={2}>
  <Card title="Architecture Guide" icon="sitemap" href="/development/architecture">
    Understand the codebase structure
  </Card>

  <Card title="Plugin Development" icon="puzzle-piece" href="/development/plugins">
    Learn to build plugins
  </Card>

  <Card title="AGENTS.md" icon="file-code" href="https://github.com/moeru-ai/airi/blob/main/AGENTS.md">
    Agent development guide
  </Card>

  <Card title="Discord Community" icon="discord" href="https://discord.gg/TgQ3Cu2F7A">
    Join the community
  </Card>
</CardGroup>

## Congratulations!

You're now ready to contribute to Project AIRI! Remember:

* Start small
* Ask questions
* Learn from feedback
* Help others
* Have fun!

<Info>
  **Thank you for contributing to Project AIRI!** Every contribution, no matter how small, helps make AIRI better for everyone.
</Info>
