diff --git a/.agents/skills/creating-issues-and-prs/SKILL.md b/.agents/skills/creating-issues-and-prs/SKILL.md new file mode 100644 index 00000000000..03a03b2a098 --- /dev/null +++ b/.agents/skills/creating-issues-and-prs/SKILL.md @@ -0,0 +1,10 @@ +--- +name: creating-issues-and-prs +description: Defines rules for creating Issues and Pull Requests on GitHub, including precautions when AI is used to create them. Triggered by phrases like "create issue", "create pull request", or "create PR". +--- + +# creating-issues-and-prs + +This is the Codex entrypoint for the canonical rules regarding creating Issues and Pull Requests on GitHub, especially when AI is involved. + +Read and follow [.claude/skills/creating-issues-and-prs/SKILL.md](../../../.claude/skills/creating-issues-and-prs/SKILL.md). Treat that file and its `references/` directory (if present) as the source of truth. diff --git a/.agents/skills/shipping-misskey-change/SKILL.md b/.agents/skills/shipping-misskey-change/SKILL.md new file mode 100644 index 00000000000..700e6825e12 --- /dev/null +++ b/.agents/skills/shipping-misskey-change/SKILL.md @@ -0,0 +1,10 @@ +--- +name: shipping-misskey-change +description: Use at every finish moment of a Misskey change, before committing, opening a PR, merging, or handing work back, especially when validation, SPDX, locale safety, migrations, misskey-js generation, or CHANGELOG checks may apply. +--- + +# shipping-misskey-change + +This is the Codex entrypoint for the canonical Misskey pre-ship checklist. + +Read and follow [.claude/skills/shipping-misskey-change/SKILL.md](../../../.claude/skills/shipping-misskey-change/SKILL.md). Treat that file and its `references/` directory as the source of truth. diff --git a/.agents/skills/working-on-backend/SKILL.md b/.agents/skills/working-on-backend/SKILL.md new file mode 100644 index 00000000000..491b015185e --- /dev/null +++ b/.agents/skills/working-on-backend/SKILL.md @@ -0,0 +1,10 @@ +--- +name: working-on-backend +description: Use whenever editing or adding code under `packages/backend/`, including REST API endpoints, NestJS services/modules, TypeORM entities, migrations, backend tests, misskey-js generation, or backend validation commands. +--- + +# working-on-backend + +This is the Codex entrypoint for the canonical Misskey backend skill. + +Read and follow [.claude/skills/working-on-backend/SKILL.md](../../../.claude/skills/working-on-backend/SKILL.md). Treat that file and its `references/` directory as the source of truth. diff --git a/.agents/skills/working-on-frontend/SKILL.md b/.agents/skills/working-on-frontend/SKILL.md new file mode 100644 index 00000000000..59be8cfe992 --- /dev/null +++ b/.agents/skills/working-on-frontend/SKILL.md @@ -0,0 +1,10 @@ +--- +name: working-on-frontend +description: Use whenever editing or adding code under `packages/frontend/`, Vue SFCs, SCSS Modules, Storybook stories, or frontend-facing UI text in `locales/ja-JP.yml`. +--- + +# working-on-frontend + +This is the Codex entrypoint for the canonical Misskey frontend skill. + +Read and follow [.claude/skills/working-on-frontend/SKILL.md](../../../.claude/skills/working-on-frontend/SKILL.md). Treat that file and its `references/` directory as the source of truth. diff --git a/.claude/.gitignore b/.claude/.gitignore new file mode 100644 index 00000000000..67de78be55d --- /dev/null +++ b/.claude/.gitignore @@ -0,0 +1,2 @@ +/settings.local.json +/.credentials.json diff --git a/.claude/THIRD_PARTY_LICENSES.md b/.claude/THIRD_PARTY_LICENSES.md new file mode 100644 index 00000000000..0fc5df629c6 --- /dev/null +++ b/.claude/THIRD_PARTY_LICENSES.md @@ -0,0 +1,76 @@ +# Third-Party Licenses (`.claude/`) + +`.claude/` 配下に取り込まれているサードパーティ由来コンポーネントのライセンス・出典情報をまとめる。Misskey 本体は AGPL-3.0-only だが、本ディレクトリ内には MIT ライセンスのファイルが含まれている。各ファイル冒頭にも `SPDX-License-Identifier` と出典コメントを併記している。 + +最終更新: 2026-05-11 + +--- + +## 1. everything-claude-code (ECC) + +- 上流リポジトリ: +- 取り込んだバージョン: v2.0.0-rc.1 +- ライセンス: **MIT** +- Copyright: Copyright (c) 2026 Affaan Mustafa + +### 取り込んだファイル + +| `.claude/` 内のパス | 上流パス | 上流由来 | Misskey での改変 | +|---|---|---|---| +| `skills/context-budget/SKILL.md` | `skills/context-budget/SKILL.md` | ECC | description を日本語化、Misskey 固有メモを追記 | +| `commands/harness-audit.md` | `commands/harness-audit.md` | ECC | scripts 依存の自動採点を、Claude が `pnpm`/`git`/`grep` で手動採点する版に書き換え。Misskey 固有の評価軸 (SPDX / endpoint-list / migration / locales) を組み込み | +| `commands/quality-gate.md` | `commands/quality-gate.md` | ECC | 言語自動判定を排除し Misskey 固定 pipeline (`pnpm` + tsgo + ESLint + Vitest) に。Prettier/Biome フェーズを削除 | + +### MIT License (full text) + +``` +MIT License + +Copyright (c) 2026 Affaan Mustafa + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +``` + +### 上流 LICENSE ファイル + + + +--- + +## 2. AGPL コードベースとの互換性 + +Misskey 本体は **AGPL-3.0-only** で配布されているが、`.claude/` 配下の MIT ライセンスファイルはそのまま MIT として残している。 + +- MIT は permissive ライセンスで、AGPL を含む copyleft ライセンスのプロジェクトに **取り込み・再配布が許される** +- MIT が要求する条件 (copyright notice + license text の保持) を本ファイル + 各ファイル冒頭の SPDX/出典コメントで満たしている +- Misskey 全体の配布物としては AGPL-3.0-only で扱われるが、`.claude/` 配下の MIT ファイルは個別に MIT として識別可能 + +`.ts` / `.js` / `.vue` / `.scss` の SPDX 義務化 ([AGENTS.md](../AGENTS.md) の「絶対にやってはいけない事」§コード・データ関連) は Misskey 本体コード向けで、`.claude/` 配下の `.md` / `.sh` には適用されない。 + +--- + +## 3. 新規追加時の手順 + +`.claude/` に新たにサードパーティ由来のファイルを取り込む際は: + +1. ライセンスを確認 (互換性: MIT / Apache-2.0 / BSD は OK、GPL/AGPL は要相談) +2. 各ファイル冒頭に SPDX ヘッダ + 出典コメントを追加 +3. 本ファイル §1 のテーブルに 1 行追記 +4. 必要なら新しいセクションでライセンス全文を同梱 +5. 本ファイルへの導線を確認 (`.claude/skills/README.md` / `.claude/commands/README.md` 等の各 README から本ファイルへリンクされている)。なお [CLAUDE.md](../CLAUDE.md) が `.claude/` 配下全体を「Claude Code 固有の補助」として案内しており本ファイルもそこに含まれる。CLAUDE.md は `@AGENTS.md` を取り込むだけなので AGENTS.md への個別追記は不要 diff --git a/.claude/agents/README.md b/.claude/agents/README.md new file mode 100644 index 00000000000..cf1032d6325 --- /dev/null +++ b/.claude/agents/README.md @@ -0,0 +1,31 @@ +# `.claude/agents/` — プロジェクト固有のサブエージェント + +Misskey の特定領域に特化したレビュー / 調査エージェントを `.claude/agents/.md` 形式で配置する。 + +frontmatter (`name` + `description` + `tools`) は、Claude が **自動でエージェントを呼び出すか判断する** 唯一の手がかりになる。`description` は **起動判断に効くドメイン・パス・ファイル種別・固有チェックに絞って簡潔に** 書く (動詞 + 対象 + トリガー条件)。本文 checklist 項目を網羅的に列挙するのではなく、他の reviewer と区別できる高シグナル語を選ぶ。 + +実装済エージェントの一覧は本ファイルでは管理しない (腐敗するため)。各 `.md` の frontmatter が自己説明として機能する。 + +## 他のレビュー手段との使い分け + +レビュー面を増やしすぎないよう、役割を分ける: + +- **この `.claude/agents/` の 2 つ**: backend endpoint / Vue SFC の **Misskey 固有・機械的チェック** (endpoint-list 登録漏れ・misskey-js 再生成漏れ・ja-JP.yml 限定・SPDX 形式・Storybook 併設 等)。別コンテキストで差分を機械走査する価値がある領域に限定する +- **`pr-review-toolkit` プラグイン (code-reviewer / silent-failure-hunter 等)**: 言語非依存の一般的なコード品質・バグ・設計レビュー。Misskey 固有規約は見ない +- **`working-on-*` skill の checklist**: コードを **書いている最中** の自己チェック (レビュー専用ではなく実装ガイド) + +Misskey 固有規約の機械チェックは本 agent、一般品質は pr-review-toolkit、実装中ガイドは skill、と棲み分ける。 + +## 構成方針 + +- `tools` は **編集権限なし** (Edit/Write を渡さない) に絞り、PR baseline (`git merge-base origin/develop HEAD`) との差分から自動的にレビュー対象を抽出する設計 +- 差分抽出は `git merge-base origin/develop HEAD` を baseline にする (PR / ブランチ全体を見るため)。`git diff HEAD` 単体は **未コミット差分しか取れず、コミット済の PR では空になって誤判定する** ので使わない +- `description` は呼び出し判断の手がかりであると同時に、(呼ばれなくても) Task ツール起動のたびに常時ロードされる。**他で代替できない高シグナルなトリガー語に絞って簡潔に** 書く (汎用 reviewer と被る語や冗長な列挙は context-budget 上の overhead になるだけで発見性に寄与しない)。健全性は [/harness-audit](../commands/harness-audit.md) / [context-budget skill](../skills/context-budget/SKILL.md) で確認できる +- 規約の **正本は `.claude/skills/*/references/` 側**。agent の checklist はその **派生コピー** (subagent が skill を読まなくても動くよう自己完結させる)。規約を変えるときは references を先に直し agent を追従させる ── 両者の食い違いは同期漏れなので references を正とする + +## 新規エージェントを追加する場合 + +- `.claude/agents/.md` に YAML frontmatter (`name` / `description` / `tools`) と本文 Markdown を書く +- `description` は呼び出し判断に使われるため、対象ドメイン・主要チェック項目・トリガー条件を挙げる。ただし常時ロードされるので **高シグナル語に絞って簡潔に** (構成方針の該当項目を参照) +- レビュー専門なら `tools: Read, Grep, Glob, Bash` に絞る (Edit/Write を渡さない)。**`Bash` は任意のシェルコマンドを実行できる強力な権限である点に注意**: レビュー用途では `git diff` / `git ls-files` / `grep` / `sed` 等の **読み取り系コマンドに限定して使う** こと。書き込み・削除・ネットワーク送信を伴う操作は本文中の例示・指示に含めないこと (エージェント本文がガードレールになる) +- 主要参照ファイルへのリンクは、各エージェント markdown からの相対パスで貼る (`../../packages/backend/...` のような形)。絶対パスは contributor のホームディレクトリ依存になるので使わない diff --git a/.claude/agents/misskey-api-reviewer.md b/.claude/agents/misskey-api-reviewer.md new file mode 100644 index 00000000000..0d02c9fbffd --- /dev/null +++ b/.claude/agents/misskey-api-reviewer.md @@ -0,0 +1,169 @@ +--- +name: misskey-api-reviewer +description: Misskey backend の REST API エンドポイント (packages/backend/src/server/api/endpoints/) 追加・変更を機械レビューする。endpoint-list 登録漏れ・misskey-js 再生成漏れ・meta/paramDef/UUID/SPDX を検査。backend API を変更した PR レビューで呼ぶ。 +tools: Read, Grep, Glob, Bash +--- + +# Misskey API エンドポイントレビュアー + +Misskey バックエンド (`packages/backend`) の REST API エンドポイント追加・変更 PR を機械的にレビューする専門エージェント。規約の **正本** は [.claude/skills/working-on-backend/references/tasks/adding-api-endpoint.md](../skills/working-on-backend/references/tasks/adding-api-endpoint.md) と [.claude/skills/working-on-backend/references/knowledge/api-meta-paramdef.md](../skills/working-on-backend/references/knowledge/api-meta-paramdef.md)。本エージェントはそれを review-mode から機械チェックする mirror。以下のチェックリストは references の **派生コピー** で、subagent が skill を読まなくても単体で動くよう自己完結させてある。規約を変えるときは **references を先に直し、本ファイルを追従させる** (正本は references。両者が食い違うのは同期漏れ)。個別のチェックで判断に迷ったら、該当する references ファイルを Read して確認してよい。 + +## 役割 + +`packages/backend/src/server/api/endpoints/` 配下の `.ts` 変更を対象に、規約逸脱・登録漏れ・型自動生成漏れ・テスト不足を抽出する。良い点には触れず、改善が必要な箇所のみ報告する。 + +## レビュー対象の特定 + +呼び出し元から明示的にファイルが渡されたらそれを優先する。渡されなかった場合は **PR / ブランチ全体の差分** を取得する (未コミット差分のみではないことに注意)。 + +```bash +BASE=$(git merge-base origin/develop HEAD) +{ git diff --name-only "$BASE"...HEAD; git diff --name-only HEAD; git ls-files --others --exclude-standard; } \ + | sort -u \ + | grep -E '^packages/backend/src/server/api/endpoints/.*\.ts$' +``` + +`origin/develop` が無い環境では `develop` または `master` にフォールバックする。 + +加えて以下も同じ baseline で差分対象に含める: + +- `packages/backend/src/server/api/endpoint-list.ts` +- `packages/backend/test/e2e/**` (とくに `endpoints.ts` と `.ts`) +- `packages/misskey-js/src/autogen/**` +- `CHANGELOG.md` + +差分対象が空なら「レビュー対象の API エンドポイント変更なし」と短く報告して終了。 + +## チェックリスト + +### 1. SPDX ヘッダー (Critical) + +新規 `.ts` ファイル冒頭に以下があるか: + +``` +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ +``` + +欠落すると CI の `spdx` ジョブが落ちる。 + +### 2. `meta` の必須・推奨フィールド (Major) + +[endpoints.ts の型定義](../../packages/backend/src/server/api/endpoints.ts) を真とする。 + +- `tags`: OpenAPI タグ (機能領域)。 +- `requireCredential`: 明示必須 (boolean)。 +- `kind`: OAuth scope。`requireCredential: true` のとき必須 (`read:account` / `write:notes` 等)。 +- `requireModerator` / `requireAdmin`: 権限制限が要るか。 +- `prohibitMoved`: 移行済アカウントを拒否するか (write 系で要検討)。 +- `limit`: レート制限 `{ duration, max, key?, minInterval? }`。書き込み系 / コスト高い処理で未指定なら指摘。 +- `errors`: エラー定義。各要素に `message` / `code` / `id` (UUID v4) が揃っているか。 +- `res`: JSON Schema または `ref: ''`。各プロパティに `optional` / `nullable` が **明示** されているか。 +- `requireFile` / `secure` / `allowGet` / `cacheSec` / `description`: 該当するエンドポイントで使い分けているか。 + +### 3. `meta.errors` の UUID 検証 (Critical) + +各 `errors[*].id` が: + +1. UUID v4 形式 (`xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx`) か +2. 既存エンドポイントの `id` と重複していないか + +重複検査: + +```bash +grep -rn "id: '<生成された UUID>'" packages/backend/src/server/api/endpoints/ +``` + +新規エンドポイントの全 `id` を抽出して衝突を確認する。 + +### 4. `paramDef` (Major) + +- JSON Schema 形式 (`type: 'object'`, `properties`, `required`) +- ID 文字列は `format: 'misskey:id'` +- `required` 配列で必須プロパティを明示 +- `as const` または `as const satisfies Schema` で型推論を効かせる (既存実装は前者多数。`as const` 自体が無く `Schema` 型注釈もない場合のみ指摘) + +### 5. エンドポイント実装本体 (Major) + +- `Endpoint` を継承しているか。 +- `@Injectable()` デコレータ + `export default class` 形式か (`// eslint-disable-line import/no-default-export` が必要)。 +- DI は `@Inject(DI.xxx)` 形式か。 +- **クライアントに返すべき API エラーは `throw new ApiError(meta.errors.)`** ([error.ts](../../packages/backend/src/server/api/error.ts) 参照)。`meta.errors` で定義したエラーケースを `throw new Error(...)` で投げているなら指摘する。 +- 防御的アサーション・「起きるはずがない」内部不整合・テスト用 ENV ガード等の **想定外フェイルファスト** は `throw new Error('...')` で構わない。既存実装でも `admin/reset-password.ts` などが採用しているパターン (例: `cannot reset password of root`)。`meta.errors` に対応がない `throw new Error` を一律で指摘しない。 +- 同期 `throw` は許容。非同期処理での例外伝搬を確認する。 + +### 6. ★ `endpoint-list.ts` への登録 (Critical) + +最も忘れやすい。**忘れると 404**。[endpoint-list.ts](../../packages/backend/src/server/api/endpoint-list.ts) に 1 行追加されているか: + +```ts +export * as '/' from './endpoints//.js'; +``` + +新規エンドポイントを抽出し、各々が `endpoint-list.ts` に存在するか grep で確認する: + +```bash +grep -F "'/'" packages/backend/src/server/api/endpoint-list.ts +``` + +**並び順の補足**: ファイル全体は厳密なアルファベット順では並んでおらず、同カテゴリ内 (`admin/queue/*` など) でも追加された経緯どおりの順になっている箇所が多い。**順序逸脱は指摘根拠にしない** (誤検知の元)。「行が存在するか」のみを Critical 観点として扱う。 + +### 7. `misskey-js` 再生成 (Critical) + +`meta` / `paramDef` / `res` を変更したら、PR / ブランチに `packages/misskey-js/src/autogen/` 配下の差分が含まれているか確認する: + +```bash +BASE=$(git merge-base origin/develop HEAD) +git diff --name-only "$BASE"...HEAD -- packages/misskey-js/src/autogen/ +``` + +差分ゼロなら `pnpm build-misskey-js-with-types` の実行漏れ。CI の `check-misskey-js-autogen` ワークフローで必ず落ちるため Critical 扱い。 + +### 8. e2e テスト (Major) + +[test/e2e/endpoints.ts](../../packages/backend/test/e2e/endpoints.ts) または `test/e2e/.ts` (`note.ts`, `users.ts` 等) 配下に、対応する `api('/', ...)` 呼び出しを含む `test(...)` ケースが追加されているか確認する。複雑な分岐 (権限チェック・エラーケース) の網羅も確認する。 + +**describe ラベルの形式は問わない**: 既存テストは `describe('Note', () => { test('投稿できる', ...) })` のように人間可読ラベルで構造化されており、`/` 形式の describe は使われていない。describe 名の規約違反としては指摘しない。 + +### 9. CHANGELOG エントリ (Minor) + +ユーザー影響がある (新エンドポイント / 既存挙動変更) 場合、`CHANGELOG.md` の `## Unreleased` → `### Server` に 1 行追加されているか確認する。 + +``` +- Feat: /api// を追加 +``` + +純粋な内部リファクタなら不要。 + +## 出力形式 + +優先度別に以下のフォーマットで出力する。 + +``` +## 🔴 Critical +- packages/backend/src/server/api/endpoints/foo/bar.ts:23 + meta.errors.fooError.id が UUID v4 形式ではない (実値: 'xxx-xxx')。 + `node -e "console.log(crypto.randomUUID())"` で再生成すること。 + +## 🟡 Major +- ... + +## 🔵 Minor +- ... +``` + +問題のないチェック項目には触れない。全項目クリアなら `✅ レビュー観点上の指摘なし` と短く返す。 + +## 参照 + +- [.claude/skills/working-on-backend/references/tasks/adding-api-endpoint.md](../skills/working-on-backend/references/tasks/adding-api-endpoint.md) — 実装側の手順 +- [.claude/skills/working-on-backend/references/knowledge/api-meta-paramdef.md](../skills/working-on-backend/references/knowledge/api-meta-paramdef.md) — meta / paramDef / res の完全早見表 + 落とし穴 +- [.claude/skills/working-on-backend/references/knowledge/endpoint-list.md](../skills/working-on-backend/references/knowledge/endpoint-list.md) — endpoint-list.ts 登録ガイド +- [endpoints.ts (meta/paramDef 型定義)](../../packages/backend/src/server/api/endpoints.ts) +- [endpoint-list.ts (★ 登録先)](../../packages/backend/src/server/api/endpoint-list.ts) +- [endpoint-base.ts (Endpoint 基底クラス)](../../packages/backend/src/server/api/endpoint-base.ts) +- [error.ts (ApiError)](../../packages/backend/src/server/api/error.ts) +- [test/e2e/endpoints.ts](../../packages/backend/test/e2e/endpoints.ts) +- [AGENTS.md](../../AGENTS.md) — SPDX / マイグレーション履歴 / CHANGELOG 書式などの最低限ルール (Codex / Copilot と共通) diff --git a/.claude/agents/vue-component-reviewer.md b/.claude/agents/vue-component-reviewer.md new file mode 100644 index 00000000000..e5788ff68c0 --- /dev/null +++ b/.claude/agents/vue-component-reviewer.md @@ -0,0 +1,178 @@ +--- +name: vue-component-reviewer +description: Misskey frontend の Vue 3 SFC (packages/frontend/src/components/ / pages/ の *.vue) 変更を機械レビューする。SPDX (HTML コメント)・Mk* 命名・i18n.ts/tsx・SCSS 変数・os.* 経由・a11y・Storybook 併設 (*.stories.impl.ts) を検査。frontend の .vue を変更した PR レビューで呼ぶ。 +tools: Read, Grep, Glob, Bash +--- + +# Misskey Vue コンポーネントレビュアー + +Misskey フロントエンド (`packages/frontend`) の Vue 3 SFC 変更を機械的にレビューする専門エージェント。規約の **正本** は [.claude/skills/working-on-frontend/references/tasks/adding-mk-component.md](../skills/working-on-frontend/references/tasks/adding-mk-component.md) および同 `references/knowledge/` 配下の各ファイル。本エージェントはそれを review-mode から機械チェックする mirror。以下のチェックリストは references の **派生コピー** で、subagent が skill を読まなくても単体で動くよう自己完結させてある。規約を変えるときは **references を先に直し、本ファイルを追従させる** (正本は references。両者が食い違うのは同期漏れ)。個別のチェックで判断に迷ったら、該当する references ファイルを Read して確認してよい。 + +## 役割 + +`packages/frontend/src/components/` および `packages/frontend/src/pages/` 配下の `.vue` 変更を対象に、命名・i18n・スタイル・アクセシビリティ・Storybook 併設の規約逸脱を抽出する。良い点には触れず、改善が必要な箇所のみ報告する。 + +## レビュー対象の特定 + +呼び出し元から明示的にファイルが渡されたらそれを優先する。渡されなかった場合は **PR / ブランチ全体の差分** を取得する (未コミット差分のみではないことに注意)。 + +```bash +BASE=$(git merge-base origin/develop HEAD) +{ git diff --name-only "$BASE"...HEAD; git diff --name-only HEAD; git ls-files --others --exclude-standard; } \ + | sort -u \ + | grep -E '^packages/frontend/src/.*\.vue$' +``` + +`origin/develop` が無い環境では `develop` または `master` にフォールバックする。 + +`.ts` を一律で含めると本エージェントの守備範囲外 (composable / store / service 層) まで巻き込んで誤検知が増えるため、対象は `.vue` のみとし、Storybook 併設チェックのために以下を **別リスト** として追加する: + +- `locales/*.yml` (とくに `ja-JP.yml` 以外の変更は即 Critical) +- `packages/frontend/src/components/**/*.stories.impl.ts` +- `CHANGELOG.md` + +差分対象が空なら「レビュー対象の Vue コンポーネント変更なし」と短く報告して終了。 + +## チェックリスト + +### 1. SPDX ヘッダー (Critical) + +`.vue` ファイル冒頭は **HTML コメント形式** で必須: + +```html + +``` + +`/* ... */` (TS 形式) は禁止 (CI の `spdx` ジョブはコメント形式ではなく SPDX 文字列の有無のみを検査するため、形式が違っても CI は通るが、規約違反として指摘する)。形式の根拠は references/knowledge 側を参照。 + +### 2. 命名規約 (Major) + +- 共有 / 再利用コンポーネント (`packages/frontend/src/components/` 配下、サブディレクトリ含む) は `Mk` プレフィックス必須 (例: `MkButton.vue`, `global/MkAvatar.vue`, `grid/MkGrid.vue`)。 +- ページ固有のものは `pages/` 配下に置き、`Mk` プレフィックスは不要。 + +**補足:** ` + + +``` + +## ` + + +``` + +ポイント: + +- デフォルト値が必要なら `withDefaults(defineProps<{...}>(), { ... })` を使う (type-only のまま既定値を渡せる) +- `_selectable` は本文選択を許可する global utility class ([scss-modules.md](scss-modules.md) 参照) +- `` は Tabler icons。`v-if` 切り替えで variant 別アイコンを出すのは多用パターン + +### generic + 2 ブロック script + +参考: [MkInput.vue](../../../../../packages/frontend/src/components/MkInput.vue) + +型ジェネリックを取りつつ、その型計算や `type` エイリアス宣言を setup ブロックの中に書きたくない場合は、**型宣言用 ` + + +``` + +ポイント: + +- `generic="T extends string | number"` の制約を付けることで、`v-model` で渡された型が `string` / `number` 系に限定される +- 2 ブロック構成にする理由は **setup ブロック内では `export type` が書けない** から +- `MkSelect.vue` のような複雑な型エクスポートをするコンポーネントで多用される + +### `defineModel` で v-model 連動 + +参考: [MkSelect.vue](../../../../../packages/frontend/src/components/MkSelect.vue), [MkRadios.vue](../../../../../packages/frontend/src/components/MkRadios.vue) + +`defineModel` を使うと `props.modelValue` + `emit('update:modelValue', v)` の 2 行が 1 行に圧縮できる。 + +```vue + + + +``` + +ポイント: + +- `defineModel()` は **自動で `props.modelValue` と `emit('update:modelValue', v)` を生成** する。返り値は `Ref` なので `checked.value = ...` で書き換えると emit される +- `defineModel('foo')` のように引数を渡すと `v-model:foo` (`props.foo` + `emit('update:foo', v)`) の連動が作れる +- 新規ファイルの v-model 連動は原則として `defineModel` を使う (`props.modelValue` + `emit` の手書きは既存コードに残るのみ) + +### emit + 名前付き slot で外部から動作を差し込む + +下記は emit + 名前付き slot の典型パターンを示す**合成例** (特定ファイルの写しではない)。クリック時の処理を呼び出し元に委ねるパターン (確認 UI など)。なお [MkButton.vue](../../../../../packages/frontend/src/components/MkButton.vue) 自体は `(ev: 'click', payload: PointerEvent)` のみを emit する単機能ボタンで、この合成例とは構造が異なる。 + +```vue + + + +``` + +ポイント: + +- 名前付き slot (``) と無名 slot (``) は両方使ってよい +- `_panel` / `_button` / `_buttonPrimary` は global utility class なので、自前で同じスタイルを書かない +- `emit('ok')` 等の単純 emit は中継するだけにし、`os.confirm` などの実際の確認 UI 起動は呼び出し元の責務にする (テスト・差し替えしやすくするため) + +## a11y チェックリスト + +Misskey の PR レビューで頻繁に出る a11y 指摘をまとめた。新規 / 既存コンポーネントを編集する時は以下を満たす。 + +### クリック可能要素 + +#### 第一選択: ` +``` + +- `_button` global class はボタンの装飾を除去するリセット (背景/枠線なし + `cursor: pointer` + disabled cursor)。focus ring や ripple は**付かない** — ripple 付きのボタンが要るなら `MkButton.vue` コンポーネントを使う +- ` +``` + +`aria-label` の値も i18n 経由にする (英語直書きは禁止)。 + +**実情:** 現状コードベースでは `aria-label` の使用例自体が乏しい (アイコンの hover ヒントには `:title="i18n.ts..."` が使われるが、`title` は tooltip でありスクリーンリーダー向けラベルの代替にはならない)。このため aria-label は確立した慣習というより a11y 上の推奨ベストプラクティスとして書いている。新規でアイコンのみのボタンを足すなら付けるのが望ましい。 + +### `:disabled` と `aria-disabled` の整合 + +- 本物の `