## Summary
Recipes (skills) were in `localStorage` under `recipes/custom`, as one
list. `localStorage` holds a few megabytes, and each change wrote the
whole list. This PR moves the recipes to IndexedDB, one record for each
recipe.
The data model ADR lists `Recipe` as a Document entity. Each record has
the fields that a later sync needs: the recipe id, the time of addition,
the time of the last change, and a tombstone for a removal.
## Changes
- `recipes.repo.ts` keeps the recipes in the `airi-recipes` database.
The list keeps the order of addition.
- A removal leaves a tombstone. Deleting all data clears the database.
- After a change, the other windows read the recipes again through a
`BroadcastChannel`.
- The store moves the recipes from `recipes/custom` once, with their ids
and order. The ids stay, because sessions and runs refer to a recipe by
its id. The move has a `// NOTICE:` and a removal condition.
- Adding, proposing, editing, and removing a recipe are async. The
proposal tool and the Settings page wait for them. Reads stay
synchronous, from the recipes that the window read last.
- The `Proposals` switch is a setting, so it stays in `localStorage`.
- The store tests run in the browser project with real IndexedDB. Node
tests use an in-memory repo mock.
The ADR `docs/ai/adr/2026-10-10-skills-automations-and-memory.md`
describes the storage.
## Verification
- `pnpm -F @proj-airi/core-agent build`, then `pnpm -F
@proj-airi/stage-ui typecheck` and `pnpm -F @proj-airi/stage-pages
typecheck`: pass.
- The commit hook ran `moeru-lint --fix`.
- Tests did not run locally. CI runs them.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
Some Korean strings were wrong or out of date. This PR corrects 14
values in 3 files under `packages/i18n/src/locales/ko/`.
- `tamagotchi.stage.controls-island.login`: the Controls Island sign-in
button said 가입하기, which means "sign up". It now says 로그인, as the other
Korean sign-in strings do.
- `settings.pages.connection.*` and
`settings.websocket-secure-enabled.*`: 2770267dc rewrote 12 English
strings on the connection settings page. The Korean values kept the
older text. Eight of them were still English, for example "Connect from
Stage Pocket" for the current "Pairing". They now follow the current
English text.
- The glossary says the mobile edition reads as "Mobile ver." to end
users. The Korean text now says 모바일 버전 and does not use "Stage Pocket"
or "pocket".
- `stage.chat.sessions.new`: the new-conversation button said "+ New"
next to its own plus icon. It now says 새 대화.
This PR is independent. It changes only the `ko` locale. Other locales
still have the same older English in `pages.connection`, but Crowdin
owns them, so this PR does not touch them.
`tamagotchi.stage.about.links.github` keeps `Github`. `GitHub` equals
the English text, and deleting the key fails the locale check.
## Verification
```text
node .github/scripts/check-locales.ts --root packages/i18n/src/locales --base <upstream/main locales> --source-changes warning # passed
pnpm exec eslint packages/i18n/src/locales/ko/settings.yaml packages/i18n/src/locales/ko/stage.yaml packages/i18n/src/locales/ko/tamagotchi/stage.yaml # passed
```
- The pre-commit hook (`moeru-lint --fix`) passed.
- No ko value in the 3 files is equal to its English value.
## Visual changes
| Before | After |
| --- | --- |
|

|

|
| Main window / Controls Island menu, signed out, `ko` | Main window /
Controls Island menu, signed out, `ko` |
|

|

|
| Settings / Connection, `ko` | Settings / Connection, `ko` |
|

|

|
| Floating chat / Conversations drawer, `ko` | Floating chat /
Conversations drawer, `ko` |
How I took the captures:
- I built stage-tamagotchi with `pnpm -F @proj-airi/stage-tamagotchi
build` on Windows 11 and captured it with `vishot capture --target
electron`.
- Each run used a new empty profile (`APP_USER_DATA_PATH`) with
`settings/language` set to `ko` and onboarding marked as done.
- The "Before" build used the same commit with the 3 `ko` files restored
from the merge base (`71b3c178e`). The merge base and this branch differ
only in these files.
- The `qr.token-hint` and `qr.image-alt` values are not in the captures.
They show only when the Pairing panel is open, and that panel shows a
live pairing QR code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>