Skip to content

Developer Guide

thejaustin edited this page Dec 25, 2025 · 1 revision

Developer Guide

Complete guide for contributing to AutoCat development.

πŸš€ Getting Started

Prerequisites

  • Git with submodule support
  • Android Studio (latest stable version)
  • Java 21 JDK
  • GitHub account
  • GitHub CLI (gh) for releases (optional)

Clone Repository

git clone --recursive https://github.com/thejaustin/AutoCat.git
cd AutoCat

If you forget --recursive, initialize submodules:

git submodule update --init --recursive

Open in Android Studio

  1. Open Android Studio
  2. File β†’ Open β†’ Select AutoCat directory
  3. Select build variant: lawnWithQuickstepGithubDebug
  4. Wait for Gradle sync

Fix Submodule Errors

If you see errors with iconloaderlib or searchuilib:

git submodule update --init --recursive

🚨 CRITICAL: Build Policy

NEVER BUILD LOCALLY

ALL builds are handled exclusively by GitHub Actions.

Why?

Building Android apps on Termux/mobile devices is:

  • Resource-Intensive: Requires 6GB+ RAM, takes 30+ minutes, drains battery
  • Unreliable: Frequent OOM crashes, Gradle daemon crashes, corrupted artifacts
  • Unnecessary: GitHub Actions provides free, consistent, reproducible builds

How to Get a Build

Step 1: Make Your Changes

# Edit code as needed
# Run code formatting (this is safe)
./gradlew spotlessApply

Step 2: Commit and Push

git add .
git commit -m "feat: your changes"
git push

Step 3: Let GitHub Actions Build

  • GitHub Actions will automatically build on push
  • View progress: gh run list or check GitHub website
  • Build takes ~10-15 minutes on GitHub servers

Step 4: Download the APK

# Download from latest release
gh release download dev-latest

# Or from GitHub web interface
# https://github.com/thejaustin/AutoCat/releases/tag/dev-latest

Safe Commands (Run Locally)

βœ… Safe to run:

# Code formatting
./gradlew spotlessApply
./gradlew spotlessCheck

# Gradle info
./gradlew tasks
./gradlew help
./gradlew projects

# Git operations
git status
git add .
git commit -m "message"
git push

# GitHub CLI
gh run list
gh run watch
gh release list
gh release download

Forbidden Commands (NEVER Run)

❌ NEVER run these:

./gradlew build               # ❌ WILL FAIL
./gradlew assembleDebug       # ❌ WILL FAIL
./gradlew assembleRelease     # ❌ WILL FAIL
./gradlew installDebug        # ❌ WILL FAIL
./gradlew bundleDebug         # ❌ WILL FAIL
./gradlew clean build         # ❌ WILL FAIL

πŸ“ Development Workflow

Tiered Workflow

We use a tiered workflow to balance development speed with stability. All PRs target the 15-dev branch.

Tier Definition Examples Protocol
Trivial changes Zero risk of functional regression Fixing typos, simple code style fixes Commit directly to 15-dev
Simple, self-contained work Functionally isolated, very low risk Single-file bug fixes, minor UX polish 1. Create PR
2. Assign reviewer
3. Enable Auto-merge
Medium complexity features Multiple components, not deeply architectural New settings screen, new search provider 1. Create detailed PR
2. Assign core team
Major architectural changes High-risk, complex changes Android version rebase 1. Very detailed PR
2. Mandatory Review before merge

Commit Message Convention

We follow Conventional Commits:

Format: type(scope): subject

Example: feat(settings): Add toggle for new feature

Allowed Types:

  • feat - New feature
  • fix - Bug fix
  • style - Code style changes (formatting)
  • refactor - Code refactoring
  • perf - Performance improvements
  • docs - Documentation changes
  • test - Test additions/changes
  • chore - Build/tooling changes

AutoCat-Specific Convention:

All commits automatically include attribution footer:

πŸ€– Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

πŸ—οΈ Project Structure

Package Organization

lawnchair/
β”œβ”€β”€ src/app/lawnchair/          # AutoCat-specific code (ADD NEW FILES HERE)
β”‚   β”œβ”€β”€ categorization/         # Categorization system
β”‚   β”‚   β”œβ”€β”€ llm/                # LLM providers
β”‚   β”‚   β”œβ”€β”€ stages/             # Categorization pipeline
β”‚   β”‚   └── learning/           # User correction learning
β”‚   β”œβ”€β”€ data/tab/               # Database entities & DAOs
β”‚   β”œβ”€β”€ ui/preferences/         # Settings screens
β”‚   └── preferences/            # Preference definitions
β”‚
src/                            # Launcher3 codebase (MINIMIZE CHANGES)
└── com/android/launcher3/      # Upstream Launcher3 code

Rule: Always add new files to lawnchair/src/app/lawnchair/, not src/.

AutoCat-Specific Files

42 AutoCat Files across 5 packages:

app.lawnchair.categorization/ (19 files)
β”œβ”€β”€ AccuracyTracker.kt
β”œβ”€β”€ AdaptiveModelSelector.kt
β”œβ”€β”€ CategorizationManager.kt
β”œβ”€β”€ CategoryFolderSyncService.kt
β”œβ”€β”€ llm/
β”‚   β”œβ”€β”€ GoogleAIProvider.kt
β”‚   β”œβ”€β”€ ClaudeProvider.kt
β”‚   β”œβ”€β”€ OpenAIProvider.kt
β”‚   β”œβ”€β”€ PerplexityProvider.kt
β”‚   β”œβ”€β”€ LLMProvider.kt
β”‚   β”œβ”€β”€ ProviderCircuitBreaker.kt
β”‚   └── ConfidenceCalibrator.kt
└── stages/
    β”œβ”€β”€ BuiltInCategorizer.kt
    └── LLMCategorizer.kt

app.lawnchair.data.tab/ (7 files)
β”œβ”€β”€ TabDatabase.kt
β”œβ”€β”€ TabDao.kt
β”œβ”€β”€ AccuracyDao.kt
└── entities/
    β”œβ”€β”€ AppTab.kt
    β”œβ”€β”€ CustomTab.kt
    └── ModelAccuracy.kt

app.lawnchair.ui.preferences.destinations/ (8 files)
β”œβ”€β”€ AppCategorizationListPreferences.kt
β”œβ”€β”€ CategorizationSettingsPreferences.kt
β”œβ”€β”€ CategoryManagementPreferences.kt
└── LLMSettingsPreferences.kt

See AutoCat vs Upstream for complete file list.


πŸ’» Coding Guidelines

Kotlin Conventions

Follow Kotlin Coding Conventions:

  • Use camelCase for variables/functions
  • Use PascalCase for classes
  • 4 spaces for indentation
  • Max line length: 120 characters
  • Always use explicit types for public APIs

Code Formatting

Always run before committing:

./gradlew spotlessApply

Check formatting:

./gradlew spotlessCheck

String Naming

Strings in strings.xml follow this format:

Type Format Example
Generic word $1 disagree_or_agree
Action $1_action apply_action
Preference/popup label $1_label folders_label
Preference description $1_description folders_description
Preference choice $1_choice off_choice
Feature string (feature_name)_$1 colorpicker_hsb
Launcher string $1_launcher device_contacts_launcher

Database Migrations

When changing database schema:

  1. Increment version number in TabDatabase.kt
  2. Add migration logic (or use fallbackToDestructiveMigration() for dev)
  3. Test migration with existing data
  4. Document changes in commit message

Example:

@Database(
    entities = [AppTab::class, CustomTab::class, ModelAccuracy::class],
    version = 7,  // Increment this
    exportSchema = false,
)

πŸ§ͺ Testing

Manual Testing Checklist

When testing a feature:

  • Feature works as expected
  • No crashes or errors
  • Settings save and persist
  • Works after app restart
  • No performance degradation
  • UI looks correct on different screen sizes
  • Logs show expected output

Reporting Bugs

Use GitHub Issues template. Include:

  • Build info: Commit hash (e.g., AutoCat-debug-abc1234.apk)
  • Android version: From Settings β†’ About Phone
  • Device model: Manufacturer and model
  • Steps to reproduce: Exact steps
  • Expected vs actual: What should happen vs what happens
  • Logs: adb logcat | grep AutoCat

πŸ”€ Version Control

Branching Strategy

  • Main branch: 15-dev
  • Feature branches: feature/your-feature-name
  • Bug fixes: fix/issue-number-description

Creating a Pull Request

  1. Create branch:

    git checkout -b feature/new-feature
  2. Make changes and commit:

    git add .
    git commit -m "feat: Add new feature"
  3. Push to GitHub:

    git push origin feature/new-feature
  4. Create PR on GitHub:

    • Base branch: 15-dev
    • Include description of changes
    • Link related issues
    • Enable auto-merge (for simple PRs)
  5. Wait for CI:

    • GitHub Actions will build and test
    • Fix any errors
    • Get review approval
  6. Merge:

    • Auto-merge will merge when CI passes and reviewer approves
    • Or manually merge after review

🎨 UI Development

Material 3 Expressive Design

AutoCat uses Material 3 Expressive design system:

  • Typography: Material 3 type scale
  • Colors: Material 3 dynamic colors
  • Spacing: 8dp grid system
  • Components: Material 3 components

Preference Screens

Use existing preference components:

@Composable
fun MyPreferences() {
    PreferenceLayout(label = "My Settings") {
        PreferenceGroup(heading = "Section 1") {
            SwitchPreference(
                adapter = preferenceManager.mySetting.getAdapter(),
                label = "My Setting"
            )
        }
    }
}

See Preference Components README for details.


πŸ”§ Common Tasks

Adding a New LLM Provider

  1. Create provider class in app.lawnchair.categorization.llm/:

    class MyLLMProvider(context: Context) : LLMProvider {
        override suspend fun categorizeApp(...): CategorizationResult {
            // Implementation
        }
    }
  2. Add to provider registry in CategorizationManager.kt

  3. Add preferences in PreferenceManager.kt:

    val llmMyProviderKey = StringPref("pref_llmMyProviderKey", "", {})
    val llmMyProviderModel = StringPref("pref_llmMyProviderModel", "default-model", {})
  4. Add UI in LLMSettingsPreferences.kt

  5. Test with real API key

Adding a New Database Entity

  1. Create entity in app.lawnchair.data.tab.entities/:

    @Entity(tableName = "my_table")
    data class MyEntity(
        @PrimaryKey val id: Int,
        @ColumnInfo(name = "field") val field: String
    )
  2. Add to database in TabDatabase.kt:

    @Database(
        entities = [AppTab::class, CustomTab::class, MyEntity::class],
        version = 7,  // Increment
    )
  3. Create DAO in app.lawnchair.data.tab/:

    @Dao
    interface MyDao {
        @Query("SELECT * FROM my_table")
        suspend fun getAll(): List<MyEntity>
    }
  4. Add DAO to database:

    abstract fun myDao(): MyDao

πŸ“š Additional Resources

Documentation

Communication

Code of Conduct

Be civil and respectful. See Code of Conduct.


πŸ†˜ Getting Help

For Development Questions

  1. Check existing documentation
  2. Search closed issues on GitHub
  3. Ask in Telegram/Discord
  4. Open a discussion on GitHub

For Bug Reports

  1. Check if issue already reported
  2. Test with latest build
  3. Create issue with all required information
  4. Be patient and responsive to questions

Last Updated: 2025-12-25

Clone this wiki locally