airi/AGENTS.md

9.3 KiB
Raw Blame History

Project AIRI Agent Guide

Concise but detailed reference for contributors working across the moeru-ai/airi monorepo. Improve code when you touch it; avoid one-off patterns.

Tech Stack (by surface)

  • Desktop (stage-tamagotchi): Electron, Vue, Vite, TypeScript, Pinia, VueUse, Eventa (IPC/RPC), UnoCSS, Vitest, ESLint.
  • Web (stage-web): Vue 3 + Vue Router, Vite, TypeScript, Pinia, VueUse, UnoCSS, Vitest, ESLint. Backend: WIP.
  • Mobile (stage-pocket): Vue 3 + Vue Router, Vite, TypeScript, Pinia, VueUse, UnoCSS, Vitest, ESLint, Kotlin, Swift, Capacitor.
  • UI/Shared Packages:
    • packages/stage-ui: Core business components, composables, stores shared by stage-web & stage-tamagotchi (heart of stage work).
    • packages/stage-ui-three: Three.js bindings + Vue components.
    • packages/stage-ui-pixi: Planned Pixi bindings.
    • packages/stage-shared: Shared logic across stage-ui, stage-ui-three, stage-web, stage-tamagotchi.
    • packages/ui: Standardized primitives (inputs, textarea, buttons, layout) built on reka-ui; minimal business logic.
    • packages/i18n: Central translations.
    • Server channel: packages/server-runtime, packages/server-sdk, packages/server-shared (power services/ and plugins/).
    • Legacy: crates/ (old Tauri desktop; current desktop is Electron).

Structure & Responsibilities

  • Apps
    • apps/stage-web: Web app; composables/stores in src/composables, src/stores; pages in src/pages; devtools in src/pages/devtools; router config via vite.config.ts.
    • apps/stage-tamagotchi: Electron app; renderer pages in src/renderer/pages; devtools in src/renderer/pages/devtools; settings layout at src/renderer/layouts/settings.vue; router config via electron.vite.config.ts.
    • Settings/devtools routes rely on <route lang="yaml"> meta: layout: settings </route>; ensure routes/icons are registered accordingly (apps/stage-tamagotchi/src/renderer/layouts/settings.vue, apps/stage-web/src/layouts/settings.vue).
    • Shared page bases: packages/stage-pages.
    • Stage pages: apps/stage-web/src/pages, apps/stage-tamagotchi/src/renderer/pages (plus devtools folders).
  • Stage UI internals (packages/stage-ui/src)
    • Providers: stores/providers.ts and stores/providers/ (standardized provider definitions).
    • Modules: stores/modules/ (AIRI orchestration building blocks).
    • Composables: composables/ (business-oriented Vue helpers).
    • Components: components/; scenarios in components/scenarios/ for page/use-case-specific pieces.
    • Stories: packages/stage-ui/stories, packages/stage-ui/histoire.config.ts (e.g. components/misc/Button.story.vue).
  • IPC/Eventa: Always use @moeru/eventa for type-safe, framework/runtime-agnostic IPC/RPC. Define contracts centrally (e.g., apps/stage-tamagotchi/src/shared) and follow usage patterns in apps/stage-tamagotchi/src/main/services/electron for main/renderer integration.
  • Dependency Injection: Use injeca for services/electron modules/plugins/frontend; see apps/stage-tamagotchi/src/main/index.ts for composition patterns.
  • Build/CI/Lint: .github/workflows for pipelines; eslint.config.js for lint rules.
  • Bundling libs: Use tsdown for new modules (see packages/vite-plugin-warpdrive).
  • Styles: UnoCSS config at uno.config.ts; check apps/stage-web/src/styles for existing animations; prefer UnoCSS over Tailwind.

Key Path Index (what lives where)

  • packages/stage-ui: Core stage business components/composables/stores.
    • src/stores/providers.ts and src/stores/providers/: provider definitions (standardized).
    • src/stores/modules/: AIRI orchestration modules.
    • src/composables/: reusable Vue composables (business-oriented).
    • src/components/: business components; src/components/scenarios/ for page/use-case-specific pieces.
    • Stories: packages/stage-ui/stories, packages/stage-ui/histoire.config.ts (e.g. components/misc/Button.story.vue).
  • packages/stage-ui-three: Three.js bindings + Vue components.
  • packages/stage-ui-pixi: Planned Pixi bindings.
  • packages/stage-shared: Shared logic across stage-ui, stage-ui-three, stage-web, stage-tamagotchi.
  • packages/ui: Standardized primitives (inputs/textarea/buttons/layout) built on reka-ui.
  • packages/i18n: All translations.
  • Server channel: packages/server-runtime, packages/server-sdk, packages/server-shared (power services/ and plugins/).
  • Legacy desktop: crates/ (old Tauri; Electron is current).
  • Pages: packages/stage-pages (shared bases); apps/stage-web/src/pages and apps/stage-tamagotchi/src/renderer/pages for app-specific pages; devtools live in each apps .../pages/devtools.
  • Router configs: apps/stage-web/vite.config.ts, apps/stage-tamagotchi/electron.vite.config.ts.
  • Devtools/layouts: apps/stage-tamagotchi/src/renderer/layouts/settings.vue, apps/stage-web/src/layouts/settings.vue.
  • IPC/Eventa contracts/examples: apps/stage-tamagotchi/src/shared, apps/stage-tamagotchi/src/main/services/electron.
  • DI examples: apps/stage-tamagotchi/src/main/index.ts (injeca).
  • Styles: uno.config.ts (UnoCSS), apps/stage-web/src/styles (animations/reference).
  • Build pipeline refs: .github/workflows; lint rules in eslint.config.js.
  • Tailwind/UnoCSS: prefer UnoCSS; if standardizing styles, add shortcuts/rules/plugins in uno.config.ts.
  • Bundling pattern: packages/vite-plugin-warpdrive (tsdown example).

Commands (pnpm with filters)

Use pnpm workspace filters to scope tasks. Examples below are generic; replace the filter with the target workspace name (e.g. @proj-airi/stage-tamagotchi, @proj-airi/stage-web, @proj-airi/stage-ui, etc.).

  • Typecheck
    • pnpm -F <package.json name> typecheck
    • Example: pnpm -F @proj-airi/stage-tamagotchi typecheck (runs tsc + vue-tsc).
  • Unit tests (Vitest)
    • Targeted: pnpm exec vitest run <path/to/file> e.g. pnpm exec vitest run apps/stage-tamagotchi/src/renderer/stores/tools/builtin/widgets.test.ts
    • Workspace: pnpm -F <package.json name> exec vitest run e.g. pnpm -F @proj-airi/stage-tamagotchi exec vitest run
    • Root pnpm test:run: runs all tests across registered projects. If no tests are found, check vitest.config.ts include patterns.
    • Root vitest.config.ts includes apps/stage-tamagotchi and other projects; each app/package can have its own vitest.config.
  • Lint
    • pnpm lint and pnpm lint:fix
    • Formatting is handled via ESLint; pnpm lint:fix applies formatting.
  • Build
    • pnpm -F <package.json name> build
    • Example: pnpm -F @proj-airi/stage-tamagotchi build (typecheck + electron-vite build).

Styling & Components

  • Prefer Vue v-bind class arrays for readability when working with UnoCSS & tailwindcss: do :class="['px-2','py-1','flex','items-center','bg-white/50','dark:bg-black/50']", don't do class="px-2 py-1 flex items-center bg-white/50 dark:bg-black/50", don't do px="2" py="1" flex="~ items-center" bg="white/50 dark:black/50"; avoid long inline class="". Refactor legacy when you touch it.
  • Use/extend UnoCSS shortcuts/rules in uno.config.ts; add new shortcuts/rules/plugins there when standardizing styles. Prefer UnoCSS over Tailwind.
  • Check apps/stage-web/src/styles for existing animations; reuse or extend before adding new ones. If you need config references, see apps/stage-web/tsconfig.json and uno.config.ts.
  • Build primitives on @proj-airi/ui (reka-ui) instead of raw DOM; see packages/ui/src/components/Form for patterns.
  • Use Iconify icon sets; avoid bespoke SVGs.
  • Animations: keep intuitive, lively, and readable.
  • useDark (VueUse): set disableTransition: false or use existing composables in packages/ui.

Testing Practices

  • Vitest per project; keep runs targeted for speed.
  • Mock IPC/services with vi.fn/vi.mock; do not rely on real Electron runtime.
  • For external providers/services, add both mock-based tests and integration-style tests (with env guards) when feasible. You can mock imports with Vitest.
  • Grow component/e2e coverage progressively (Vitest browser env where possible). Use expect and assert mock calls/params.

TypeScript / IPC / Tools

  • Keep JSON Schemas provider-compliant (explicit type: object, required fields; avoid unbounded records).
  • Favor functional patterns + DI (injeca); avoid new class hierarchies unless extending browser APIs (classes are harder to mock/test).
  • Centralize Eventa contracts; use @moeru/eventa for all events.

i18n

  • Add/modify translations in packages/i18n; avoid scattering i18n across apps/packages.

CSS/UNO

  • Use/extend UnoCSS shortcuts in uno.config.ts.
  • Prefer grouped class arrays for readability; refactor legacy inline strings when possible.

Naming & Comments

  • File names: kebab-case.
  • Avoid classes unless necessary for browser API extensions; FP + DI is easier to test/mock.
  • Avoid stubby/hacky scaffolding; prefer small refactors that leave code cleaner.
  • Use markers:
    • // TODO: follow-ups
    • // REVIEW: concerns/needs another eye
    • // NOTICE: magic numbers, hacks, important context, external references/links

PR / Workflow Tips

  • Rebase pulls; branch naming username/feat/short-name; clear commit messages (gitmoji optional).
  • Summarize changes, how tested (commands), and follow-ups.
  • Improve legacy you touch; avoid one-off patterns.
  • Keep changes scoped; use workspace filters (pnpm -F <workspace> <script>).