# AGENTS.md This file provides guidance to AI coding agents when working with code in this repository. ## Project Overview Kanbn4Droid is an unofficial app to connect to and manipulate data stored in self-hosted Kan.bn repositories. The app allows the user to authenticate with a Kan.bn server, display a list of available boards, open boards to edit lists and move cards around, and to create and edit cards. The app is written in Kotlin using mostly standard Android libraries and components and is designed to be compiled and edited through the command line, without Android Studio. ## Dependencies - AndroidX Preferences library. - AndroidX SplashScreen library. - Kotlin coroutines (Android dispatcher). ## Current bootstrap status - Build system: Gradle Kotlin DSL with version catalog (`gradle/libs.versions.toml`). - Wrapper: Gradle 8.11.1. - Android plugin and language: AGP 8.9.2, Kotlin 2.1.20, Java 17 target. - Module layout: single Android app module at `app/`. - Namespace and application id: `space.hackenslacker.kanbn4droid.app`. - Minimum SDK: API 29. - Compile/target SDK: API 35. - Baseline tests: - JVM unit tests for auth URL normalization and auth error mapping in `app/src/test/`. - JVM unit tests for boards repository and boards view model in `app/src/test/space/hackenslacker/kanbn4droid/app/boards/`. - Instrumentation tests for login and boards flows in `app/src/androidTest/`. ## Command-line workflow - List tasks: `./gradlew tasks` - Run unit tests: `./gradlew test` - Build debug APK: `./gradlew assembleDebug` - Install debug APK: `./gradlew installDebug` - Run instrumentation tests: `./gradlew connectedDebugAndroidTest` `installDebug` and `connectedDebugAndroidTest` require a connected device or emulator. ## Architecture **Splash screen** - The app displays a standard Android splash screen when open from a cold start. - Current status: implemented through `Theme.Kanbn4Droid.Splash` with a temporary placeholder image resource at `app/src/main/res/drawable/splash_placeholder.xml`. **Login view** - It's the first screen the user sees when opening the app if no login has been successfully stored so far. - The view has fields to request the user for an instance base URL (http or https, with or without port number) and an API key. - The default base URL is that of the standard Kan.bn instance at https://kan.bn/ - The view tries to check connection with the server at the given base URL using the Kan.bn API healthcheck endpoint. - The API key is stored in app preferences together with the base URL. - No migration is performed from prior Credential Manager storage, so users must re-enter their API key one time after upgrading. - On success, the view stores the URL and API key pair in preferences and moves over to the boards view. - On successful manual sign-in, the stored workspace id is cleared so the boards flow can resolve a fresh default workspace for the account. - If there is a URL and API Key pair stored, the view tries to authenticate the user through the API automatically and proceeds to the boards view instantly without showing the login screen if successful. - If startup authentication fails due to invalid credentials then the stored API key is invalidated; transient connectivity/server failures keep the stored key and return to login. - Current status: implemented in `MainActivity` with XML views and navigation into `BoardsActivity`. **Boards list view** - Displays a list of boards as rounded-square cards with the board's title centered in it. - Clicking on a board card moves on to that board's detail view. - The boards list is refreshed automatically when entering the view. - The boards list can be refreshed manually with a pull-down gesture on the list. - The view has a floating + button at the bottom right that shows a modal dialog for creating a new board. - The modal board creation dialog requests the user for a board name. - The modal board creation dialog has a toggleable pill button labeled "Use template". - Enabling the "Use template" button shows a list of available templates to use when creating the board. - The list of templates is obtained through the Kan.bn API. - The modal board creation dialog has two buttons at the bottom right for "Cancel" and "Create" respectively. - Board creation is done through the Kan.bn API. - On success creating a board moves on to that new board's detal view immediately. - On failure creating a board shows a modal dialog with the server's reported cause of failure and an OK button. - Long-pressing an existing board shows a modal dialog asking the user if they want to delete the board, with buttons for "Cancel" and "Delete". - Pressing "Delete" in the modal dialog MUST show a second confirmation modal asking if the user is sure, with buttons for "Cancel" and "I'm sure". - Only on pressing "I'm sure" in the second confirmation modal dialog should a board delete request be sent to the API. - Current status: implemented in `BoardsActivity` using XML Views, `RecyclerView`, `SwipeRefreshLayout`, and a `BoardsViewModel`/`BoardsRepository` flow. The screen includes auto-refresh on entry, pull-to-refresh, create board dialog with optional template selector, and two-step board delete confirmation. Board taps navigate to `BoardDetailActivity`. API calls are workspace-scoped; when no workspace is stored the app resolves workspaces through the API, stores the first workspace id as default, and uses it for board listing, template listing (`type=template`), and board creation. **Board detail view** - The board detail view shows the lists in the board as vertical lists. - Each list has it's title at the top. - Clicking on the title of a list allows editing the title. - Below the title each card is shown in a vertically scrolling list of rounded-square shaped cards with one entry for each card in the list. - Each card contains it's title in bold font at the top, a list of the card's tags and it's due date if available, in that order. - The tag list of a card is a series of pill-shaped labels with the tag's name on them and a colored border with the color of the tag. - The due date of the card is shown in black (or light in dark mode) text if it's still valid, or in red text if it's expired. - The due date MUST be formatted in the system's locale. - Swiping right or left on a list allows the user to change to the next or previous list in the board respectively if any. - On reaching the first or last list in the board it's no longer possible to keep swiping in that direction. - Long-pressing a card in a list allows selecting that card. - Tapping other cards in the same or other lists selects them as well. - Tapping an already selected card deselects it. - When one or more cards are selected, the top bar of the application MUST display the following buttons using the indicated icon for each one, without text: "Select all" (a 4x4 square grid), "Move cards" (a double-ended left-right arrow), "Delete cards" (a trash can). - Tapping the "Select all" button selects all cards in the list that is being shown to the user, NOT all cards in all available lists. - Tapping the "Move cards" button shows a modal dialog that asks the user to what list does he want to move the cards. - This modal dialog shows a selector with all the lists available in the current board. - This modal dialog has two buttons at the bottom for "Cancel" and "Move" - Tapping the "Delete cards" button asks the user for confirmation to delete the cards. This confirmation dialog has two buttons at the bottom for "Cancel" and "Delete". - Pressing "Delete" in the modal dialog MUST show a second confirmation modal asking if the user is sure, with buttons for "Cancel" and "I'm sure". - Only on pressing "I'm sure" in the second confirmation modal dialog should a board delete request be sent to the API. - Long-pressing any of the buttons must show a tooltip with the button name. - The view has a floating + button that allows choosing between two options: "Add new list", "Add new card" - The Add new list option shows a modal dialog that asks for a list title. The modal dialog has two buttons at the bottom for "Cancel" and "Create" - The list is created using the Kan.bn API. - The new list is added at the end of the lists in the current board after the current last list. - The Add new card option shows a modal dialog for creating a new card using the Kan.bn API. - The new card is added to the top of the currently shown list. - The modal dialog has a field for the card's name. This field is mandatory - Below the card name field there is a markdown-enabled text area for an optional card description. - Below the card description field there is an optional date field to set the card's due date. - Below the card's due date field there is an optional multi-value selector that allows choosing the card's tags from the tags available for the current board. - The title bar of the view has two icon-only buttons for "Filter by tag" (icon is three bars of decreasing width, widest on top) and "Search" (icon is a leaning looking glass) - The filter by tag button opens a modal dialog that shows a multi-value selector that allows choosing from the tags available on the current board. The modal has a title that says "Filter by tag". The modal has buttons for "Cancel" and "Filter". - The search button a modal dialog that shows a text field that has the placeholder value "Search". The modal has a title that seas "Search by title". The modal has buttons for "Cancel" and "Search". - Applying a filter or search makes the active board show only the cards that match the given criteria (selected tags or matching title). - The filters are applied locally without contacting the server. - The search by title filter matches any part of the title. Example: searching for "Duke" matches "Duke Nukem" as well as "Nukem Duke" - When a filter by tag or search is applied the corresponding button in the title bar gets highlighted. - Tapping on the filter by tag or search buttonswhen either of them is applied disables the active filter. - When a card(s) is selected by a long press, the filter by tag and search buttons get hidden by the select all, move card and delete card buttons until all cards are deselected. - When a card(s) is selected by a long press, the back arrow in the title bar and the back system button remove all selections. - Current status: implemented in `BoardDetailActivity` with `ViewPager2` (one list per page), inline list-title edit, and card rendering (title/tags/due date locale formatting and expiry color). - FAB flows are implemented for both add-list and add-card dialogs. - Filter/search behavior is local (no server roundtrip), and active filter/search icons are highlighted. - Cross-page card selection is implemented. In selection mode, toolbar actions are replaced (filter/search hidden; select-all/move/delete shown). - Select-all is page-scoped, move uses a list selector dialog, and delete uses two-step confirmation. - Back handling clears selection from both the top-bar back arrow and the system back button before navigation. - The screen includes mutation guards while in progress and API-backed reload/reconciliation behavior through `BoardDetailViewModel` and `BoardDetailRepository`. - Card move requests try these variants for Kan.bn API compatibility: `PUT /api/v1/cards/{cardPublicId}` with `listPublicId`, then GET+full-body `PUT /api/v1/cards/{cardPublicId}` payload (`title`, `description`, `index`, `listPublicId`, `dueDate`), then `PUT /api/v1/cards/{cardPublicId}` with `listId`, then `PATCH /api/v1/cards/{cardPublicId}` with `listId`. - Board detail parsing prefers public ids (`publicId`/`public_id`) over internal `id` values so follow-up card/list mutations target correct API identifiers. - Label chip border colors are hydrated from Kan.bn `Get a label by public ID` (`colourCode`) and cached in-memory by `BoardDetailRepository` so each label color is fetched only once per app process. - Selection action icons use local vector drawables (`ic_select_all_grid_24`, `ic_move_cards_horizontal_24`, `ic_delete_24`) with day/night variants so dark mode uses light icon fills automatically. - Startup blocking dialogs are shown for missing board id and missing session. **Card detail view** - The view shows the card's title in bold letters. Tapping on the card's title allows editing it. - Below the title a horizontally scrollable there is a list of the card's tags, shown as pills with the border color set to the tag's color obtained from the Kan.bn API. - Below the tags there is a date field showing the card's due date, if any, or the option to set a due date. - If the due date is set and is still valid then it is shown in black (or light in dark mode) text. - If the due date is set and is expired, then it is shown in red text. - Below the due date the view shows the card's description if any in a markdown-enabled, editable text field. - Below the description the app shows the lastest 10 elements of the card's edit history (named card activities in the Kan.bn documentation) obtained from the Kan.bn API, in least to most recent order. - The view has a floating + button that shows a modal dialog that allows adding a comment to the card's history using the Kan.bn API. - The modal dialog has "Add comment" as a title. - The modal dialog has an editable markdown-enabled text field for the comment. - The modal dialog has two buttons at the bottom on the right side for "Cancel" and "Add" respectively. - Current status: full card detail is still pending. Tapping a board-detail card currently navigates to `CardDetailPlaceholderActivity` with card id/title extras. **Settings view** - The view shows a list of settings that can be changed by the user. The following settings are available: - Theme (selector with three choices: Light, Dark, Follow System) - Base URL (editable text field) - API Key (editable password text field with obfuscated characters) - Logout (single button that shows a modal dialog asking the user if it's OK to sign out) - All settings are managed using the AndroidX Preferences library. - Signing out clears the stored API key and app cache and returns the user to the login screen. ## Considerations - All views support light or dark theme following the system's indicated preference by default. - The app's default accent color is obtained from the system's theme. - The app's design follows Material You guidelines. - Every new feature MUST include a full set of tests, using the standard Android SDK testing framework. - The minimum supported Android version is Android 10 (API level 29) - It is preferable to use standard Android libraries and tools whenever possible. - If a task would be better served by or can only be done with external libraries then it is allowed to use them but you MUST ask the user for permission to add the library to the project first. - The documentation for the Kan.bn API is available here https://docs.kan.bn/api-reference/introduction - Never push code unless explicitely prompted to do so. - After every run, update this file as needed to reflect the changes made.