# i18n Contributing Guide

This project uses ICU MessageFormat via `@formatjs/intl` with a custom Svelte 5 store.

## Adding a New Language

1. Create `locales/<tag>.json` (e.g. `locales/de.json`) with all keys from `locales/en.json`.
2. Register the locale in `src/mainview/i18n.svelte.ts`:
   - Add an entry to `AVAILABLE_LOCALES` with tag, label, nativeLabel, and dir.
   - Add a dynamic import entry to the `loaders` map.
3. The language will automatically appear in Settings > Appearance > Language.

## Key Naming Convention

Use dot-notation: `component.element.state`

```
sidebar.settings        -- component.element
agent.status.running    -- component.element.state
settings.appearance     -- component.element
common.cancel           -- shared across components
errors.connectionFailed -- error messages
```

Group prefixes:
- `sidebar.*` -- left sidebar
- `agent.*` -- agent pane
- `terminal.*` -- terminal tabs
- `settings.*` -- settings drawer
- `statusbar.*` -- bottom status bar
- `notifications.*` -- notification drawer
- `files.*` -- file browser
- `search.*` -- search overlay
- `comms.*` -- communications tab
- `tasks.*` -- task board
- `errors.*` -- error messages
- `splash.*` -- splash screen
- `common.*` -- shared labels (cancel, save, delete)
- `project.*` -- project management
- `palette.*` -- command palette

## ICU MessageFormat Syntax

### Plain text
```json
"common.save": "Save"
```

### Plurals (English: one/other)
```json
"search.resultsCount": "{count, plural, one {{count} result} other {{count} results}}"
```

### Plurals (Polish: one/few/many/other)
```json
"search.resultsCount": "{count, plural, one {{count} wynik} few {{count} wyniki} many {{count} wynikow} other {{count} wynikow}}"
```

### Plurals (Arabic: zero/one/two/few/many/other)
```json
"tasks.taskCount": "{count, plural, =0 {no tasks} one {one task} two {two tasks} few {{count} tasks} many {{count} tasks} other {{count} tasks}}"
```

### Interpolation
```json
"errors.unhandled": "Unhandled error: {message}"
```

### Select
```json
"agent.status": "{status, select, running {Running} idle {Idle} other {Unknown}}"
```

## Using Translations in Components

```svelte
<script lang="ts">
  import { t } from './i18n.svelte.ts';
</script>

<button>{t('common.save')}</button>
<span>{t('sidebar.notifCount', { count: 5 })}</span>
```

## Testing Translations

1. Switch language in Settings > Appearance > Language.
2. All `t()` calls update reactively -- no page reload needed.
3. Missing keys fall back to the key name itself (e.g. `"agent.status.running"`).
4. Check the browser console for `[i18n]` warnings about missing or malformed messages.

## Regenerating Types

After adding or removing keys in `locales/en.json`:

```bash
bun scripts/i18n-types.ts
```

This regenerates `src/mainview/i18n.types.ts` with the updated `TranslationKey` union type. TypeScript will then flag any `t()` calls using keys that no longer exist.

## RTL Support

Arabic (`ar`) sets `document.dir = 'rtl'` automatically. CSS should use logical properties (`inline-start`/`inline-end`) instead of `left`/`right` where possible.
