fix: validate override piece via resolver including ensemble scope

This commit is contained in:
nrslib 2026-02-22 02:47:11 +09:00
parent 102f31447a
commit 9e3fb5cf16
2 changed files with 14 additions and 5 deletions

View File

@ -33,6 +33,7 @@ vi.mock('../infra/config/index.js', () => ({
resolvePieceConfigValue: (...args: unknown[]) => mockResolvePieceConfigValue(...args),
listPieces: vi.fn(() => ['default']),
listPieceEntries: vi.fn(() => []),
loadPieceByIdentifier: vi.fn((identifier: string) => (identifier === 'default' ? { name: 'default' } : null)),
isPiecePath: vi.fn(() => false),
}));
@ -86,11 +87,13 @@ vi.mock('../features/pieceSelection/index.js', () => ({
}));
import { confirm } from '../shared/prompt/index.js';
import { loadPieceByIdentifier } from '../infra/config/index.js';
import { createSharedClone, autoCommitAndPush, summarizeTaskName } from '../infra/task/index.js';
import { selectPiece } from '../features/pieceSelection/index.js';
import { selectAndExecuteTask, determinePiece } from '../features/tasks/execute/selectAndExecute.js';
const mockConfirm = vi.mocked(confirm);
const mockLoadPieceByIdentifier = vi.mocked(loadPieceByIdentifier);
const mockCreateSharedClone = vi.mocked(createSharedClone);
const mockAutoCommitAndPush = vi.mocked(autoCommitAndPush);
const mockSummarizeTaskName = vi.mocked(summarizeTaskName);
@ -180,6 +183,14 @@ describe('resolveAutoPr default in selectAndExecuteTask', () => {
expect(mockSelectPiece).toHaveBeenCalledWith('/project');
});
it('should accept ensemble scoped piece override when it exists', async () => {
mockLoadPieceByIdentifier.mockReturnValueOnce({ name: '@nrslib/takt-packages/critical-thinking' } as never);
const selected = await determinePiece('/project', '@nrslib/takt-packages/critical-thinking');
expect(selected).toBe('@nrslib/takt-packages/critical-thinking');
});
it('should fail task record when executeTask throws', async () => {
mockConfirm.mockResolvedValue(true);
mockSummarizeTaskName.mockResolvedValue('test-task');

View File

@ -7,12 +7,11 @@
*/
import {
listPieces,
loadPieceByIdentifier,
isPiecePath,
} from '../../../infra/config/index.js';
import { confirm } from '../../../shared/prompt/index.js';
import { createSharedClone, summarizeTaskName, getCurrentBranch, TaskRunner } from '../../../infra/task/index.js';
import { DEFAULT_PIECE_NAME } from '../../../shared/constants.js';
import { info, error, withProgress } from '../../../shared/ui/index.js';
import { createLogger } from '../../../shared/utils/index.js';
import { executeTask } from './taskExecution.js';
@ -30,9 +29,8 @@ export async function determinePiece(cwd: string, override?: string): Promise<st
if (isPiecePath(override)) {
return override;
}
const availablePieces = listPieces(cwd);
const knownPieces = availablePieces.length === 0 ? [DEFAULT_PIECE_NAME] : availablePieces;
if (!knownPieces.includes(override)) {
const resolvedPiece = loadPieceByIdentifier(override, cwd);
if (!resolvedPiece) {
error(`Piece not found: ${override}`);
return null;
}