From 6140c6ba0292796c462806fe4b1efb6703b843b3 Mon Sep 17 00:00:00 2001 From: nrslib <38722970+nrslib@users.noreply.github.com> Date: Fri, 6 Feb 2026 10:32:03 +0900 Subject: [PATCH] =?UTF-8?q?Hybrid=20Codex=20=E3=82=AB=E3=83=86=E3=82=B4?= =?UTF-8?q?=E3=83=AA=E8=BF=BD=E5=8A=A0=E3=80=81description=20=E3=81=AEYAML?= =?UTF-8?q?=E3=83=91=E3=83=BC=E3=82=B9=E3=82=A8=E3=83=A9=E3=83=BC=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E3=80=81=E3=82=B5=E3=83=96=E3=82=AB=E3=83=86=E3=82=B4?= =?UTF-8?q?=E3=83=AA=E3=83=8A=E3=83=93=E3=82=B2=E3=83=BC=E3=82=B7=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/global/en/piece-categories.yaml | 14 ++++ .../en/pieces/default-hybrid-codex.yaml | 2 +- .../en/pieces/expert-cqrs-hybrid-codex.yaml | 2 +- .../global/en/pieces/expert-hybrid-codex.yaml | 2 +- .../en/pieces/minimal-hybrid-codex.yaml | 2 +- .../en/pieces/passthrough-hybrid-codex.yaml | 2 +- .../review-fix-minimal-hybrid-codex.yaml | 2 +- resources/global/ja/piece-categories.yaml | 15 ++++ .../global/ja/pieces/coding-hybrid-codex.yaml | 2 +- .../ja/pieces/default-hybrid-codex.yaml | 2 +- .../ja/pieces/expert-cqrs-hybrid-codex.yaml | 2 +- .../global/ja/pieces/expert-hybrid-codex.yaml | 2 +- .../ja/pieces/minimal-hybrid-codex.yaml | 2 +- .../ja/pieces/passthrough-hybrid-codex.yaml | 2 +- .../review-fix-minimal-hybrid-codex.yaml | 2 +- src/__tests__/piece-selection.test.ts | 68 +++++++++++++++++++ src/features/pieceSelection/index.ts | 2 +- 17 files changed, 111 insertions(+), 14 deletions(-) diff --git a/resources/global/en/piece-categories.yaml b/resources/global/en/piece-categories.yaml index d7fa452..a06cfb7 100644 --- a/resources/global/en/piece-categories.yaml +++ b/resources/global/en/piece-categories.yaml @@ -22,6 +22,20 @@ piece_categories: - expert - expert-cqrs + "🔀 Hybrid (Codex Coding)": + "🚀 Quick Start": + pieces: + - default-hybrid-codex + - passthrough-hybrid-codex + - minimal-hybrid-codex + "🔍 Review & Fix": + pieces: + - review-fix-minimal-hybrid-codex + "🔧 Expert": + pieces: + - expert-hybrid-codex + - expert-cqrs-hybrid-codex + "Others": pieces: - research diff --git a/resources/global/en/pieces/default-hybrid-codex.yaml b/resources/global/en/pieces/default-hybrid-codex.yaml index 98b83ea..3baadbc 100644 --- a/resources/global/en/pieces/default-hybrid-codex.yaml +++ b/resources/global/en/pieces/default-hybrid-codex.yaml @@ -20,7 +20,7 @@ # - Decisions: 02-coder-decisions.md name: default-hybrid-codex -description: Standard development piece with planning and specialized reviews (hybrid: coder=codex) +description: Standard development piece with planning and specialized reviews max_iterations: 30 diff --git a/resources/global/en/pieces/expert-cqrs-hybrid-codex.yaml b/resources/global/en/pieces/expert-cqrs-hybrid-codex.yaml index 2309b2f..05e5917 100644 --- a/resources/global/en/pieces/expert-cqrs-hybrid-codex.yaml +++ b/resources/global/en/pieces/expert-cqrs-hybrid-codex.yaml @@ -19,7 +19,7 @@ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary") name: expert-cqrs-hybrid-codex -description: CQRS+ES, Frontend, Security, QA Expert Review (hybrid: coder=codex) +description: CQRS+ES, Frontend, Security, QA Expert Review max_iterations: 30 diff --git a/resources/global/en/pieces/expert-hybrid-codex.yaml b/resources/global/en/pieces/expert-hybrid-codex.yaml index b7655b2..7db1ca6 100644 --- a/resources/global/en/pieces/expert-hybrid-codex.yaml +++ b/resources/global/en/pieces/expert-hybrid-codex.yaml @@ -31,7 +31,7 @@ # - Decisions: 02-coder-decisions.md name: expert-hybrid-codex -description: Architecture, Frontend, Security, QA Expert Review (hybrid: coder=codex) +description: Architecture, Frontend, Security, QA Expert Review max_iterations: 30 diff --git a/resources/global/en/pieces/minimal-hybrid-codex.yaml b/resources/global/en/pieces/minimal-hybrid-codex.yaml index 552c9a4..16c004c 100644 --- a/resources/global/en/pieces/minimal-hybrid-codex.yaml +++ b/resources/global/en/pieces/minimal-hybrid-codex.yaml @@ -12,7 +12,7 @@ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary") name: minimal-hybrid-codex -description: Minimal development piece (implement -> parallel review -> fix if needed -> complete) (hybrid: coder=codex) +description: Minimal development piece (implement -> parallel review -> fix if needed -> complete) max_iterations: 20 diff --git a/resources/global/en/pieces/passthrough-hybrid-codex.yaml b/resources/global/en/pieces/passthrough-hybrid-codex.yaml index 8ea9ffd..fe4c1d6 100644 --- a/resources/global/en/pieces/passthrough-hybrid-codex.yaml +++ b/resources/global/en/pieces/passthrough-hybrid-codex.yaml @@ -7,7 +7,7 @@ # COMPLETE name: passthrough-hybrid-codex -description: Single-agent thin wrapper. Pass task directly to coder as-is. (hybrid: coder=codex) +description: Single-agent thin wrapper. Pass task directly to coder as-is. max_iterations: 10 diff --git a/resources/global/en/pieces/review-fix-minimal-hybrid-codex.yaml b/resources/global/en/pieces/review-fix-minimal-hybrid-codex.yaml index be4b76d..6342d29 100644 --- a/resources/global/en/pieces/review-fix-minimal-hybrid-codex.yaml +++ b/resources/global/en/pieces/review-fix-minimal-hybrid-codex.yaml @@ -12,7 +12,7 @@ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary") name: review-fix-minimal-hybrid-codex -description: Review and fix piece for existing code (starts with review, no implementation) (hybrid: coder=codex) +description: Review and fix piece for existing code (starts with review, no implementation) max_iterations: 20 diff --git a/resources/global/ja/piece-categories.yaml b/resources/global/ja/piece-categories.yaml index 91ee58a..ced6285 100644 --- a/resources/global/ja/piece-categories.yaml +++ b/resources/global/ja/piece-categories.yaml @@ -21,6 +21,21 @@ piece_categories: - expert - expert-cqrs + "🔀 ハイブリッド (Codex Coding)": + "🚀 クイックスタート": + pieces: + - default-hybrid-codex + - passthrough-hybrid-codex + - coding-hybrid-codex + - minimal-hybrid-codex + "🔍 レビュー&修正": + pieces: + - review-fix-minimal-hybrid-codex + "🔧 フルスタック": + pieces: + - expert-hybrid-codex + - expert-cqrs-hybrid-codex + "その他": pieces: - research diff --git a/resources/global/ja/pieces/coding-hybrid-codex.yaml b/resources/global/ja/pieces/coding-hybrid-codex.yaml index 9be0c67..8b0ee98 100644 --- a/resources/global/ja/pieces/coding-hybrid-codex.yaml +++ b/resources/global/ja/pieces/coding-hybrid-codex.yaml @@ -27,7 +27,7 @@ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary") name: coding-hybrid-codex -description: Architecture-focused development piece with parallel reviews (architect -> implement -> parallel review -> complete) (hybrid: coder=codex) +description: Architecture-focused development piece with parallel reviews (architect -> implement -> parallel review -> complete) max_iterations: 20 diff --git a/resources/global/ja/pieces/default-hybrid-codex.yaml b/resources/global/ja/pieces/default-hybrid-codex.yaml index 555d73f..4a26972 100644 --- a/resources/global/ja/pieces/default-hybrid-codex.yaml +++ b/resources/global/ja/pieces/default-hybrid-codex.yaml @@ -11,7 +11,7 @@ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary") name: default-hybrid-codex -description: Standard development piece with planning and specialized reviews (hybrid: coder=codex) +description: Standard development piece with planning and specialized reviews max_iterations: 30 diff --git a/resources/global/ja/pieces/expert-cqrs-hybrid-codex.yaml b/resources/global/ja/pieces/expert-cqrs-hybrid-codex.yaml index 8f34ee0..b2582fd 100644 --- a/resources/global/ja/pieces/expert-cqrs-hybrid-codex.yaml +++ b/resources/global/ja/pieces/expert-cqrs-hybrid-codex.yaml @@ -28,7 +28,7 @@ # - Decisions: 02-coder-decisions.md name: expert-cqrs-hybrid-codex -description: CQRS+ES・フロントエンド・セキュリティ・QA専門家レビュー (hybrid: coder=codex) +description: CQRS+ES・フロントエンド・セキュリティ・QA専門家レビュー max_iterations: 30 diff --git a/resources/global/ja/pieces/expert-hybrid-codex.yaml b/resources/global/ja/pieces/expert-hybrid-codex.yaml index 54b6590..b63b379 100644 --- a/resources/global/ja/pieces/expert-hybrid-codex.yaml +++ b/resources/global/ja/pieces/expert-hybrid-codex.yaml @@ -19,7 +19,7 @@ # {report_dir} - レポートディレクトリ名(例: "20250126-143052-task-summary") name: expert-hybrid-codex -description: アーキテクチャ・フロントエンド・セキュリティ・QA専門家レビュー (hybrid: coder=codex) +description: アーキテクチャ・フロントエンド・セキュリティ・QA専門家レビュー max_iterations: 30 diff --git a/resources/global/ja/pieces/minimal-hybrid-codex.yaml b/resources/global/ja/pieces/minimal-hybrid-codex.yaml index 55f4315..3e08e61 100644 --- a/resources/global/ja/pieces/minimal-hybrid-codex.yaml +++ b/resources/global/ja/pieces/minimal-hybrid-codex.yaml @@ -12,7 +12,7 @@ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary") name: minimal-hybrid-codex -description: Minimal development piece (implement -> parallel review -> fix if needed -> complete) (hybrid: coder=codex) +description: Minimal development piece (implement -> parallel review -> fix if needed -> complete) max_iterations: 20 diff --git a/resources/global/ja/pieces/passthrough-hybrid-codex.yaml b/resources/global/ja/pieces/passthrough-hybrid-codex.yaml index 7070d2a..a68627b 100644 --- a/resources/global/ja/pieces/passthrough-hybrid-codex.yaml +++ b/resources/global/ja/pieces/passthrough-hybrid-codex.yaml @@ -7,7 +7,7 @@ # COMPLETE name: passthrough-hybrid-codex -description: Single-agent thin wrapper. Pass task directly to coder as-is. (hybrid: coder=codex) +description: Single-agent thin wrapper. Pass task directly to coder as-is. max_iterations: 10 diff --git a/resources/global/ja/pieces/review-fix-minimal-hybrid-codex.yaml b/resources/global/ja/pieces/review-fix-minimal-hybrid-codex.yaml index 732e583..780df0c 100644 --- a/resources/global/ja/pieces/review-fix-minimal-hybrid-codex.yaml +++ b/resources/global/ja/pieces/review-fix-minimal-hybrid-codex.yaml @@ -12,7 +12,7 @@ # {report_dir} - Report directory name (e.g., "20250126-143052-task-summary") name: review-fix-minimal-hybrid-codex -description: 既存コードのレビューと修正ピース(レビュー開始、実装なし) (hybrid: coder=codex) +description: 既存コードのレビューと修正ピース(レビュー開始、実装なし) max_iterations: 20 diff --git a/src/__tests__/piece-selection.test.ts b/src/__tests__/piece-selection.test.ts index 635c5c4..ae250df 100644 --- a/src/__tests__/piece-selection.test.ts +++ b/src/__tests__/piece-selection.test.ts @@ -162,4 +162,72 @@ describe('selectPieceFromCategorizedPieces', () => { const selected = await selectPieceFromCategorizedPieces(categorized, ''); expect(selected).toBe('my-piece'); }); + + it('should navigate into subcategories recursively', async () => { + const categorized: CategorizedPieces = { + categories: [ + { + name: 'Hybrid', + pieces: [], + children: [ + { name: 'Quick Start', pieces: ['hybrid-default'], children: [] }, + { name: 'Full Stack', pieces: ['hybrid-expert'], children: [] }, + ], + }, + ], + allPieces: createPieceMap([ + { name: 'hybrid-default', source: 'builtin' }, + { name: 'hybrid-expert', source: 'builtin' }, + ]), + missingPieces: [], + }; + + // Select Hybrid category → Quick Start subcategory → piece + selectOptionMock + .mockResolvedValueOnce('__custom_category__:Hybrid') + .mockResolvedValueOnce('__category__:Quick Start') + .mockResolvedValueOnce('hybrid-default'); + + const selected = await selectPieceFromCategorizedPieces(categorized, ''); + expect(selected).toBe('hybrid-default'); + expect(selectOptionMock).toHaveBeenCalledTimes(3); + }); + + it('should show subcategories and pieces at the same level within a category', async () => { + const categorized: CategorizedPieces = { + categories: [ + { + name: 'Dev', + pieces: ['base-piece'], + children: [ + { name: 'Advanced', pieces: ['adv-piece'], children: [] }, + ], + }, + ], + allPieces: createPieceMap([ + { name: 'base-piece', source: 'user' }, + { name: 'adv-piece', source: 'user' }, + ]), + missingPieces: [], + }; + + // Select Dev category, then directly select the root-level piece + selectOptionMock + .mockResolvedValueOnce('__custom_category__:Dev') + .mockResolvedValueOnce('base-piece'); + + const selected = await selectPieceFromCategorizedPieces(categorized, ''); + expect(selected).toBe('base-piece'); + + // Second call should show Advanced subcategory AND base-piece at same level + const secondCallOptions = selectOptionMock.mock.calls[1]![1] as { label: string; value: string }[]; + const labels = secondCallOptions.map((o) => o.label); + + // Should contain the subcategory folder + expect(labels.some((l) => l.includes('Advanced'))).toBe(true); + // Should contain the piece + expect(labels.some((l) => l.includes('base-piece'))).toBe(true); + // Should NOT contain the parent category again + expect(labels.some((l) => l.includes('Dev'))).toBe(false); + }); }); diff --git a/src/features/pieceSelection/index.ts b/src/features/pieceSelection/index.ts index bfb0f8d..689c096 100644 --- a/src/features/pieceSelection/index.ts +++ b/src/features/pieceSelection/index.ts @@ -377,7 +377,7 @@ export async function selectPieceFromCategorizedPieces( if (selection.type === 'category') { const piece = await selectPieceFromCategoryTree( - [selection.node], + selection.node.children, currentPiece, true, selection.node.pieces,