Commit Graph
781 Commits
Author SHA1 Message Date
Weathercold 69e7f7ee1f chore(nix): update pnpmDeps hash (#2341) 2026-08-23 02:30:06 +08:00
Neko Ayaka cf31b695d9 fix(deps): added required eslint-plugin-format 2026-08-23 00:40:14 +08:00
Neko b6d0809ecb perf(stage-ui): virtualize chat history (#2334) 2026-08-21 05:32:21 +08:00
leafyy 7756d921a7 fix(stage-ui): define deterministic chat math syntax (#2328) 2026-08-20 16:30:01 +08:00
RainbowBird d22daf6b4c feat(chat-ws): add versioned Eventa protocols (#2308)
Signed-off-by: RainbowBird <git@luoling.moe>
2026-08-20 12:24:47 +08:00
RainbowBird 0062070d7d fix(api): correct gateway and database pool alerts (#2324) 2026-08-19 08:30:55 +00:00
Neko 5e95e56d62 fix(stage-ui,stage-web,stage-tamagotchi): capture imported Live2D models in Polaroid (#2320) 2026-08-19 14:17:03 +08:00
Neko 2770267dc7 fix(stage-tamagotchi): sync pairing settings and QR state (#2318) 2026-08-18 19:55:15 +00:00
Neko Ayaka d2b837fa01 fix(stage-ui,stage-tamagotchi,stage-web): infinite write config causing forever loading 2026-08-19 01:07:30 +08:00
RainbowBird bd790098d2 fix(api): load Drizzle migrations at runtime (#2307) 2026-08-17 11:19:53 +00:00
Neko 73c05d37eb fix(stage-tamagotchi): prevent auxiliary renderer request storms (#2304) 2026-08-16 22:08:18 +08:00
RainbowBirdandautofix-ci[bot] ab5e43ae0c test(server): use ioredis-mock for Redis behavior (#2294)
## Summary

- Replace Redis command fakes with `ioredis-mock` in API tests.
- Run the production Lua scripts through `EVAL`.
- Keep Redis behavior tests on the same command and Pub/Sub
implementation used by production code.

## Stack

- This PR is the base for #2289.
- It replaces #2291 as the merge-to-`main` unit. #2291 merged into the
old
  ConfigKV branch before the stack could be reordered.

## Tests

- `pnpm install --frozen-lockfile --offline --ignore-scripts`
- `pnpm exec vitest run <6 changed API test files>` (73 tests passed)
- `pnpm exec eslint <7 changed API TypeScript files>`
- `git diff --check`

## Visual changes

None. This PR changes test infrastructure only.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Tests**
  * Added isolated in-memory Redis support for automated testing.
* Updated billing, Stripe, flux, concurrency, and user-deletion tests to
use a shared Redis test setup.
* Improved verification of Redis operations while preserving existing
test coverage and expected outcomes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: RainbowBird <rbxin2003@outlook.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-15 21:43:30 +08:00
Lovehsigure_520 497546e02f fix(auth-ui): hide sign-in form during provider handoff (#2282) 2026-08-14 11:04:57 +00:00
Neko Ayaka ebf34968e2 chore(deps): updated 2026-08-14 18:47:19 +08:00
Neko Ayaka e93a637058 chore(deps): updated 2026-08-14 18:40:02 +08:00
d4fe2bef59 fix(stage-tamagotchi): install desktop entry and appstream metainfo f… (#2245)
## Description

I understand that flatpak workflow already left my hand last year, and
this is not suitable for my ability and role at AIRI. However, I'd like
to ask if I have permissions to post my opinion to solve this:

- It may be better to manage sandbox permissions with smaller
boundaries.
- It is considerable to copy a desktop shortcut, and the metainfo to
properly trigger an app.

```
diff --git a/apps/stage-tamagotchi/ai.moeru.airi.flatpak.yml b/apps/stage-tamagotchi/ai.moeru.airi.flatpak.yml
index c8f9c33fd..311af5d74 100644
--- a/apps/stage-tamagotchi/ai.moeru.airi.flatpak.yml
+++ b/apps/stage-tamagotchi/ai.moeru.airi.flatpak.yml
@@ -22,7 +22,10 @@ finish-args:
   - --talk-name=org.freedesktop.portal.Desktop
   - --system-talk-name=org.freedesktop.login1
   - --system-talk-name=org.freedesktop.UPower
-  - --filesystem=home:rw
+  # Filesystem permissions
+  - --filesystem=xdg-download:rw
+  - --filesystem=xdg-config/airi:create
+  - --filesystem=~/.config/airi:create
 
 modules:
   - name: AIRI-App
@@ -34,6 +37,9 @@ modules:
       - install airi.sh /app/bin/airi.sh
       - chmod +x /app/bin/airi/airi.sh
       - chmod +x /app/bin/airi/airi
+      - install -Dm644 ai.moeru.airi.desktop /app/share/applications/ai.moeru.airi.desktop
+      - install -Dm644 ai.moeru.airi.metainfo.xml /app/share/metainfo/ai.moeru.airi.metainfo.xml
+      - install -Dm644 build/icons/icon.png /app/share/icons/hicolor/512x512/apps/ai.moeru.airi.png
     sources:
       - type: dir
         only-arches: [x86_64]
```

This block is an overview of this patch.

This bug was reported at Discord AIRI chatroom by Scarface.

```
OS: Bazzite DX 44.20260714.0
DE: KDE Plasma 6.7.2
Wayland

Hey. I wanted to give this a try but I'm facing some issues with the flatpak.

Unfortunately, I can't get it to run and it doesn't seem to even print out any logs whatsoever.

I tried running it from the terminal and noticed the following:

1) The flatpak runs
2) Processes are created
3) There is no output in the terminal even when using the verbose flag 
4) A blank taskbar icon appears that when clicked on creates a KDE toast pop up that says "No exec field in"

I went with the manual installation (git clone -> pnpm ...) and it works fine but if possible i'd like to keep using the Flatpak

Couldn't find anyone else with the same issue on Github or here. Any suggestions are appreciated.
```

## Linked Issues

Scarface mentioned that he `Couldn't find anyone else with the same
issue on Github or here. Any suggestions are appreciated.`

I could not find a same bug for this, too.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Liet Blue <127093491+lietblue@users.noreply.github.com>
Co-authored-by: Liet Blue <lietblue@posteo.net>
2026-08-13 14:39:05 +00:00
Neko Ayaka 0ef3a26f7d feat(testing-audio): now entire audio input/output pipeline can be tested 2026-08-13 22:12:24 +08:00
935347828c chore: update README release artifacts to v0.11.3 (#2277)
## Description

Updates stable desktop download links after the v0.11.3 release.

## Linked Issues

None.

## Additional Context

Generated by the post-release README workflow.

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-13 19:26:52 +08:00
RainbowBirdandautofix-ci[bot] 22b5249c64 refactor(server): split independent auth service (#2202)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-12 23:33:58 +08:00
Neko Ayaka a9906bf13b fix(deps): pin eventa to beta.13 2026-08-12 18:15:04 +08:00
Neko 1ca59ea5c5 fix(api-server): pin Eventa WebSocket protocol (#2259) 2026-08-12 00:04:41 +08:00
fd8b7a0ae3 feat(core-agent): bump xsai / remove patches (#2164)
## Summary

- Bump catalog `@xsai/*`, `@xsai-ext/providers`, and `xsschema` to
**0.5.0-beta.8**, and delete the three `@xsai/*` pnpm patches — the
beta.2 ones from #1602 and the beta.8 regenerations that landed on main
in `38a008500`.
- Always capture tool failures on the core-agent chat path: xsAI beta.8
marks failed tool executions with `isError: true` on `tool-result.done`,
and `llm-service.ts` maps that to AIRI's `tool-error` event via
`toAiriStreamEvent`, so the agent loop continues instead of aborting.
- Remove the `captureToolErrors` request flag (and stop forwarding it
into `streamText`).
- Rebased onto latest `main` (`b230e16b2`). Includes one follow-up fix:
steps are marked settled before the finish listener runs, and finish
listener failures still reject the stream.

### Related

- Supersedes / follows up on
[#1602](https://github.com/moeru-ai/airi/pull/1602) (`captureToolErrors`
+ xsai patches).

### Scope of capture

| Case | Covered |
| --- | --- |
| A — unknown tool | yes |
| B — invalid / unparseable arguments JSON | yes |
| C — `validate` failure | yes |
| D — `execute` throw | yes |
| `missing_name` / `missing_arguments` | no (xsai still aborts) |
| `repairToolCall` | no |

Error copy on beta.8: `Tool "<toolName>" execution failed: …` (produced
by xsAI).

## Test plan

### Automated (Vitest)

- [x] core-agent `llm-service.test.ts` — 16/16
- [x] core-agent full suite — 82/82
- [x] stage-ui `llm.test.ts` + `chat.contract.test.ts` — 44/44 (the
previous `stepsSettled` timing failure is fixed in this branch)
- [x] stage-ui full suite — 594 passed / 0 failed (one
browser-test-runner teardown error, not a test failure)
- [x] typecheck — core-agent, stage-ui, component-calling, satori-bot
pass; telegram-bot fails only at `src/utils/velin.ts`, which is
pre-existing on main and untouched by this PR

### Real-environment E2E (rebase branch, DeepSeek V4 Flash via DeepSeek
API)

Harness: `/Users/lulu/GitHub/airi-e2e/pr2164/tool-error-e2e-rebase.mjs`
— drives the built `core-agent` `streamFrom` with a deliberately failing
tool.

| Case | Result | Evidence |
| --- | --- | --- |
| D — execute throw | **pass** | `tool-error` carried `Tool
"always_fail" execution failed: boom: deterministic tool failure`; the
model answered: "The always_fail tool threw a deterministic error as
expected." |
| A — unknown tool | **pass** | The model called the unavailable
`search_the_moon_database` after being told truthfully that this tests
AIRI's error capture; runtime returned `tool-error` and the conversation
continued. |
| B — bad arguments JSON | not observed on real model | providers rarely
emit invalid `arguments`; covered by unit test |
| C — `validate` failure | pass (earlier manual run with a temporary
validate-gated tool) | — |

Evidence artifacts:
`/Users/lulu/GitHub/airi-e2e/artifacts/pr2164/tool-error-e2e-2026-08-10T16-49-15-384Z.{json,log}`

### Notes / non-goals

- Fallout-only updates for the xsai beta.8 API rename: `textStream`,
`inputTokens` / `outputTokens` / `totalTokens` in component-calling /
telegram / satori.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-11 17:51:15 +08:00
b3fac81c5a feat(minecraft): desktop relay via a Minecraft adapter (#1916)
> **Reworked.** This PR has been rebuilt around the neutral Context Flow
architecture, per @shinohara-rin's review. Minecraft is no longer
special-cased in the generic stage-ui runtime — desktop relay &
read-aloud are now reintroduced through a **Minecraft adapter** that
contributes into the existing generic stores.

## Stacked PRs (please review/merge in order)

This rework is split as you suggested — "first restore
`services/minecraft` to only own Minecraft semantics, then reintroduce
desktop relay/read-aloud through ... a Minecraft adapter":

1. **#1949** — generic stage-ui robustness fixes (spark:command result
guard + TTS session isolation), split out as you noted they were
separable.
2. **#1950** — `refactor(minecraft)`: restore `services/minecraft` to
neutral Minecraft semantics (removes the desktop-relay assumptions baked
into the merged #1915 — `handleActionIntent`'s
`username='主人'`/`relayedFrom`, the `master:` status hint, and the
`minecraft:speech` forwarding).
3. **this PR** — reintroduces desktop relay & read-aloud via the
Minecraft adapter.

Because #1949 and #1950 are not merged yet, their commits currently
appear in this PR's diff. Once they land I'll rebase this PR onto `main`
so the diff shrinks to just the adapter work.

## The adapter (`apps/stage-tamagotchi/src/renderer/stores/minecraft/`)

The renderer owns the entire desktop ↔ in-game-bot integration and
contributes into the **existing** generic stores — the same pattern as
`mcp-tools.ts` / `plugin-tools.ts`:

- **`relayToMinecraft` tool** →
`useLlmToolsStore.registerTools('minecraft', …)`, registered **only
while the bot is online** (a hard capability gate, replacing the old
prompt-only "don't relay when offline"). `execute()` re-checks
availability, so a relay is never acked after the bot disconnects.
- **Persona directive** →
`useLlmToolsetPromptsStore.registerToolsetPrompts('minecraft', …)`,
re-registered whenever online/master/runtime-context change so the model
gets a fresh directive each turn.
- **Read-aloud** → consumes the bot's `minecraft:speech` chat into the
stage TTS (Chinese-gated), and binds 主人 by **parsing the bot's neutral
status text** — no desktop-specific hint from the bot service.
- **Notify muting** →
`orchestratorStore.muteNotifySource('minecraft-bot')`.

## Generic, non-Minecraft additions

- **`useSystemSpeechStore`** (stage-ui): a neutral bridge so any module
can voice a one-off system line; `Stage.vue` consumes it via
independent, tracked TTS sessions cancelled on unmount /
provider-or-voice change.
- **`orchestrator.muteNotifySource(id)`**: a generic primitive so a
module suppresses only **its own** notifies — every other module/plugin
notify still reacts (this fixes the earlier P1 where all
`character`-targeted notifies were dropped).
- **`./tools/*` export** from stage-ui so app-side tool authors can
reuse the shared spark-command normalizers.

## services/minecraft

Re-adds the bot's own-chat forwarding on `minecraft:speech`, now landing
**together with** its adapter consumer so the read-aloud contract is
never half-present on `main`.

## How tested

- `pnpm -F @proj-airi/stage-ui typecheck` + `pnpm -F
@proj-airi/stage-tamagotchi typecheck` → 0 errors.
- 16 new unit tests (persona prompt builder + relay tool: availability
gate, do/stop, full-label fidelity, master parsing, read-aloud gating);
orchestrator suite 5/5.
- `eslint` → 0 problems.

## Addressed review points

- Restore non-Minecraft notifications → generic `muteNotifySource` (only
the bot's source is muted).
- Isolate / track-and-cancel one-off system TTS sessions → `Stage.vue`
`oneOffSessions`.
- Re-check bot availability before relaying → `isAvailable()` in
`execute()`.
- Read the master hint that actually exists → desktop now parses the
master from neutral status **text** (the `master:` hint is removed in
#1950).
- Defer Minecraft init until after channel config → adapter `setup()`
runs after the configured `serverChannelStore.initialize(...)`.

---------

Co-authored-by: Rin <shinohara-rin@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-10 15:30:45 +08:00
Neko Ayaka 38a008500d chore(deps): updated patch 2026-08-09 03:35:50 +08:00
Neko Ayaka 16f7dfaf4d chore(deps): updated 2026-08-09 01:46:13 +08:00
584e4960e9 feat(stage-pocket): improve permission management (#2184)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: LemonNeko <17664845+LemonNekoGH@users.noreply.github.com>
2026-08-08 20:16:10 +08:00
5f3746ead8 fix(stage-tamagotchi): grant screen capture through the media permission (#2178)
## Description

Screen capture in Stage Tamagotchi is denied before it ever reaches the
desktop picker: `navigator.mediaDevices.getDisplayMedia()` resolves with
`NotAllowedError: Permission denied`, so the vision screen-capture panel
can list sources but never start a stream.

The cause is in `shouldGrantElectronPermission`. Electron reports
**screen capture as the `media` permission**, not as `display-capture`,
and it only appends `audio`/`video` to `details.mediaTypes` for *device*
capture — so a `getDisplayMedia()` request arrives as `media` with an
**empty** `mediaTypes` list
([`web_contents_permission_helper.cc#L249-L274`](https://github.com/electron/electron/blob/v41.2.1/shell/browser/web_contents_permission_helper.cc#L249-L274)).

The handler took an early return for every `media` operation and
required audio-only details, so display capture was rejected before the
allowlisted `display-capture` entry could be consulted:

```ts
if (permission === 'media')
  return shouldGrantAudioCapturePermission(webContents, permission, requestingOrigin, details)

return LOCAL_APP_PERMISSION_NAMES.has(permission) && shouldGrantLocalAppPermission(...)
```

The fix resolves a `media` operation that declares no device media type
back to `display-capture`, so the existing allowlist and local-frame
checks decide the outcome — which is what `LOCAL_APP_PERMISSION_NAMES`
already intended:

```ts
const allowlistPermission = isDisplayCaptureMediaPermission(permission, details) ? 'display-capture' : permission

return LOCAL_APP_PERMISSION_NAMES.has(allowlistPermission)
  && shouldGrantLocalAppPermission(webContents, requestingOrigin, details)
```

Camera and microphone operations always report their device media type
(`['video']`, `['audio']`, `mediaType: 'audio'`), so they never take
this path and stay exactly as strict as before. Remote frames are still
rejected, because the local-frame check is unchanged and still applies
to display capture.

Three regression tests are added: screen capture from a local page is
granted, screen capture from a remote page is rejected, and a camera
request is still denied now that it shares the `media` permission.

## Linked Issues

Closes #2177

## Additional Context

- **Regression range.** This was introduced by #2002 (`5e8bf75`,
2026-07-10), which added the permission allowlist. Nothing on the
failing path is platform-specific — the `media` vs `display-capture`
mismatch is in Electron's browser process — so although the issue was
reported on Windows, screen capture has been broken on macOS and Linux
since that commit too. Worth noting for anyone triaging similar reports.
- **Detection signal.** The predicate keys on `mediaTypes.length === 0`
rather than on the absence of the field, so a `media` operation with
*no* `mediaTypes` at all (e.g. permission *checks*, which send
`mediaType: 'unknown'` instead) is not silently promoted to display
capture. That keeps the change to exactly the shape Electron documents
for `getDisplayMedia()` requests.
- **Deliberately out of scope.** #2104 (camera snapshot denied) is a
policy decision — whether the camera should join the allowlist — not
this bug, and #2132 (`systemPreferences.getMediaAccessStatus` undefined
on Linux) is unrelated. Happy to follow up on either if you'd like them
addressed.
- **Second layer still applies.** `setDisplayMediaRequestHandler` in
`packages/electron-screen-capture` is only installed inside the
`setSource` mutex window, so a grant here still requires the renderer to
have selected a source first. This change does not widen that.
- **Verification.** `media-permissions.test.ts` goes 16/16 → 19/19; with
only the tests applied, the new local-screen-capture case fails as
expected. Type checking and the repo ESLint config both pass clean on
the two touched files.

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-08 14:40:50 +09:00
Neko Ayaka eb35c4d66a refactor(*): cleaner provider design, simplified chat store 2026-08-08 01:34:44 +08:00
RainbowBird dd4658bd41 perf(api): remove legacy rolling user metric (#2233) 2026-08-06 18:31:29 +08:00
Neko Ayaka f7212965da chore(deps): updated vishot to v0.2.0 2026-08-06 02:39:20 +08:00
ff7f64ace8 feat(server): add Steam OpenID sign-in and account linking plugin (#2226)
## Summary

Adds a self-contained better-auth plugin
(`server/apps/api/src/libs/auth-plugins/steam.ts`) implementing Steam
OpenID 2.0 sign-in, account linking, and callback verification via "dumb
mode".

Steam's web login is OpenID 2.0, not OAuth2/OIDC, so it cannot be
registered as a `socialProviders` entry, and better-auth has no plugin
hook for extending its OAuth2 endpoints with a non-OAuth2 protocol. The
plugin therefore adds the endpoints Steam's protocol needs: `POST
/sign-in/steam`, `POST /link/steam`, and `GET /steam/callback`.

- Callback verification uses OpenID "dumb mode"
(`openid.mode=check_authentication`): one extra round trip to Steam
instead of managing RSA association state.
- New sign-ups get a placeholder `<steamid64>@steam.placeholder.local`
with `emailVerified: true`, mirroring Apple Sign In's
`<sub>@apple.placeholder.local`.
- The plugin's request/query schemas use Zod; a `// NOTICE:` documents
that better-auth's OpenAPI generator is Zod-native. Steam verification
uses `ofetch`.
- Wires Steam into `apps/ui-server-auth` sign-in and profile "Connected
accounts", plus the shared `OAuthProvider` / `defaultSignInProviders` in
`packages/stage-ui`.
- Linking routes through `/link/steam` via the client's `$fetch`;
unlinking needs no special-casing (`/unlink-account` already takes a
free-form `providerId`).

No Steam Web API key is required for this browser-based flow.

We intentionally do not depend on community Steam packages (e.g.
`better-auth-steam`) or the still-open upstream draft
([better-auth#4877](https://github.com/better-auth/better-auth/pull/4877)).
Steam never returns an email, and we need sign-up that does not ask the
user for one plus first-class account linking; the available options
either require an email at sign-in, lack linking, or are abandoned /
blocked — shipping a small in-tree plugin is the safer auth dependency
for this requirement.

## Test plan

- [x] `pnpm exec vitest run
server/apps/api/src/libs/auth-plugins/steam.test.ts` — 6/6 passing
- [x] `pnpm -F @proj-airi/ui-server-auth exec vitest run` — 32/32
passing
- [x] `pnpm -F @proj-airi/stage-ui exec vitest run
src/libs/steam-auth-client.test.ts
src/composables/use-linked-accounts.test.ts` — 5/5 passing
- [x] `pnpm -F @proj-airi/api-server typecheck`
- [x] `pnpm -F @proj-airi/ui-server-auth typecheck`
- [x] `pnpm -F @proj-airi/stage-ui typecheck`

## Follow-ups

- Desktop Steam ticket sign-in (top of this stack): silent startup
ticket exchange for Steam builds; the server resolves or creates the
AIRI user for the verified SteamID before issuing an OIDC code.
- Steam persona name/avatar via `GetPlayerSummaries` inside the plugin,
if display names beyond `Steam User <id>` are wanted.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-05 23:57:55 +08:00
Neko Ayaka f2d411ea22 chore(deps): updated eventa to v1.0.0-beta.14 2026-08-05 20:32:58 +08:00
Ryanba 4421b5810b fix(stage-ui-live2d): read bundled model ZIPs as array buffers (#2224) 2026-08-05 15:39:34 +08:00
Neko Ayaka 0f20a2784b chore(deps): updated eventa to v1.0.0-beta.13 2026-08-05 00:49:14 +08:00
Makitoandautofix-ci[bot] 42aaa514a6 chore(ci): add workflow to upload glossary to crowdin (#2220)
This pull request adds a workflow to upload the TBX output from the
glossary to Crowdin.

Improves #2148.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-08-05 01:26:30 +09:00
Neko Ayaka 4f7a9d63e9 chore(deps): updated eventa to v1.0.0-beta.9 2026-08-04 22:05:57 +08:00
Neko 5a56770f1c fix(stage-ui-live2d): support CJK paths in Live2D archives (#2219) 2026-08-04 22:05:40 +08:00
Neko Ayaka e6ca9750b4 fix(.agents/skills): added vishot skills and create-pr guidelines 2026-08-04 20:59:49 +08:00
Weathercoldandgithub-actions[bot] 5f0076e3d4 chore(nix): update pnpmDeps hash (#2216)
Auto-generated by CI to keep Nix pnpmDeps hash up-to-date.

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-04 10:07:00 +00:00
Neko Ayaka e289d87af8 chore(deps): updated 2026-08-04 17:52:19 +08:00
Neko 47c23e6467 feat(ui): add animated content primitive (#2212) 2026-08-04 17:48:17 +08:00
Neko Ayaka 1226417768 refactor(*): new button 2026-08-04 03:24:32 +08:00
Makito b26ea3123d feat(i18n): set up glossary (#2198)
This pull request introduces the initial glossary for the project to
improve the translation quality.

Implements #2148.

### TODOs

- [x] Add the definition YAML
- [x] Add a generator to produce Crowdin-compatible (TBX v3) format
- [x] AGENTS.md
- [ ] ~Workflow~ (Split to another PR)
- [ ] ~Skills~ (Same as above)
2026-08-03 02:01:43 +09:00
Makito be3621ef39 chore(deps): remove stale patch for @mediapipe/tasks-vision 2026-08-03 01:46:09 +09:00
Makito 51d98ee4ac chore(deps): add overrides for @better-auth/oauth-provider 2026-08-03 01:08:24 +09:00
RainbowBird d5a241b10e chore: migrate services to integration folder 2026-08-02 20:12:13 +08:00
RainbowBird 4ccde2c96e chore: move the server to an independent folder 2026-08-02 18:43:57 +08:00
藍+85CD 9dafc6d3ef chore(deps): bump mmd version (#2175) 2026-07-30 11:28:35 +08:00
藍+85CD c97169bac7 perf(stage-ui-tachie): use fflate instead of jszip (#2172) 2026-07-30 08:36:41 +08:00
藍+85CD e29fcb8c2a refactor(stage-ui-mmd): use @moeru/three-mmd (#2167) 2026-07-30 00:15:11 +08:00