fix: takt add #N でIssue内容がAI要約で壊れる問題を修正 (#46)
This commit is contained in:
parent
26ac231435
commit
80a75004a4
@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||||
|
|
||||||
|
## [0.3.3] - 2026-01-31
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `takt add #N` がIssue内容をAI要約に通してしまい、タスク内容が壊れる問題を修正 (#46)
|
||||||
|
- Issue参照時は `resolveIssueTask` の結果をそのままタスクとして使用するように変更
|
||||||
|
|
||||||
## [0.3.1] - 2026-01-31
|
## [0.3.1] - 2026-01-31
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@ -291,15 +291,11 @@ describe('addTask', () => {
|
|||||||
expect(content).not.toContain('workflow:');
|
expect(content).not.toContain('workflow:');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fetch issue and summarize with AI when given issue reference', async () => {
|
it('should fetch issue and use directly as task content when given issue reference', async () => {
|
||||||
// Given: issue reference "#99"
|
// Given: issue reference "#99"
|
||||||
const issueText = 'Issue #99: Fix login timeout\n\nThe login page times out after 30 seconds.';
|
const issueText = 'Issue #99: Fix login timeout\n\nThe login page times out after 30 seconds.';
|
||||||
const summarized = '# ログインタイムアウト修正\nログインページの30秒タイムアウトを修正する';
|
|
||||||
mockResolveIssueTask.mockReturnValue(issueText);
|
mockResolveIssueTask.mockReturnValue(issueText);
|
||||||
|
|
||||||
const mockProviderCall = vi.fn().mockResolvedValue({ content: summarized });
|
|
||||||
mockGetProvider.mockReturnValue({ call: mockProviderCall } as any);
|
|
||||||
|
|
||||||
mockSummarizeTaskName.mockResolvedValue('fix-login-timeout');
|
mockSummarizeTaskName.mockResolvedValue('fix-login-timeout');
|
||||||
mockConfirm.mockResolvedValue(false);
|
mockConfirm.mockResolvedValue(false);
|
||||||
mockListWorkflows.mockReturnValue([]);
|
mockListWorkflows.mockReturnValue([]);
|
||||||
@ -313,29 +309,16 @@ describe('addTask', () => {
|
|||||||
// Then: resolveIssueTask was called
|
// Then: resolveIssueTask was called
|
||||||
expect(mockResolveIssueTask).toHaveBeenCalledWith('#99');
|
expect(mockResolveIssueTask).toHaveBeenCalledWith('#99');
|
||||||
|
|
||||||
// Then: summarizeConversation was called with issue text
|
// Then: task file created with issue text directly (no AI summarization)
|
||||||
expect(mockProviderCall).toHaveBeenCalledWith(
|
|
||||||
'task-summarizer',
|
|
||||||
issueText,
|
|
||||||
expect.objectContaining({
|
|
||||||
cwd: testDir,
|
|
||||||
maxTurns: 1,
|
|
||||||
allowedTools: [],
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Then: task file created with summarized content
|
|
||||||
const taskFile = path.join(testDir, '.takt', 'tasks', 'fix-login-timeout.yaml');
|
const taskFile = path.join(testDir, '.takt', 'tasks', 'fix-login-timeout.yaml');
|
||||||
expect(fs.existsSync(taskFile)).toBe(true);
|
expect(fs.existsSync(taskFile)).toBe(true);
|
||||||
const content = fs.readFileSync(taskFile, 'utf-8');
|
const content = fs.readFileSync(taskFile, 'utf-8');
|
||||||
expect(content).toContain('ログインタイムアウト修正');
|
expect(content).toContain('Fix login timeout');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should proceed to worktree/workflow settings after issue summarization', async () => {
|
it('should proceed to worktree/workflow settings after issue fetch', async () => {
|
||||||
// Given: issue with worktree enabled
|
// Given: issue with worktree enabled
|
||||||
mockResolveIssueTask.mockReturnValue('Issue text');
|
mockResolveIssueTask.mockReturnValue('Issue text');
|
||||||
const mockProviderCall = vi.fn().mockResolvedValue({ content: 'Summarized issue' });
|
|
||||||
mockGetProvider.mockReturnValue({ call: mockProviderCall } as any);
|
|
||||||
mockSummarizeTaskName.mockResolvedValue('issue-task');
|
mockSummarizeTaskName.mockResolvedValue('issue-task');
|
||||||
mockConfirm.mockResolvedValue(true);
|
mockConfirm.mockResolvedValue(true);
|
||||||
mockPromptInput.mockResolvedValue('');
|
mockPromptInput.mockResolvedValue('');
|
||||||
|
|||||||
@ -82,18 +82,16 @@ export async function addTask(cwd: string, task?: string): Promise<void> {
|
|||||||
let taskContent: string;
|
let taskContent: string;
|
||||||
|
|
||||||
if (task && isIssueReference(task)) {
|
if (task && isIssueReference(task)) {
|
||||||
// Issue reference: fetch issue and summarize with AI
|
// Issue reference: fetch issue and use directly as task content
|
||||||
info('Fetching GitHub Issue...');
|
info('Fetching GitHub Issue...');
|
||||||
let issueText: string;
|
|
||||||
try {
|
try {
|
||||||
issueText = resolveIssueTask(task);
|
taskContent = resolveIssueTask(task);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const msg = e instanceof Error ? e.message : String(e);
|
const msg = e instanceof Error ? e.message : String(e);
|
||||||
log.error('Failed to fetch GitHub Issue', { task, error: msg });
|
log.error('Failed to fetch GitHub Issue', { task, error: msg });
|
||||||
info(`Failed to fetch issue ${task}: ${msg}`);
|
info(`Failed to fetch issue ${task}: ${msg}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
taskContent = await summarizeConversation(cwd, issueText);
|
|
||||||
} else {
|
} else {
|
||||||
// Interactive mode: AI conversation to refine task
|
// Interactive mode: AI conversation to refine task
|
||||||
const result = await interactiveMode(cwd);
|
const result = await interactiveMode(cwd);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user