Yuki Takei 1 день назад
Родитель
Сommit
8d6e5babad
4 измененных файлов с 108 добавлено и 549 удалено
  1. 87 0
      .claude/rules/project-structure.md
  2. 0 252
      .claude/skills/monorepo-overview/SKILL.md
  3. 0 269
      .claude/skills/tech-stack/SKILL.md
  4. 21 28
      AGENTS.md

+ 87 - 0
.claude/rules/project-structure.md

@@ -0,0 +1,87 @@
+# Project Structure
+
+## Monorepo Layout
+
+```
+growi/
+├── apps/
+│   ├── app/           # Main GROWI application (Next.js + Express + MongoDB)
+│   ├── pdf-converter/ # PDF conversion microservice (Ts.ED + Puppeteer)
+│   └── slackbot-proxy/# Slack integration proxy (Ts.ED + TypeORM + MySQL)
+├── packages/          # Shared libraries
+│   ├── core/          # Domain types & utilities hub (see below)
+│   ├── ui/            # React component library
+│   ├── editor/        # Markdown editor
+│   └── pluginkit/     # Plugin framework
+└── .claude/
+    ├── rules/         # Always loaded into every session
+    ├── skills/        # Load on demand via Skill tool
+    └── agents/        # Specialized subagents
+```
+
+## @growi/core — Shared Domain Hub
+
+`@growi/core` is the single source of truth for cross-package types and utilities, depended on by all other packages (10+ consumers).
+
+- **Shared interfaces go here** — `IPage`, `IUser`, `IRevision`, `Ref<T>`, `HasObjectId`, etc.
+- **Cross-cutting pure utilities** — page path validation, ObjectId checks, `serializeUserSecurely()`
+- **Global type augmentations** — `declare global` in `index.ts` propagates to all consumers
+- Minimal runtime deps (only `bson-objectid`); safe to import from both server and client
+
+> When adding a new interface used by multiple packages, put it in `@growi/core`, not in the consuming package.
+
+## Build Order Management
+
+Turborepo build dependencies are declared **explicitly**, not auto-detected from `pnpm-workspace.yaml`.
+
+When a package gains a new workspace dependency on another buildable package (one that produces `dist/`), declare it in a per-package `turbo.json`:
+
+```json
+// packages/my-package/turbo.json
+{
+  "extends": ["//"],
+  "tasks": {
+    "build": { "dependsOn": ["@growi/some-dep#build"] },
+    "dev":   { "dependsOn": ["@growi/some-dep#dev"] }
+  }
+}
+```
+
+- `"extends": ["//"]` inherits root task definitions; only add the extra `dependsOn`
+- Omitting this causes Turborepo to build in the wrong order → missing `dist/` → type errors
+
+## Adding Workspace Dependencies
+
+When referencing another package in the monorepo, use the `workspace:` protocol — never a hardcoded version:
+
+```json
+{ "@growi/core": "workspace:^" }
+```
+
+After editing `package.json`, run `pnpm install` from the repo root to update the lockfile.
+
+## New Package Defaults
+
+When creating a new package, use **Biome + Vitest** from the start (not ESLint/Prettier/Jest):
+
+```bash
+biome check <files>          # lint + format check
+biome check --write <files>  # auto-fix
+```
+
+Configuration lives in the root `biome.json` (inherited by all packages). Legacy packages may still use ESLint during migration — don't add ESLint to new packages.
+
+## Changeset Workflow
+
+```bash
+# 1. After making changes that affect published packages:
+npx changeset          # Describe the change, select bump type
+
+# 2. Commit both code and the generated .changeset/*.md file
+
+# 3. On release:
+pnpm run version-subpackages   # Updates CHANGELOG.md + package.json versions
+pnpm run release-subpackages   # Publishes @growi/core, @growi/pluginkit to npm
+```
+
+Published packages: `@growi/core`, `@growi/pluginkit`. Internal packages do not need changesets.

+ 0 - 252
.claude/skills/monorepo-overview/SKILL.md

@@ -1,252 +0,0 @@
----
-name: monorepo-overview
-description: GROWI monorepo structure, workspace organization, and architectural principles. Auto-invoked for all GROWI development work.
-user-invocable: false
----
-
-# GROWI Monorepo Overview
-
-GROWI is a team collaboration wiki platform built as a monorepo using **pnpm workspace + Turborepo**.
-
-## Monorepo Structure
-
-```
-growi/
-├── apps/                    # Applications
-│   ├── app/                # Main GROWI application (Next.js + Express + MongoDB)
-│   ├── pdf-converter/      # PDF conversion microservice (Ts.ED + Puppeteer)
-│   └── slackbot-proxy/     # Slack integration proxy (Ts.ED + TypeORM + MySQL)
-├── packages/               # Shared libraries
-│   ├── core/              # Core utilities and shared logic
-│   ├── core-styles/       # Common styles (SCSS)
-│   ├── editor/            # Markdown editor components
-│   ├── ui/                # UI component library
-│   ├── pluginkit/         # Plugin framework
-│   ├── slack/             # Slack integration utilities
-│   ├── presentation/      # Presentation mode
-│   ├── pdf-converter-client/ # PDF converter client library
-│   └── remark-*/          # Markdown plugins (remark-lsx, remark-drawio, etc.)
-└── Configuration files
-    ├── pnpm-workspace.yaml
-    ├── turbo.json
-    ├── package.json
-    └── .changeset/
-```
-
-## Workspace Management
-
-### pnpm Workspace
-
-All packages are managed via **pnpm workspace**. Package references use the `workspace:` protocol:
-
-```json
-{
-  "dependencies": {
-    "@growi/core": "workspace:^",
-    "@growi/ui": "workspace:^"
-  }
-}
-```
-
-### Turborepo Orchestration
-
-Turborepo handles task orchestration with caching and parallelization:
-
-```bash
-# Run tasks across all workspaces
-turbo run dev
-turbo run test
-turbo run lint
-turbo run build
-
-# Filter to specific package
-turbo run test --filter @growi/app
-turbo run lint --filter @growi/core
-```
-
-### Build Order Management
-
-Build dependencies in this monorepo are **not** declared with `dependsOn: ["^build"]` (the automatic workspace-dependency mode). Instead, they are declared **explicitly** — either in the root `turbo.json` for legacy entries, or in per-package `turbo.json` files for newer packages.
-
-**When to update**: whenever a package gains a new workspace dependency on another buildable package (one that produces a `dist/`), declare the build-order dependency explicitly. Without it, Turborepo may build in the wrong order, causing missing `dist/` files or type errors.
-
-**Pattern — per-package `turbo.json`** (preferred for new dependencies):
-
-```json
-// packages/my-package/turbo.json
-{
-  "extends": ["//"],
-  "tasks": {
-    "build": { "dependsOn": ["@growi/some-dep#build"] },
-    "dev":   { "dependsOn": ["@growi/some-dep#dev"] }
-  }
-}
-```
-
-- `"extends": ["//"]` inherits all root task definitions; only add the extra `dependsOn`
-- Keep root `turbo.json` clean — package-level overrides live with the package that owns the dependency
-- For packages with multiple tasks (watch, lint, test), mirror the dependency in each relevant task
-
-**Existing examples**:
-- `packages/slack/turbo.json` — `build`/`dev` depend on `@growi/logger`
-- `packages/remark-attachment-refs/turbo.json` — all tasks depend on `@growi/core`, `@growi/logger`, `@growi/remark-growi-directive`, `@growi/ui`
-- Root `turbo.json` — `@growi/ui#build` depends on `@growi/core#build` (pre-dates the per-package pattern)
-
-## Architectural Principles
-
-### 1. Feature-Based Architecture (Recommended)
-
-**All packages should prefer feature-based organization**:
-
-```
-{package}/src/
-├── features/              # Feature modules
-│   ├── {feature-name}/
-│   │   ├── index.ts      # Main export
-│   │   ├── interfaces/   # TypeScript types
-│   │   ├── server/       # Server-side logic (if applicable)
-│   │   ├── client/       # Client-side logic (if applicable)
-│   │   └── utils/        # Shared utilities
-```
-
-**Benefits**:
-- Clear boundaries between features
-- Easy to locate related code
-- Facilitates gradual migration from legacy structure
-
-### 2. Server-Client Separation
-
-For full-stack packages (like apps/app), separate server and client logic:
-
-- **Server code**: Node.js runtime, database access, API routes
-- **Client code**: Browser runtime, React components, UI state
-
-This enables better code splitting and prevents server-only code from being bundled into client.
-
-### 3. Shared Libraries in packages/
-
-Common code should be extracted to `packages/`:
-
-- **core**: Domain hub (see below)
-- **ui**: Reusable React components
-- **editor**: Markdown editor
-- **pluginkit**: Plugin system framework
-
-#### @growi/core — Domain & Utilities Hub
-
-`@growi/core` is the foundational shared package depended on by all other packages (10 consumers). Its responsibilities:
-
-- **Domain type definitions** — Single source of truth for cross-package interfaces (`IPage`, `IUser`, `IRevision`, `Ref<T>`, `HasObjectId`, etc.)
-- **Cross-cutting utilities** — Pure functions for page path validation, ObjectId checks, serialization (e.g., `serializeUserSecurely()`)
-- **System constants** — File types, plugin configs, scope enums
-- **Global type augmentations** — Runtime/polyfill type declarations visible to all consumers (e.g., `RegExp.escape()` via `declare global` in `index.ts`)
-
-Key patterns:
-
-1. **Shared types and global augmentations go in `@growi/core`** — Not duplicated per-package. `declare global` in `index.ts` propagates to all consumers through the module graph.
-2. **Subpath exports for granular imports** — `@growi/core/dist/utils/page-path-utils` instead of barrel imports from root.
-3. **Minimal runtime dependencies** — Only `bson-objectid`; ~70% types. Safe to import from both server and client contexts.
-4. **Server-specific interfaces are namespaced** — Under `interfaces/server/`.
-5. **Dual format (ESM + CJS)** — Built via Vite with `preserveModules: true` and `vite-plugin-dts` (`copyDtsFiles: true`).
-
-## Version Management with Changeset
-
-GROWI uses **Changesets** for version management and release notes:
-
-```bash
-# Add a changeset (after making changes)
-npx changeset
-
-# Version bump (generates CHANGELOGs and updates versions)
-pnpm run version-subpackages
-
-# Publish packages to npm (for @growi/core, @growi/pluginkit)
-pnpm run release-subpackages
-```
-
-### Changeset Workflow
-
-1. Make code changes
-2. Run `npx changeset` and describe the change
-3. Commit both code and `.changeset/*.md` file
-4. On release, run `pnpm run version-subpackages`
-5. Changesets automatically updates `CHANGELOG.md` and `package.json` versions
-
-### Version Schemes
-
-- **Main app** (`apps/app`): Manual versioning with RC prereleases
-  - `pnpm run version:patch`, `pnpm run version:prerelease`
-- **Shared libraries** (`packages/core`, `packages/pluginkit`): Changeset-managed
-- **Microservices** (`apps/pdf-converter`, `apps/slackbot-proxy`): Independent versioning
-
-## Package Categories
-
-### Applications (apps/)
-
-| Package | Description | Tech Stack |
-|---------|-------------|------------|
-| **@growi/app** | Main wiki application | Next.js (Pages Router), Express, MongoDB, Jotai, SWR |
-| **@growi/pdf-converter** | PDF export service | Ts.ED, Puppeteer |
-| **@growi/slackbot-proxy** | Slack bot proxy | Ts.ED, TypeORM, MySQL |
-
-### Core Libraries (packages/)
-
-| Package | Description | Published to npm |
-|---------|-------------|------------------|
-| **@growi/core** | Core utilities | ✅ |
-| **@growi/pluginkit** | Plugin framework | ✅ |
-| **@growi/ui** | UI components | ❌ (internal) |
-| **@growi/editor** | Markdown editor | ❌ (internal) |
-| **@growi/core-styles** | Common styles | ❌ (internal) |
-
-## Development Workflow
-
-### Initial Setup
-
-```bash
-# Install dependencies for all packages
-pnpm install
-
-# Bootstrap (install + build dependencies)
-turbo run bootstrap
-```
-
-### Daily Development
-
-```bash
-# Start all dev servers (apps/app + dependencies)
-turbo run dev
-
-# Run a specific test file (from package directory)
-pnpm vitest run yjs.integ
-
-# Run ALL tests / lint for a package
-turbo run test --filter @growi/app
-turbo run lint --filter @growi/core
-```
-
-### Cross-Package Development
-
-When modifying shared libraries (packages/*), ensure dependent apps reflect changes:
-
-1. Make changes to `packages/core`
-2. Turborepo automatically detects changes and rebuilds dependents
-3. Test in `apps/app` to verify
-
-## Key Configuration Files
-
-- **pnpm-workspace.yaml**: Defines workspace packages
-- **turbo.json**: Turborepo pipeline configuration
-- **.changeset/config.json**: Changeset configuration
-- **tsconfig.base.json**: Base TypeScript config for all packages
-- **vitest.workspace.mts**: Vitest workspace config
-- **biome.json**: Biome linter/formatter config
-
-## Design Principles Summary
-
-1. **Feature Isolation**: Use feature-based architecture for new code
-2. **Server-Client Separation**: Keep server and client code separate
-3. **Shared Libraries**: Extract common code to packages/
-4. **Type-Driven Development**: Define interfaces before implementation
-5. **Progressive Enhancement**: Migrate legacy code gradually
-6. **Version Control**: Use Changesets for release management

+ 0 - 269
.claude/skills/tech-stack/SKILL.md

@@ -1,269 +0,0 @@
----
-name: tech-stack
-description: GROWI technology stack, build tools, and global commands. Auto-invoked for all GROWI development work.
-user-invocable: false
----
-
-# GROWI Tech Stack
-
-## Core Technologies
-
-- **TypeScript** ~5.0.0
-- **Node.js** ^18 || ^20
-- **MongoDB** with **Mongoose** ^6.13.6 (apps/app)
-- **MySQL** with **TypeORM** 0.2.x (apps/slackbot-proxy)
-
-## Frontend Framework
-
-- **React** 18.x
-- **Next.js** (Pages Router) - Full-stack framework for apps/app
-
-## State Management & Data Fetching (Global Standard)
-
-- **Jotai** - Atomic state management (recommended for all packages with UI state)
-  - Use for UI state, form state, modal state, etc.
-  - Lightweight, TypeScript-first, minimal boilerplate
-
-- **SWR** ^2.3.2 - Data fetching with caching
-  - Use for API data fetching with automatic revalidation
-  - Works seamlessly with RESTful APIs
-
-### Why Jotai + SWR?
-
-- **Separation of concerns**: Jotai for UI state, SWR for server state
-- **Performance**: Fine-grained reactivity (Jotai) + intelligent caching (SWR)
-- **Type safety**: Both libraries have excellent TypeScript support
-- **Simplicity**: Minimal API surface, easy to learn
-
-## Build & Development Tools
-
-### Package Management
-- **pnpm** Package manager (faster, more efficient than npm/yarn)
-
-### Monorepo Orchestration
-- **Turborepo** ^2.1.3 - Build system with caching and parallelization
-
-### Linter & Formatter
-- **Biome** ^2.2.6 - Unified linter and formatter (recommended)
-  - Replaces ESLint + Prettier
-  - Significantly faster (10-100x)
-  - Configuration: `biome.json`
-
-```bash
-# Lint and format check
-biome check <files>
-
-# Auto-fix issues
-biome check --write <files>
-```
-
-- **Stylelint** ^16.5.0 - SCSS/CSS linter
-  - Configuration: `.stylelintrc.js`
-
-```bash
-# Lint styles
-stylelint "src/**/*.scss"
-```
-
-### Testing
-- **Vitest** ^2.1.1 - Unit and integration testing (recommended)
-  - Fast, Vite-powered
-  - Jest-compatible API
-  - Configuration: `vitest.workspace.mts`
-
-- **React Testing Library** ^16.0.1 - Component testing
-  - User-centric testing approach
-
-- **vitest-mock-extended** ^2.0.2 - Type-safe mocking
-  - TypeScript autocomplete for mocks
-
-- **Playwright** ^1.49.1 - E2E testing
-  - Cross-browser testing
-
-## Essential Commands (Global)
-
-### Development
-
-```bash
-# Start all dev servers (apps/app + dependencies)
-turbo run dev
-
-# Start dev server for specific package
-turbo run dev --filter @growi/app
-
-# Install dependencies for all packages
-pnpm install
-
-# Bootstrap (install + build dependencies)
-turbo run bootstrap
-```
-
-### Testing & Quality
-
-```bash
-# Run a specific test file (from package directory, e.g. apps/app)
-pnpm vitest run yjs.integ          # Partial file name match
-pnpm vitest run helper.spec        # Works for any test file
-pnpm vitest run yjs.integ --repeat=10  # Repeat for flaky test detection
-
-# Run ALL tests for a package (uses Turborepo caching)
-turbo run test --filter @growi/app
-
-# Run linters for specific package
-turbo run lint --filter @growi/app
-```
-
-### Building
-
-```bash
-# Build all packages
-turbo run build
-
-# Build specific package
-turbo run build --filter @growi/core
-```
-
-## Turborepo Task Filtering
-
-Turborepo uses `--filter` to target specific packages:
-
-```bash
-# Run task for single package
-turbo run test --filter @growi/app
-
-# Run task for multiple packages
-turbo run build --filter @growi/core --filter @growi/ui
-
-# Run task for package and its dependencies
-turbo run build --filter @growi/app...
-```
-
-## Important Configuration Files
-
-### Workspace Configuration
-- **pnpm-workspace.yaml** - Defines workspace packages
-  ```yaml
-  packages:
-    - 'apps/*'
-    - 'packages/*'
-  ```
-
-### Build Configuration
-- **turbo.json** - Turborepo pipeline configuration
-  - Defines task dependencies, caching, and outputs
-
-### TypeScript Configuration
-- **tsconfig.base.json** - Base TypeScript config extended by all packages
-  - **Target**: ESNext
-  - **Module**: ESNext
-  - **Strict Mode**: Enabled (`strict: true`)
-  - **Module Resolution**: Bundler
-  - **Allow JS**: true (for gradual migration)
-  - **Isolated Modules**: true (required for Vite, SWC)
-
-Package-specific tsconfig.json example:
-```json
-{
-  "extends": "../../tsconfig.base.json",
-  "compilerOptions": {
-    "outDir": "./dist",
-    "rootDir": "./src"
-  },
-  "include": ["src/**/*"],
-  "exclude": ["node_modules", "dist", "**/*.spec.ts"]
-}
-```
-
-### Testing Configuration
-- **vitest.workspace.mts** - Vitest workspace config
-  - Defines test environments (Node.js, happy-dom)
-  - Configures coverage
-
-### Linter Configuration
-- **biome.json** - Biome linter/formatter config
-  - Rules, ignore patterns, formatting options
-
-## Development Best Practices
-
-### Command Usage
-
-1. **Use Turborepo for full-package tasks** (all tests, lint, build):
-   - ✅ `turbo run test --filter @growi/app`
-   - ❌ `cd apps/app && pnpm test` (bypasses Turborepo caching)
-2. **Use vitest directly for individual test files** (from package directory):
-   - ✅ `pnpm vitest run yjs.integ` (simple, fast)
-   - ❌ `turbo run test --filter @growi/app -- yjs.integ` (unnecessary overhead)
-
-2. **Use pnpm for package management**:
-   - ✅ `pnpm install`
-   - ❌ `npm install` or `yarn install`
-
-3. **Run tasks from workspace root**:
-   - Turborepo handles cross-package dependencies
-   - Caching works best from root
-
-### State Management Guidelines
-
-1. **Use Jotai for UI state**:
-   ```typescript
-   // Example: Modal state
-   import { atom } from 'jotai';
-
-   export const isModalOpenAtom = atom(false);
-   ```
-
-2. **Use SWR for server state**:
-   ```typescript
-   // Example: Fetching pages
-   import useSWR from 'swr';
-
-   const { data, error, isLoading } = useSWR('/api/pages', fetcher);
-   ```
-
-3. **Avoid mixing concerns**:
-   - Don't store server data in Jotai atoms
-   - Don't manage UI state with SWR
-
-## Migration Notes
-
-- **New packages**: Use Biome + Vitest from the start
-- **Legacy packages**: Can continue using existing tools during migration
-- **Gradual migration**: Prefer updating to Biome + Vitest when modifying existing files
-
-## Technology Decisions
-
-### Why Next.js Pages Router (not App Router)?
-
-- GROWI started before App Router was stable
-- Pages Router is well-established and stable
-- Migration to App Router is being considered for future versions
-
-### Why Jotai (not Redux/Zustand)?
-
-- **Atomic approach**: More flexible than Redux, simpler than Recoil
-- **TypeScript-first**: Excellent type inference
-- **Performance**: Fine-grained reactivity, no unnecessary re-renders
-- **Minimal boilerplate**: Less code than Redux
-
-### Why SWR (not React Query)?
-
-- **Simplicity**: Smaller API surface
-- **Vercel integration**: Built by Vercel (same as Next.js)
-- **Performance**: Optimized for Next.js SSR/SSG
-
-### Why Biome (not ESLint + Prettier)?
-
-- **Speed**: 10-100x faster than ESLint
-- **Single tool**: Replaces both ESLint and Prettier
-- **Consistency**: No conflicts between linter and formatter
-- **Growing ecosystem**: Active development, Rust-based
-
-## Package-Specific Tech Stacks
-
-Different apps in the monorepo may use different tech stacks:
-
-- **apps/app**: Next.js + Express + MongoDB + Jotai + SWR
-- **apps/pdf-converter**: Ts.ED + Puppeteer
-- **apps/slackbot-proxy**: Ts.ED + TypeORM + MySQL
-
-See package-specific CLAUDE.md or skills for details.

+ 21 - 28
AGENTS.md

@@ -14,40 +14,35 @@ GROWI is a team collaboration wiki platform using Markdown, featuring hierarchic
 
 ## Knowledge Base
 
-### Claude Code Skills (Auto-Invoked)
+### Always-Loaded Context
 
-Technical information is available in **Claude Code Skills** (`.claude/skills/`), which are automatically invoked during development.
-
-**Global Skills** (always loaded):
-
-| Skill | Description |
-|-------|-------------|
-| **monorepo-overview** | Monorepo structure, workspace organization, Changeset versioning |
-| **tech-stack** | Technology stack, pnpm/Turborepo, TypeScript, Biome |
-
-**Rules** (always applied):
+**Rules** (`.claude/rules/`) — loaded into every session automatically:
 
 | Rule | Description |
 |------|-------------|
+| **project-structure** | Monorepo layout, @growi/core role, build order, Changeset workflow |
 | **coding-style** | Coding conventions, naming, exports, immutability, comments |
 | **security** | Security checklist, secret management, OWASP vulnerability prevention |
 | **performance** | Model selection, context management, build troubleshooting |
+| **testing** | Test commands, pnpm vitest usage |
+
+### On-Demand Skills
 
-**Agents** (specialized):
+**Agents** (specialized subagents):
 
 | Agent | Description |
 |-------|-------------|
 | **build-error-resolver** | TypeScript/build error resolution with minimal diffs |
 | **security-reviewer** | Security vulnerability detection, OWASP Top 10 |
 
-**Commands** (user-invocable):
+**Commands** (user-invocable via `/`):
 
 | Command | Description |
 |---------|-------------|
 | **/tdd** | Test-driven development workflow |
 | **/learn** | Extract reusable patterns from sessions |
 
-**apps/app Skills** (loaded when working in apps/app):
+**apps/app Skills** (load via Skill tool when working in apps/app):
 
 | Skill | Description |
 |-------|-------------|
@@ -63,10 +58,6 @@ Each application has its own CLAUDE.md with detailed instructions:
 - `apps/pdf-converter/CLAUDE.md` - PDF conversion microservice
 - `apps/slackbot-proxy/CLAUDE.md` - Slack integration proxy
 
-### Serena Memories
-
-Additional detailed specifications are stored in **Serena memories** and can be referenced when needed for specific features or subsystems.
-
 ## Quick Reference
 
 ### Essential Commands (Global)
@@ -94,9 +85,9 @@ growi/
 │   └── slackbot-proxy/     # Slack integration proxy
 ├── packages/               # Shared libraries (@growi/core, @growi/ui, etc.)
 └── .claude/
-    ├── skills/             # Claude Code skills (auto-loaded)
-    ├── rules/              # Coding standards (always applied)
-    ├── agents/             # Specialized agents
+    ├── rules/              # Always loaded into every session
+    ├── skills/             # Load on demand via Skill tool
+    ├── agents/             # Specialized subagents
     └── commands/           # User-invocable commands (/tdd, /learn)
 ```
 
@@ -104,11 +95,13 @@ growi/
 
 1. **Feature-Based Architecture**: Create new features in `features/{feature-name}/`
 2. **Server-Client Separation**: Keep server and client code separate
-3. **State Management**: Jotai for UI state, SWR for data fetching
-4. **Named Exports**: Prefer named exports (except Next.js pages)
-5. **Test Co-location**: Place test files next to source files
-6. **Type Safety**: Use strict TypeScript throughout
-7. **Changeset**: Use `npx changeset` for version management
+3. **State Management**: Jotai for UI state, SWR for data fetching *(Jotai: atomic/TypeScript-first for UI; SWR: caching/revalidation for server state — don't mix)*
+4. **Linter/Formatter**: Biome (replaces ESLint + Prettier); Stylelint for SCSS *(10–100x faster, single config in `biome.json`)*
+5. **Frontend Framework**: Next.js Pages Router *(App Router not yet adopted — GROWI predates its stability)*
+6. **Named Exports**: Prefer named exports (except Next.js pages)
+7. **Test Co-location**: Place test files next to source files
+8. **Type Safety**: Use strict TypeScript throughout
+9. **Changeset**: Use `npx changeset` for version management
 
 ## Before Committing
 
@@ -132,6 +125,6 @@ pnpm run build
 ---
 
 For detailed information, refer to:
-- **Rules**: `.claude/rules/` (coding standards)
-- **Skills**: `.claude/skills/` (technical knowledge)
+- **Rules**: `.claude/rules/` (always loaded — coding standards, project structure)
+- **Skills**: `.claude/skills/` (on-demand — app-specific patterns)
 - **Package docs**: `apps/*/CLAUDE.md` (package-specific)