review ピースに拡張: PR/ブランチ/現在の差分の3モード自動判定に対応

pr-review → review にリネームし、gather が入力テキストからモードを自動判定する。
ブランチ名の判定を git branch -a で確認する方式に強化、直近Nコミット指定に対応、
output contract にコミット履歴セクションを追加。
This commit is contained in:
nrslib 2026-02-24 13:11:31 +09:00
parent c44477dea0
commit cc7f73dc3e
20 changed files with 214 additions and 142 deletions

View File

@ -1,14 +0,0 @@
Gather PR information and produce a report for reviewers to reference.
**Do:**
1. Extract the PR number from the task ("PR #42", "#42", "pull/42", etc.)
2. Run `gh pr view {number}` to retrieve the PR title, description, and labels
3. Run `gh pr diff {number}` to retrieve the diff
4. Compile the list of changed files
5. Extract the purpose and requirements from the PR description
6. If linked Issues exist, retrieve them with `gh issue view {number}`
- Extract Issue numbers from "Closes #N", "Fixes #N", "Resolves #N" in the PR description
- Collect the Issue title, description, labels, and comments
**If no PR number is found:**
- Inspect the branch diff and identify the code under review

View File

@ -0,0 +1,42 @@
Gather information about the review target and produce a report for reviewers to reference.
## Auto-detect review mode
Analyze the task text and determine which mode to use.
### Mode 1: PR mode
**Trigger:** Task contains PR references like `#42`, `PR #42`, `pull/42`, or a URL with `/pull/`
**Steps:**
1. Extract the PR number
2. Run `gh pr view {number}` to get title, description, labels
3. Run `gh pr diff {number}` to get the diff
4. Compile the changed files list
5. Extract purpose and requirements from the PR description
6. If linked Issues exist, retrieve them with `gh issue view {number}`
- Extract Issue numbers from "Closes #N", "Fixes #N", "Resolves #N"
- Collect Issue title, description, labels, and comments
### Mode 2: Branch mode
**Trigger:** Task text matches a branch name found in `git branch -a`. This includes names with `/` (e.g., `feature/auth`) as well as simple names (e.g., `develop`, `release-v2`, `hotfix-login`). When unsure, verify with `git branch -a | grep {text}`.
**Steps:**
1. Determine the base branch (default: `main`, fallback: `master`)
2. Run `git log {base}..{branch} --oneline` to get commit history
3. Run `git diff {base}...{branch}` to get the diff
4. Compile the changed files list
5. Extract purpose from commit messages
6. If a PR exists for the branch, fetch it with `gh pr list --head {branch}`
### Mode 3: Current diff mode
**Trigger:** Task does not match Mode 1 or Mode 2 (e.g., "review current changes", "last 3 commits", "current diff")
**Steps:**
1. If the task specifies a count (e.g., "last N commits"), extract N. Otherwise default to N=1
2. Run `git diff` for unstaged changes and `git diff --staged` for staged changes
3. If both are empty, run `git diff HEAD~{N}` to get the diff for the last N commits
4. Run `git log --oneline -{N+10}` for commit context
5. Compile the changed files list
6. Extract purpose from recent commit messages
## Report requirements
- Regardless of mode, the output report must follow the same format
- Fill in what is available; mark unavailable sections as "N/A"
- Always include: review target overview, purpose, changed files, and the diff

View File

@ -13,7 +13,7 @@ Review the changes from a requirements fulfillment perspective.
## Judgment Procedure ## Judgment Procedure
1. Extract requirements one by one from the PR description and task 1. Extract requirements one by one from the review target report and task
2. For each requirement, identify the implementing code (file:line) 2. For each requirement, identify the implementing code (file:line)
3. Confirm that the code satisfies the requirement 3. Confirm that the code satisfies the requirement
4. Check for any changes not covered by the requirements 4. Check for any changes not covered by the requirements

View File

@ -1,29 +0,0 @@
```markdown
# PR Information
## PR Overview
| Field | Details |
|-------|---------|
| PR Number | #{number} |
| Title | {PR title} |
| Labels | {label list} |
## Purpose & Requirements
{Purpose and requirements extracted from the PR description}
## Linked Issues
{State "None" if no issues are linked}
### Issue #{number}: {Issue title}
- Labels: {label list}
- Description: {Summary of Issue body}
- Key comments: {Summary of relevant comments}
## Changed Files
| File | Type | Lines Changed |
|------|------|---------------|
| `{file path}` | Added/Modified/Deleted | +{added} -{removed} |
## Diff
{Output of gh pr diff}
```

View File

@ -7,7 +7,7 @@
{Summarize the result in 1-2 sentences} {Summarize the result in 1-2 sentences}
## Requirements Cross-Reference ## Requirements Cross-Reference
| # | Requirement (from PR) | Satisfied | Evidence (file:line) | | # | Requirement (from task) | Satisfied | Evidence (file:line) |
|---|----------------------|-----------|----------------------| |---|----------------------|-----------|----------------------|
| 1 | {requirement 1} | ✅/❌ | `src/file.ts:42` | | 1 | {requirement 1} | ✅/❌ | `src/file.ts:42` |

View File

@ -0,0 +1,37 @@
```markdown
# Review Target
## Overview
| Field | Details |
|-------|---------|
| Mode | PR / Branch / Current Diff |
| Source | PR #{number} / Branch `{name}` / Working tree |
| Title | {title or summary from commits} |
| Labels | {label list, or N/A} |
## Purpose & Requirements
{Purpose and requirements extracted from PR description, commit messages, or task text}
## Linked Issues
{State "N/A" if not applicable}
### Issue #{number}: {Issue title}
- Labels: {label list}
- Description: {Summary of Issue body}
- Key comments: {Summary of relevant comments}
## Commit History
{Include for Branch/Current Diff modes. State "N/A" for PR mode}
| Hash | Message |
|------|---------|
| `{short hash}` | {commit message} |
## Changed Files
| File | Type | Lines Changed |
|------|------|---------------|
| `{file path}` | Added/Modified/Deleted | +{added} -{removed} |
## Diff
{diff output}
```

View File

@ -36,7 +36,7 @@ piece_categories:
- structural-reform - structural-reform
🔍 Review: 🔍 Review:
pieces: pieces:
- pr-review - review
🧪 Testing: 🧪 Testing:
pieces: pieces:
- unit-test - unit-test

View File

@ -1,5 +1,5 @@
name: pr-review name: review
description: Multi-perspective PR Review - reviews a PR in parallel from 5 perspectives and outputs consolidated results description: Multi-perspective Code Review - reviews changes in parallel from 5 perspectives and outputs consolidated results
piece_config: piece_config:
provider_options: provider_options:
codex: codex:
@ -20,15 +20,15 @@ movements:
- Bash - Bash
- WebSearch - WebSearch
- WebFetch - WebFetch
instruction: gather-pr instruction: gather-review
output_contracts: output_contracts:
report: report:
- name: 00-pr-info.md - name: 00-review-target.md
format: pr-gather format: review-gather
rules: rules:
- condition: PR information gathered - condition: Review target information gathered
next: reviewers next: reviewers
- condition: PR number unidentifiable, insufficient info - condition: Cannot identify review target, insufficient info
next: ABORT next: ABORT
appendix: | appendix: |
Clarifications needed: Clarifications needed:
@ -167,12 +167,12 @@ movements:
## Review Results ## Review Results
{previous_response} {previous_response}
**This is a PR review-only piece.** Do NOT run tests or builds. **This is a review-only piece.** Do NOT run tests or builds.
Your role is to synthesize the review results and produce a final summary. Your role is to synthesize the review results and produce a final summary.
**Tasks:** **Tasks:**
1. Read all review reports in the Report Directory 1. Read all review reports in the Report Directory
- `00-pr-info.md` (PR information) - `00-review-target.md` (Review target information)
- `01-architecture-review.md` (Architecture review) - `01-architecture-review.md` (Architecture review)
- `02-security-review.md` (Security review) - `02-security-review.md` (Security review)
- `03-qa-review.md` (QA review) - `03-qa-review.md` (QA review)
@ -183,7 +183,7 @@ movements:
**Review Summary output contract:** **Review Summary output contract:**
```markdown ```markdown
# PR Review Summary # Review Summary
## Overall Verdict: APPROVE / REJECT ## Overall Verdict: APPROVE / REJECT
@ -212,7 +212,7 @@ movements:
- name: review-summary.md - name: review-summary.md
format: | format: |
```markdown ```markdown
# PR Review Summary # Review Summary
## Overall Verdict: APPROVE / REJECT ## Overall Verdict: APPROVE / REJECT

View File

@ -1,14 +0,0 @@
PR の情報を収集し、レビュアーが参照するレポートを作成してください。
**やること:**
1. タスクから PR 番号を抽出する("PR #42"、"#42"、"pull/42" 等)
2. `gh pr view {番号}` で PR のタイトル・説明・ラベルを取得
3. `gh pr diff {番号}` で差分を取得
4. 変更ファイル一覧をまとめる
5. PR の説明から要件・目的を抽出する
6. リンクされた Issue があれば `gh issue view {番号}` で取得する
- PR 説明内の "Closes #N"、"Fixes #N"、"Resolves #N" 等からIssue番号を抽出
- Issue のタイトル・説明・ラベル・コメントを収集する
**PR番号が見つからない場合:**
- ブランチの差分を確認し、レビュー対象のコードを特定する

View File

@ -0,0 +1,42 @@
レビュー対象の情報を収集し、レビュアーが参照するレポートを作成してください。
## レビューモードの自動判定
タスクテキストを分析し、適切なモードを判定してください。
### モード1: PRモード
**判定条件:** タスクに `#42``PR #42``pull/42`、または `/pull/` を含むURL がある
**手順:**
1. PR番号を抽出する
2. `gh pr view {番号}` でタイトル・説明・ラベルを取得
3. `gh pr diff {番号}` で差分を取得
4. 変更ファイル一覧をまとめる
5. PRの説明から要件・目的を抽出する
6. リンクされた Issue があれば `gh issue view {番号}` で取得する
- "Closes #N"、"Fixes #N"、"Resolves #N" 等からIssue番号を抽出
- Issue のタイトル・説明・ラベル・コメントを収集する
### モード2: ブランチモード
**判定条件:** タスクテキストが `git branch -a` の出力に含まれるブランチ名と一致する場合。`feature/auth` のように `/` を含むものだけでなく、`develop``release-v2``hotfix-login` 等のブランチ名も対象。判定に迷ったら `git branch -a | grep {テキスト}` で確認する。
**手順:**
1. ベースブランチを特定する(デフォルト: `main`、フォールバック: `master`
2. `git log {base}..{branch} --oneline` でコミット履歴を取得
3. `git diff {base}...{branch}` で差分を取得
4. 変更ファイル一覧をまとめる
5. コミットメッセージから目的を抽出する
6. ブランチに対応するPRがあれば `gh pr list --head {branch}` で取得する
### モード3: 現在の差分モード
**判定条件:** モード1・モード2に該当しない場合例: "今の差分を見て"、"現在の変更をレビュー"、"直近のコミット"、"直近3コミット"
**手順:**
1. タスクテキストに件数指定がある場合("直近Nコミット"、"last N commits"等はNを抽出する。なければ N=1
2. `git diff` でステージされていない変更、`git diff --staged` でステージ済み変更を取得
3. 両方とも空の場合は `git diff HEAD~{N}` で直近Nコミット分の差分を取得
4. `git log --oneline -{N+10}` でコミットコンテキストを取得
5. 変更ファイル一覧をまとめる
6. 直近のコミットメッセージから目的を抽出する
## レポート要件
- モードに関わらず、出力レポートは同じフォーマットに従う
- 取得可能な項目を埋め、取得できない項目は「N/A」と記載する
- 必須項目: レビュー対象概要、目的、変更ファイル一覧、差分

View File

@ -13,7 +13,7 @@
## 判定手順 ## 判定手順
1. PR の説明・タスクから要件を1つずつ抽出する 1. レビュー対象レポート・タスクから要件を1つずつ抽出する
2. 各要件について、実装されたコード(ファイル:行)を特定する 2. 各要件について、実装されたコード(ファイル:行)を特定する
3. コードが要件を満たしていることを確認する 3. コードが要件を満たしていることを確認する
4. 要求にない変更がないかチェックする 4. 要求にない変更がないかチェックする

View File

@ -1,29 +0,0 @@
```markdown
# PR 情報
## PR 概要
| 項目 | 内容 |
|------|------|
| PR番号 | #{番号} |
| タイトル | {PRタイトル} |
| ラベル | {ラベル一覧} |
## 目的・要件
{PRの説明から抽出した目的と要件}
## リンクされた Issue
{Issue がない場合は「なし」と記載}
### Issue #{番号}: {Issueタイトル}
- ラベル: {ラベル一覧}
- 説明: {Issue本文の要約}
- 主要コメント: {関連するコメントの要約}
## 変更ファイル一覧
| ファイル | 種別 | 変更行数 |
|---------|------|---------|
| `{ファイルパス}` | 追加/変更/削除 | +{追加} -{削除} |
## 差分
{gh pr diff の出力}
```

View File

@ -7,7 +7,7 @@
{1-2文で結果を要約} {1-2文で結果を要約}
## 要件照合 ## 要件照合
| # | 要件(PRから抽出) | 充足 | 根拠(ファイル:行) | | # | 要件(タスクから抽出) | 充足 | 根拠(ファイル:行) |
|---|-------------------|------|-------------------| |---|-------------------|------|-------------------|
| 1 | {要件1} | ✅/❌ | `src/file.ts:42` | | 1 | {要件1} | ✅/❌ | `src/file.ts:42` |

View File

@ -0,0 +1,37 @@
```markdown
# レビュー対象
## 概要
| 項目 | 内容 |
|------|------|
| モード | PR / ブランチ / 現在の差分 |
| ソース | PR #{番号} / ブランチ `{名前}` / ワーキングツリー |
| タイトル | {タイトルまたはコミットの要約} |
| ラベル | {ラベル一覧、または N/A} |
## 目的・要件
{PR説明、コミットメッセージ、またはタスクテキストから抽出した目的と要件}
## リンクされた Issue
{該当しない場合は「N/A」と記載}
### Issue #{番号}: {Issueタイトル}
- ラベル: {ラベル一覧}
- 説明: {Issue本文の要約}
- 主要コメント: {関連するコメントの要約}
## コミット履歴
{ブランチ/現在の差分モードの場合に記載。PRモードの場合は「N/A」}
| ハッシュ | メッセージ |
|---------|-----------|
| `{short hash}` | {コミットメッセージ} |
## 変更ファイル一覧
| ファイル | 種別 | 変更行数 |
|---------|------|---------|
| `{ファイルパス}` | 追加/変更/削除 | +{追加} -{削除} |
## 差分
{差分出力}
```

View File

@ -36,7 +36,7 @@ piece_categories:
- structural-reform - structural-reform
🔍 レビュー: 🔍 レビュー:
pieces: pieces:
- pr-review - review
🧪 テスト: 🧪 テスト:
pieces: pieces:
- unit-test - unit-test

View File

@ -1,5 +1,5 @@
name: pr-review name: review
description: PR多角レビュー - 5つの観点から並列にPRをレビューし、統合結果を出力する description: 多角レビュー - 5つの観点から並列にコード変更をレビューし、統合結果を出力する
piece_config: piece_config:
provider_options: provider_options:
codex: codex:
@ -20,15 +20,15 @@ movements:
- Bash - Bash
- WebSearch - WebSearch
- WebFetch - WebFetch
instruction: gather-pr instruction: gather-review
output_contracts: output_contracts:
report: report:
- name: 00-pr-info.md - name: 00-review-target.md
format: pr-gather format: review-gather
rules: rules:
- condition: PR情報の収集完了 - condition: レビュー対象の情報収集完了
next: reviewers next: reviewers
- condition: PR番号が特定できない、情報不足 - condition: レビュー対象を特定できない、情報不足
next: ABORT next: ABORT
appendix: | appendix: |
確認事項: 確認事項:
@ -167,12 +167,12 @@ movements:
## レビュー結果 ## レビュー結果
{previous_response} {previous_response}
**これはPRレビュー専用ピースです。** テスト実行やビルドは行わないでください。 **これはレビュー専用ピースです。** テスト実行やビルドは行わないでください。
レビュー結果を統合し、最終サマリーを作成する役割です。 レビュー結果を統合し、最終サマリーを作成する役割です。
**やること:** **やること:**
1. Report Directory内の全レビューレポートを読む 1. Report Directory内の全レビューレポートを読む
- `00-pr-info.md`PR情報) - `00-review-target.md`(レビュー対象情報)
- `01-architecture-review.md`(アーキテクチャレビュー) - `01-architecture-review.md`(アーキテクチャレビュー)
- `02-security-review.md`(セキュリティレビュー) - `02-security-review.md`(セキュリティレビュー)
- `03-qa-review.md`QAレビュー - `03-qa-review.md`QAレビュー
@ -185,7 +185,7 @@ movements:
- name: review-summary.md - name: review-summary.md
format: | format: |
```markdown ```markdown
# PRレビューサマリー # レビューサマリー
## 総合判定: APPROVE / REJECT ## 総合判定: APPROVE / REJECT

View File

@ -281,11 +281,11 @@ describe('Piece Loader IT: piece config validation', () => {
expect(movementNames).toContain(config!.initialMovement); expect(movementNames).toContain(config!.initialMovement);
}); });
it('should preserve edit property on movements (pr-review has no edit: true)', () => { it('should preserve edit property on movements (review has no edit: true)', () => {
const config = loadPiece('pr-review', testDir); const config = loadPiece('review', testDir);
expect(config).not.toBeNull(); expect(config).not.toBeNull();
// pr-review: no movement should have edit: true // review: no movement should have edit: true
for (const movement of config!.movements) { for (const movement of config!.movements) {
expect(movement.edit).not.toBe(true); expect(movement.edit).not.toBe(true);
if (movement.parallel) { if (movement.parallel) {

View File

@ -292,7 +292,7 @@ describe('Piece Patterns IT: magi piece', () => {
}); });
}); });
describe('Piece Patterns IT: pr-review piece', () => { describe('Piece Patterns IT: review piece', () => {
let testDir: string; let testDir: string;
beforeEach(() => { beforeEach(() => {
@ -306,7 +306,7 @@ describe('Piece Patterns IT: pr-review piece', () => {
}); });
it('should complete: gather → reviewers (all approved) → supervise → COMPLETE', async () => { it('should complete: gather → reviewers (all approved) → supervise → COMPLETE', async () => {
const config = loadPiece('pr-review', testDir); const config = loadPiece('review', testDir);
expect(config).not.toBeNull(); expect(config).not.toBeNull();
setMockScenario([ setMockScenario([
@ -328,7 +328,7 @@ describe('Piece Patterns IT: pr-review piece', () => {
}); });
it('should verify no movements have edit: true', () => { it('should verify no movements have edit: true', () => {
const config = loadPiece('pr-review', testDir); const config = loadPiece('review', testDir);
expect(config).not.toBeNull(); expect(config).not.toBeNull();
for (const movement of config!.movements) { for (const movement of config!.movements) {

View File

@ -166,7 +166,7 @@ piece_categories:
- nested - nested
Review: Review:
pieces: pieces:
- pr-review - review
- e2e-test - e2e-test
show_others_category: true show_others_category: true
others_category_name: Others others_category_name: Others
@ -200,7 +200,7 @@ others_category_name: Unclassified
{ name: 'Child', pieces: ['nested'], children: [] }, { name: 'Child', pieces: ['nested'], children: [] },
], ],
}, },
{ name: 'Review', pieces: ['pr-review', 'e2e-test'], children: [] }, { name: 'Review', pieces: ['review', 'e2e-test'], children: [] },
], ],
}, },
]); ]);
@ -212,7 +212,7 @@ others_category_name: Unclassified
{ name: 'Child', pieces: ['nested'], children: [] }, { name: 'Child', pieces: ['nested'], children: [] },
], ],
}, },
{ name: 'Review', pieces: ['pr-review', 'e2e-test'], children: [] }, { name: 'Review', pieces: ['review', 'e2e-test'], children: [] },
]); ]);
expect(config!.userPieceCategories).toEqual([ expect(config!.userPieceCategories).toEqual([
{ name: 'Main', pieces: ['custom'], children: [] }, { name: 'Main', pieces: ['custom'], children: [] },
@ -230,14 +230,14 @@ others_category_name: Unclassified
piece_categories: piece_categories:
: :
pieces: pieces:
- pr-review - review
- e2e-test - e2e-test
`); `);
const config = getPieceCategories(testDir); const config = getPieceCategories(testDir);
expect(config).not.toBeNull(); expect(config).not.toBeNull();
expect(config!.pieceCategories).toEqual([ expect(config!.pieceCategories).toEqual([
{ name: 'レビュー', pieces: ['pr-review', 'e2e-test'], children: [] }, { name: 'レビュー', pieces: ['review', 'e2e-test'], children: [] },
]); ]);
}); });
@ -249,7 +249,7 @@ piece_categories:
- default - default
Review: Review:
pieces: pieces:
- pr-review - review
show_others_category: true show_others_category: true
others_category_name: Others others_category_name: Others
`); `);
@ -263,11 +263,11 @@ others_category_name: Unclassified
expect(config).not.toBeNull(); expect(config).not.toBeNull();
expect(config!.pieceCategories).toEqual([ expect(config!.pieceCategories).toEqual([
{ name: 'Main', pieces: ['default'], children: [] }, { name: 'Main', pieces: ['default'], children: [] },
{ name: 'Review', pieces: ['pr-review'], children: [] }, { name: 'Review', pieces: ['review'], children: [] },
]); ]);
expect(config!.builtinPieceCategories).toEqual([ expect(config!.builtinPieceCategories).toEqual([
{ name: 'Main', pieces: ['default'], children: [] }, { name: 'Main', pieces: ['default'], children: [] },
{ name: 'Review', pieces: ['pr-review'], children: [] }, { name: 'Review', pieces: ['review'], children: [] },
]); ]);
expect(config!.userPieceCategories).toEqual([]); expect(config!.userPieceCategories).toEqual([]);
expect(config!.hasUserCategories).toBe(false); expect(config!.hasUserCategories).toBe(false);
@ -375,7 +375,7 @@ describe('buildCategorizedPieces', () => {
const allPieces = createPieceMap([ const allPieces = createPieceMap([
{ name: 'custom', source: 'user' }, { name: 'custom', source: 'user' },
{ name: 'default', source: 'builtin' }, { name: 'default', source: 'builtin' },
{ name: 'pr-review', source: 'builtin' }, { name: 'review', source: 'builtin' },
{ name: 'extra', source: 'builtin' }, { name: 'extra', source: 'builtin' },
]); ]);
const config = { const config = {
@ -386,13 +386,13 @@ describe('buildCategorizedPieces', () => {
pieces: [], pieces: [],
children: [ children: [
{ name: 'Quick Start', pieces: ['default'], children: [] }, { name: 'Quick Start', pieces: ['default'], children: [] },
{ name: 'Review', pieces: ['pr-review'], children: [] }, { name: 'Review', pieces: ['review'], children: [] },
], ],
}, },
], ],
builtinPieceCategories: [ builtinPieceCategories: [
{ name: 'Quick Start', pieces: ['default'], children: [] }, { name: 'Quick Start', pieces: ['default'], children: [] },
{ name: 'Review', pieces: ['pr-review'], children: [] }, { name: 'Review', pieces: ['review'], children: [] },
], ],
userPieceCategories: [ userPieceCategories: [
{ name: 'My Team', pieces: ['custom'], children: [] }, { name: 'My Team', pieces: ['custom'], children: [] },
@ -410,7 +410,7 @@ describe('buildCategorizedPieces', () => {
pieces: [], pieces: [],
children: [ children: [
{ name: 'Quick Start', pieces: ['default'], children: [] }, { name: 'Quick Start', pieces: ['default'], children: [] },
{ name: 'Review', pieces: ['pr-review'], children: [] }, { name: 'Review', pieces: ['review'], children: [] },
], ],
}, },
{ name: 'Others', pieces: ['extra'], children: [] }, { name: 'Others', pieces: ['extra'], children: [] },

View File

@ -1,5 +1,5 @@
/** /**
* Tests for pr-review piece * Tests for review piece
* *
* Covers: * Covers:
* - Piece YAML files (EN/JA) load and pass schema validation * - Piece YAML files (EN/JA) load and pass schema validation
@ -17,14 +17,14 @@ import { PieceConfigRawSchema } from '../core/models/index.js';
const RESOURCES_DIR = join(import.meta.dirname, '../../builtins'); const RESOURCES_DIR = join(import.meta.dirname, '../../builtins');
function loadPrReviewYaml(lang: 'en' | 'ja') { function loadReviewYaml(lang: 'en' | 'ja') {
const filePath = join(RESOURCES_DIR, lang, 'pieces', 'pr-review.yaml'); const filePath = join(RESOURCES_DIR, lang, 'pieces', 'review.yaml');
const content = readFileSync(filePath, 'utf-8'); const content = readFileSync(filePath, 'utf-8');
return parseYaml(content); return parseYaml(content);
} }
describe('pr-review piece (EN)', () => { describe('review piece (EN)', () => {
const raw = loadPrReviewYaml('en'); const raw = loadReviewYaml('en');
it('should pass schema validation', () => { it('should pass schema validation', () => {
const result = PieceConfigRawSchema.safeParse(raw); const result = PieceConfigRawSchema.safeParse(raw);
@ -32,7 +32,7 @@ describe('pr-review piece (EN)', () => {
}); });
it('should have correct name and initial_movement', () => { it('should have correct name and initial_movement', () => {
expect(raw.name).toBe('pr-review'); expect(raw.name).toBe('review');
expect(raw.initial_movement).toBe('gather'); expect(raw.initial_movement).toBe('gather');
}); });
@ -119,15 +119,15 @@ describe('pr-review piece (EN)', () => {
} }
}); });
it('should have gather movement with output_contracts for PR info', () => { it('should have gather movement with output_contracts for review target', () => {
const gather = raw.movements.find((s: { name: string }) => s.name === 'gather'); const gather = raw.movements.find((s: { name: string }) => s.name === 'gather');
expect(gather.output_contracts).toBeDefined(); expect(gather.output_contracts).toBeDefined();
expect(gather.output_contracts.report[0].name).toBe('00-pr-info.md'); expect(gather.output_contracts.report[0].name).toBe('00-review-target.md');
}); });
}); });
describe('pr-review piece (JA)', () => { describe('review piece (JA)', () => {
const raw = loadPrReviewYaml('ja'); const raw = loadReviewYaml('ja');
it('should pass schema validation', () => { it('should pass schema validation', () => {
const result = PieceConfigRawSchema.safeParse(raw); const result = PieceConfigRawSchema.safeParse(raw);
@ -135,7 +135,7 @@ describe('pr-review piece (JA)', () => {
}); });
it('should have correct name and initial_movement', () => { it('should have correct name and initial_movement', () => {
expect(raw.name).toBe('pr-review'); expect(raw.name).toBe('review');
expect(raw.initial_movement).toBe('gather'); expect(raw.initial_movement).toBe('gather');
}); });