issue参照時にもピース選択を実施 #97
This commit is contained in:
parent
919215fad3
commit
973c7df85d
@ -275,6 +275,7 @@ describe('addTask', () => {
|
||||
// Given: issue reference "#99"
|
||||
const issueText = 'Issue #99: Fix login timeout\n\nThe login page times out after 30 seconds.';
|
||||
mockResolveIssueTask.mockReturnValue(issueText);
|
||||
mockDeterminePiece.mockResolvedValue('default');
|
||||
|
||||
mockSummarizeTaskName.mockResolvedValue('fix-login-timeout');
|
||||
mockConfirm.mockResolvedValue(false);
|
||||
@ -288,6 +289,9 @@ describe('addTask', () => {
|
||||
// Then: resolveIssueTask was called
|
||||
expect(mockResolveIssueTask).toHaveBeenCalledWith('#99');
|
||||
|
||||
// Then: determinePiece was called for piece selection
|
||||
expect(mockDeterminePiece).toHaveBeenCalledWith(testDir);
|
||||
|
||||
// Then: task file created with issue text directly (no AI summarization)
|
||||
const taskFile = path.join(testDir, '.takt', 'tasks', 'fix-login-timeout.yaml');
|
||||
expect(fs.existsSync(taskFile)).toBe(true);
|
||||
@ -298,6 +302,7 @@ describe('addTask', () => {
|
||||
it('should proceed to worktree settings after issue fetch', async () => {
|
||||
// Given: issue with worktree enabled
|
||||
mockResolveIssueTask.mockReturnValue('Issue text');
|
||||
mockDeterminePiece.mockResolvedValue('default');
|
||||
mockSummarizeTaskName.mockResolvedValue('issue-task');
|
||||
mockConfirm.mockResolvedValue(true);
|
||||
mockPromptInput
|
||||
@ -331,6 +336,7 @@ describe('addTask', () => {
|
||||
// Given: issue reference "#99"
|
||||
const issueText = 'Issue #99: Fix login timeout';
|
||||
mockResolveIssueTask.mockReturnValue(issueText);
|
||||
mockDeterminePiece.mockResolvedValue('default');
|
||||
mockSummarizeTaskName.mockResolvedValue('fix-login-timeout');
|
||||
mockConfirm.mockResolvedValue(false);
|
||||
|
||||
@ -344,6 +350,42 @@ describe('addTask', () => {
|
||||
expect(content).toContain('issue: 99');
|
||||
});
|
||||
|
||||
it('should include piece selection in task file when issue reference is used', async () => {
|
||||
// Given: issue reference "#99" with non-default piece selection
|
||||
const issueText = 'Issue #99: Fix login timeout';
|
||||
mockResolveIssueTask.mockReturnValue(issueText);
|
||||
mockDeterminePiece.mockResolvedValue('review');
|
||||
mockSummarizeTaskName.mockResolvedValue('fix-login-timeout');
|
||||
mockConfirm.mockResolvedValue(false);
|
||||
|
||||
// When
|
||||
await addTask(testDir, '#99');
|
||||
|
||||
// Then: task file contains piece field
|
||||
const taskFile = path.join(testDir, '.takt', 'tasks', 'fix-login-timeout.yaml');
|
||||
expect(fs.existsSync(taskFile)).toBe(true);
|
||||
const content = fs.readFileSync(taskFile, 'utf-8');
|
||||
expect(content).toContain('piece: review');
|
||||
});
|
||||
|
||||
it('should cancel when piece selection returns null for issue reference', async () => {
|
||||
// Given: issue fetched successfully but user cancels piece selection
|
||||
const issueText = 'Issue #99: Fix login timeout';
|
||||
mockResolveIssueTask.mockReturnValue(issueText);
|
||||
mockDeterminePiece.mockResolvedValue(null);
|
||||
|
||||
// When
|
||||
await addTask(testDir, '#99');
|
||||
|
||||
// Then: no task file created (cancelled at piece selection)
|
||||
const tasksDir = path.join(testDir, '.takt', 'tasks');
|
||||
const files = fs.readdirSync(tasksDir);
|
||||
expect(files.length).toBe(0);
|
||||
|
||||
// Then: issue was fetched before cancellation
|
||||
expect(mockResolveIssueTask).toHaveBeenCalledWith('#99');
|
||||
});
|
||||
|
||||
describe('create_issue action', () => {
|
||||
it('should call createIssue when create_issue action is selected', async () => {
|
||||
// Given: interactive mode returns create_issue action
|
||||
|
||||
@ -106,18 +106,14 @@ export async function saveTaskFromInteractive(
|
||||
* add command handler
|
||||
*
|
||||
* Flow:
|
||||
* 1. ピース選択
|
||||
* 2. AI対話モードでタスクを詰める
|
||||
* 3. 会話履歴からAIがタスク要約を生成
|
||||
* 4. 要約からファイル名をAIで生成
|
||||
* 5. ワークツリー/ブランチ設定
|
||||
* 6. YAMLファイル作成
|
||||
* A) Issue参照の場合: issue取得 → ピース選択 → ワークツリー設定 → YAML作成
|
||||
* B) それ以外: ピース選択 → AI対話モード → ワークツリー設定 → YAML作成
|
||||
*/
|
||||
export async function addTask(cwd: string, task?: string): Promise<void> {
|
||||
const tasksDir = path.join(cwd, '.takt', 'tasks');
|
||||
fs.mkdirSync(tasksDir, { recursive: true });
|
||||
|
||||
// 1. ピース選択(Issue参照以外の場合、対話モードの前に実施)
|
||||
// ピース選択とタスク内容の決定
|
||||
let taskContent: string;
|
||||
let issueNumber: number | undefined;
|
||||
let piece: string | undefined;
|
||||
@ -137,6 +133,14 @@ export async function addTask(cwd: string, task?: string): Promise<void> {
|
||||
info(`Failed to fetch issue ${task}: ${msg}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// ピース選択(issue取得成功後)
|
||||
const pieceId = await determinePiece(cwd);
|
||||
if (pieceId === null) {
|
||||
info('Cancelled.');
|
||||
return;
|
||||
}
|
||||
piece = pieceId;
|
||||
} else {
|
||||
// ピース選択を先に行い、結果を対話モードに渡す
|
||||
const pieceId = await determinePiece(cwd);
|
||||
@ -165,7 +169,7 @@ export async function addTask(cwd: string, task?: string): Promise<void> {
|
||||
taskContent = result.task;
|
||||
}
|
||||
|
||||
// 3. ワークツリー/ブランチ設定
|
||||
// ワークツリー/ブランチ設定
|
||||
let worktree: boolean | string | undefined;
|
||||
let branch: string | undefined;
|
||||
|
||||
@ -180,7 +184,7 @@ export async function addTask(cwd: string, task?: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
// 4. YAMLファイル作成
|
||||
// YAMLファイル作成
|
||||
const filePath = await saveTaskFile(cwd, taskContent, {
|
||||
piece,
|
||||
issue: issueNumber,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user