Files
Kanbn4droid/AGENTS.md
2026-03-18 14:54:16 -04:00

6.5 KiB

AGENTS.md

This file is for agentic coding assistants working in this repository. It captures build/test commands and code conventions observed in the codebase.

Project Snapshot

  • Name: Kanbn4Droid
  • Platform: Android app (Kotlin, XML views, coroutines)
  • Build system: Gradle Kotlin DSL (*.gradle.kts)
  • Module layout: single app module :app
  • Namespace/application id: space.hackenslacker.kanbn4droid.app
  • Compile/target SDK: 35
  • Min SDK: 29
  • Java/Kotlin target: 17

Environment Prerequisites

  • Java 17 installed and available on PATH
  • Android SDK command-line tools installed
  • Android SDK packages:
    • platforms;android-35
    • build-tools;35.0.0
    • platform-tools
  • If SDK is not auto-detected, copy local.properties.example to local.properties and set sdk.dir

Source of Truth for Commands

  • Prefer Gradle wrapper (./gradlew) over system Gradle
  • Most Android tasks should be run with explicit module prefix when possible (:app:<task>)
  • Discover tasks with: ./gradlew tasks --all

Build / Lint / Test Commands

Core Daily Commands

  • List tasks: ./gradlew tasks --all
  • Clean: ./gradlew clean
  • Build everything in app module: ./gradlew :app:build
  • Build debug APK: ./gradlew :app:assembleDebug
  • Install debug APK on connected device/emulator: ./gradlew :app:installDebug

Lint

  • Run default lint: ./gradlew :app:lint
  • Run debug lint explicitly: ./gradlew :app:lintDebug
  • Run release lint explicitly: ./gradlew :app:lintRelease
  • Auto-fix safe lint issues: ./gradlew :app:lintFix

Unit Tests (JVM)

  • Run all unit tests (all variants): ./gradlew :app:test
  • Run debug unit tests: ./gradlew :app:testDebugUnitTest
  • Run release unit tests: ./gradlew :app:testReleaseUnitTest

Run a Single Unit Test (important)

  • Single test class:
    • ./gradlew :app:testDebugUnitTest --tests "space.hackenslacker.kanbn4droid.app.boards.BoardsViewModelTest"
  • Single test method:
    • ./gradlew :app:testDebugUnitTest --tests "space.hackenslacker.kanbn4droid.app.boards.BoardsViewModelTest.createBoardSuccessEmitsNavigateEvent"
  • Pattern match within class/package:
    • ./gradlew :app:testDebugUnitTest --tests "space.hackenslacker.kanbn4droid.app.boarddetail.*"

Instrumentation Tests (device/emulator required)

  • Run all connected debug instrumentation tests:
    • ./gradlew :app:connectedDebugAndroidTest
  • Equivalent aggregate task:
    • ./gradlew :app:connectedAndroidTest

Run a Single Instrumentation Test (important)

  • Single instrumentation test class:
    • ./gradlew :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=space.hackenslacker.kanbn4droid.app.BoardsFlowTest
  • Single instrumentation test method:
    • ./gradlew :app:connectedDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=space.hackenslacker.kanbn4droid.app.BoardsFlowTest#pullToRefreshWorks

Repository-Local Rules (Cursor/Copilot)

  • Checked for Cursor rules in .cursor/rules/ and .cursorrules: none found
  • Checked for Copilot instructions in .github/copilot-instructions.md: none found
  • Therefore, no additional repo-local AI instruction files are currently enforced beyond this document
  • If those files are added later, treat them as higher-priority guidance and update this AGENTS.md

Architecture and Code Organization

  • UI is Activity-driven (not Compose)
  • Feature folders under app/src/main/java/space/hackenslacker/kanbn4droid/app/: auth/, boards/, boarddetail/, carddetail/
  • Typical layering:
    • Activity handles view binding and user interaction wiring
    • ViewModel holds UI state and events (StateFlow + SharedFlow)
    • Repository/data source handles session and API calls
    • API client encapsulates HTTP + response parsing

Kotlin Style Guidelines (observed conventions)

Formatting

  • Follow Kotlin official code style (gradle.properties: kotlin.code.style=official)
  • Use 4-space indentation
  • Use trailing commas in multiline argument lists/constructors where already used
  • Keep functions focused; prefer extraction for repeated logic
  • Avoid unnecessary comments; use clear naming instead

Imports

  • Do not use wildcard imports
  • Keep imports grouped (platform/library/project), matching existing file style
  • Remove unused imports
  • Prefer explicit imports for readability in large files

Types and API design

  • Prefer immutable val; use var only when mutation is required
  • Use data classes for immutable UI/domain models
  • Use sealed interfaces/classes for event/result hierarchies (BoardsUiEvent, mutation results)
  • Keep nullability explicit; avoid nullable types unless required by API/domain
  • Return domain/result wrappers instead of throwing for expected failures

Naming

  • Packages: lowercase, dot-separated (space.hackenslacker...)
  • Classes/interfaces/objects: PascalCase
  • Functions/properties/locals: camelCase
  • Constants: UPPER_SNAKE_CASE (private const val ...)
  • Test method names: descriptive camelCase phrases that state behavior

Coroutines and threading

  • Use viewModelScope.launch for ViewModel async work
  • Use withContext(Dispatchers.IO) or injected IO dispatcher for blocking/network work
  • Keep dispatcher injection points testable (repositories already do this)
  • Avoid blocking calls on main thread

State and events

  • Model screen state as immutable data class in ViewModel
  • Update state via copy semantics (state.copy(...)), often with MutableStateFlow.update
  • Use one-off events via SharedFlow rather than state flags for navigation/toasts/dialog alerts
  • Keep rendering deterministic from current state

Error handling

  • Prefer explicit result types (BoardsApiResult, AuthResult) over exceptions for normal failure paths
  • Surface user-visible messages through UI events/state
  • Validate user input early (blank checks, URL normalization) before network calls

Android/UI conventions

  • Keep user-facing text in res/values/strings.xml when practical
  • Use Material components already present in the project
  • Keep Activity responsibilities focused on binding and orchestration, not business logic
  • Respect existing navigation via explicit intents and extras constants

Testing Conventions

  • Unit tests live in app/src/test/... and use JUnit4 + coroutines test utilities
  • Instrumentation tests live in app/src/androidTest/... and use Espresso/Intents
  • Prefer fakes/in-memory stores for API/session dependencies in tests
  • In coroutine tests:
    • set/reset main dispatcher in @Before/@After
    • use runTest and advanceUntilIdle()
  • Keep tests behavior-focused (arrange -> act -> assert)