# Contributing to PromptBar

Thanks for your interest in improving this library! Contributions of all kinds are welcome —
bug reports, feature requests, docs, and code.

## Project layout

```
prompt-bar/                       The published Kotlin Multiplatform library.
  src/commonMain/                  Public API + implementation.
    PromptBar.kt                   The main composable + SendStopButton.
    PromptBarState.kt              Headless state container.
    PromptBarModels.kt             Data classes — SlashCommand, Mention, PromptAttachment, etc.
    PromptBarDefaults.kt           Shape, padding, color defaults.
    AutocompleteDropdowns.kt       Slash + Mention panels.
    AttachmentChip.kt              One chip with preview + remove button.
    Tokenization.kt                Pure-logic helpers — trigger detection, replacement, paste-split.
  src/commonTest/                  Pure-logic tests — every helper + every state transition.
  src/skikoTest/                   Compose UI tests — run on Desktop and iOS test targets.
sample/composeApp/                 Shared fake-chat sample with all features wired.
sample/androidApp/                 Android launcher.
sample/desktopApp/                 Desktop (JVM) launcher.
sample/webApp/                     Web (wasmJs) launcher.
sample/iosApp/                     iOS launcher (Xcode project).
```

## Building & testing

```bash
./gradlew build                                  # build + test everything
./gradlew allTests                               # run tests on all targets
./gradlew :prompt-bar:desktopTest                # fastest feedback (commonTest + skikoTest)
./gradlew :prompt-bar:testDebugUnitTest          # Android unit tests
./gradlew :sample:desktopApp:run                 # run the desktop sample
```

The trigger-detection and paste-tokenization state machines are pure-logic — keep them that
way so behavior changes are covered without spinning up composition. UI tests verify wiring
(test tags, autocomplete panels, Send/Stop button) on top of the headless state.

## Design invariants — please preserve

- **Headless state.** `PromptBarState` is constructable + drivable without composition. Every
  new behaviour belongs there first; the composables should be thin wrappers.
- **Send-state derivation.** `sendState` is `Disabled` when blank-text + no-attachments, `Ready`
  otherwise. Overrides (`markSending` / `markStreaming`) are explicit signals from the host.
- **No platform reach-arounds in commonMain.** Voice transcription, file picking, clipboard
  access — all stay in the caller's `iosMain` / `androidMain`. PromptBar offers slots / callbacks.
- **Autocomplete openness rule.** `/` and `@` open the dropdown only at the start of a line or
  after whitespace. Don't widen this — `email@domain` must stay non-triggering.

## Conventions

- Public API gets KDoc.
- Add or update tests for every behaviour change.
- Update the sample app when you change a public API.
- Add a `CHANGELOG.md` entry under `## Unreleased`.

## Releasing

Releases are tag-driven: pushing a `v*` tag runs `.github/workflows/publish.yml`, which publishes
to Maven Central via the `com.vanniktech.maven.publish` plugin and creates a GitHub Release.
