diff --git a/CLAUDE.md b/CLAUDE.md index 41e3491..8db11a5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -67,10 +67,9 @@ TAKT (TAKT Agent Koordination Topology) is a multi-agent orchestration system fo | `--pr ` | PR number to fetch review comments and fix | | `-w, --piece ` | Piece name or path to piece YAML file | | `-b, --branch ` | Branch name (auto-generated if omitted) | -| `--auto-pr` | Create PR after execution (interactive: skip confirmation, pipeline: enable PR) | +| `--auto-pr` | Create PR after execution (pipeline mode only) | | `--skip-git` | Skip branch creation, commit, and push (pipeline mode, piece-only) | | `--repo ` | Repository for PR creation | -| `--create-worktree ` | Skip worktree confirmation prompt | | `-q, --quiet` | Minimal output mode: suppress AI output (for CI) | | `--provider ` | Override agent provider (claude\|codex\|opencode\|mock) | | `--model ` | Override agent model | diff --git a/docs/cli-reference.ja.md b/docs/cli-reference.ja.md index 0cdaa1b..28b7d1c 100644 --- a/docs/cli-reference.ja.md +++ b/docs/cli-reference.ja.md @@ -18,7 +18,6 @@ | `--draft` | PR をドラフトとして作成(`--auto-pr` または `auto_pr` 設定が必要) | | `--skip-git` | ブランチ作成、コミット、プッシュをスキップ(pipeline モード、piece のみ実行) | | `--repo ` | リポジトリを指定(PR 作成用) | -| `--create-worktree ` | worktree 確認プロンプトをスキップ | | `-q, --quiet` | 最小出力モード: AI 出力を抑制(CI 向け) | | `--provider ` | エージェント provider を上書き(claude\|codex\|opencode\|cursor\|copilot\|mock) | | `--model ` | エージェントモデルを上書き | @@ -44,7 +43,7 @@ takt hello 2. インタラクティブモードを選択(assistant / persona / quiet / passthrough) 3. AI との会話でタスク内容を精緻化 4. `/go` でタスク指示を確定(`/go 追加の指示` のように追記も可能)、または `/play ` でタスクを即座に実行 -5. 実行(worktree 作成、piece 実行、PR 作成) +5. 実行(piece 実行、PR 作成) ### インタラクティブモードの種類 @@ -89,8 +88,6 @@ Requirements: Proceed with these task instructions? (Y/n) y -? Create worktree? (Y/n) y - [Piece の実行を開始...] ``` diff --git a/docs/cli-reference.md b/docs/cli-reference.md index c422f38..7dafbc6 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -18,7 +18,6 @@ This document provides a complete reference for all TAKT CLI commands and option | `--draft` | Create PR as draft (requires `--auto-pr` or `auto_pr` config) | | `--skip-git` | Skip branch creation, commit, and push (pipeline mode, piece-only) | | `--repo ` | Specify repository (for PR creation) | -| `--create-worktree ` | Skip worktree confirmation prompt | | `-q, --quiet` | Minimal output mode: suppress AI output (for CI) | | `--provider ` | Override agent provider (claude\|codex\|opencode\|cursor\|copilot\|mock) | | `--model ` | Override agent model | @@ -44,7 +43,7 @@ takt hello 2. Select interactive mode (assistant / persona / quiet / passthrough) 3. Refine task content through conversation with AI 4. Finalize task instructions with `/go` (you can also add additional instructions like `/go additional instructions`), or use `/play ` to execute a task immediately -5. Execute (create worktree, run piece, create PR) +5. Execute (run piece, create PR) ### Interactive Mode Variants @@ -89,8 +88,6 @@ Requirements: Proceed with these task instructions? (Y/n) y -? Create worktree? (Y/n) y - [Piece execution starts...] ``` diff --git a/docs/data-flow.md b/docs/data-flow.md index 306ef96..d3771d6 100644 --- a/docs/data-flow.md +++ b/docs/data-flow.md @@ -18,7 +18,7 @@ TAKTのデータフローは以下の7つの主要なレイヤーで構成され 1. **CLI Layer** - ユーザー入力の受付 2. **Interactive Layer** - タスクの対話的な明確化 -3. **Execution Orchestration Layer** - ピース選択とworktree管理 +3. **Execution Orchestration Layer** - ピース選択と実行開始 4. **Piece Execution Layer** - セッション管理とイベント処理 5. **Engine Layer** - ステートマシンによるステップ実行 6. **Instruction Building Layer** - プロンプト生成 @@ -72,13 +72,6 @@ TAKTのデータフローは以下の7つの主要なレイヤーで構成され │ │ pieceIdentifier: string │ │ ▼ │ │ ┌──────────────────────────────────┐ │ -│ │ confirmAndCreateWorktree() │ │ -│ │ - AI branchname generation │ │ -│ │ - createSharedClone() │ │ -│ └─────────┬────────────────────────┘ │ -│ │ { execCwd, isWorktree, branch } │ -│ ▼ │ -│ ┌──────────────────────────────────┐ │ │ │ executeTask() │ │ │ │ - task: string │ │ │ │ - cwd: string (実行ディレクトリ) │ │ @@ -362,7 +355,7 @@ TAKTのデータフローは以下の7つの主要なレイヤーで構成され ### 3. Execution Orchestration Layer (`src/features/tasks/execute/selectAndExecute.ts`) -**役割**: ピース選択とworktree管理 +**役割**: ピース選択と実行オーケストレーション **主要な処理**: @@ -372,26 +365,18 @@ TAKTのデータフローは以下の7つの主要なレイヤーで構成され - 名前形式 → バリデーション - オーバーライドなし → インタラクティブ選択 (`selectPiece()`) -2. **Worktree作成** (`confirmAndCreateWorktree()`): - - ユーザー確認 (または `--create-worktree` フラグ) - - ブランチ名生成 (`summarizeTaskName()` - AIでタスクから英語スラグ生成) - - `createSharedClone()`: git clone --shared で軽量クローン作成 - -3. **タスク実行開始** (`selectAndExecuteTask()`): +2. **タスク実行開始** (`selectAndExecuteTask()`): - `executeTask()` を呼び出し - - 成功時: Auto-commit & Push - - PR作成 (オプション) + - 成功/失敗を `tasks.yaml` に記録(`skipTaskList` 設定時を除く) **データ入力**: - `task: string` - `options?: SelectAndExecuteOptions`: - `piece?: string` - - `createWorktree?: boolean` - - `autoPr?: boolean` + - `skipTaskList?: boolean` - `agentOverrides?: TaskExecutionOptions` **データ出力**: -- `{ execCwd, isWorktree, branch }` - タスク実行成功/失敗 --- @@ -763,15 +748,9 @@ async call( - `--piece` フラグ → 検証 - なし → インタラクティブ選択 (`selectPiece()`) -**Worktree作成** (オプション): -- `confirmAndCreateWorktree()`: - - ユーザー確認または `--create-worktree` フラグ - - `summarizeTaskName()`: タスク → 英語スラグ (AI呼び出し) - - `createSharedClone()`: git clone --shared - **データ**: - `pieceIdentifier: string` -- `{ execCwd, isWorktree, branch }` +- `execCwd: string` (実行ディレクトリ) --- diff --git a/docs/testing/e2e.md b/docs/testing/e2e.md index 7ed9b2e..78b7bd3 100644 --- a/docs/testing/e2e.md +++ b/docs/testing/e2e.md @@ -48,10 +48,10 @@ E2Eテストを追加・変更した場合は、このドキュメントも更 - `README.md` に行が追加されることを確認する。 - 実行後にタスクが `tasks.yaml` で `completed` ステータスになることを確認する。 - Worktree/Clone isolation(`e2e/specs/worktree.e2e.ts`) - - 目的: `--create-worktree yes` 指定で隔離環境に実行されることを確認。 + - 目的: `worktree: true` タスクが隔離環境に実行されることを確認。 - LLM: 条件付き(`TAKT_E2E_PROVIDER` が `claude` / `codex` の場合に呼び出す) - 手順(ユーザー行動/コマンド): - - `takt --task 'Add a line "worktree test" to README.md' --piece e2e/fixtures/pieces/simple.yaml --create-worktree yes` を実行する。 + - `.takt/tasks.yaml` に `worktree: true` のタスクを追加して `takt run` を実行する。 - コマンドが成功終了することを確認する。 - Pipeline mode(`e2e/specs/pipeline.e2e.ts`) - 目的: ブランチ作成→タスク実行→コミット→push→PR作成の一連フローを確認。 @@ -73,7 +73,7 @@ E2Eテストを追加・変更した場合は、このドキュメントも更 - 目的: `--task` の直接実行が、プロンプトなしで完了することを確認。 - LLM: 呼び出さない(`--provider mock` 固定) - 手順(ユーザー行動/コマンド): - - `takt --task 'Create a file called noop.txt' --piece e2e/fixtures/pieces/mock-single-step.yaml --create-worktree no --provider mock` を実行する。 + - `takt --task 'Create a file called noop.txt' --piece e2e/fixtures/pieces/mock-single-step.yaml --provider mock` を実行する。 - `TAKT_MOCK_SCENARIO=e2e/fixtures/scenarios/execute-done.json` を設定する。 - 出力に `Piece completed` が含まれることを確認する。 - Pipeline mode with --skip-git(`e2e/specs/pipeline-skip-git.e2e.ts`) @@ -87,7 +87,7 @@ E2Eテストを追加・変更した場合は、このドキュメントも更 - 目的: reportフェーズとjudgeフェーズを通ることを確認(mockシナリオ)。 - LLM: 呼び出さない(`--provider mock` 固定) - 手順(ユーザー行動/コマンド): - - `takt --task 'Create a short report and finish' --piece e2e/fixtures/pieces/report-judge.yaml --create-worktree no --provider mock` を実行する。 + - `takt --task 'Create a short report and finish' --piece e2e/fixtures/pieces/report-judge.yaml --provider mock` を実行する。 - `TAKT_MOCK_SCENARIO=e2e/fixtures/scenarios/report-judge.json` を設定する。 - 出力に `Piece completed` が含まれることを確認する。 - Add task(`e2e/specs/add.e2e.ts`) @@ -135,7 +135,7 @@ E2Eテストを追加・変更した場合は、このドキュメントも更 - LLM: 条件付き(`TAKT_E2E_PROVIDER` が `claude` / `codex` / `opencode` の場合に実行、未指定時は skip) - 手順(ユーザー行動/コマンド): - E2E用 `config.yaml` に `runtime.prepare: [gradle, node]` を設定する。 - - `takt --task '' --piece e2e/fixtures/pieces/simple.yaml --create-worktree no` を実行する。 + - `takt --task '' --piece e2e/fixtures/pieces/simple.yaml` を実行する。 - 正例では、作業リポジトリに `.runtime/env.sh` と `.runtime/{tmp,cache,config,state,gradle,npm}` が作成されていることを確認する。 - 負例(`runtime.prepare` 未設定)では、`GRADLE_USER_HOME is required` と npm キャッシュ書き込み失敗が出力され、`.runtime/env.sh` が生成されないことを確認する。 - List tasks non-interactive(`e2e/specs/list-non-interactive.e2e.ts`) diff --git a/e2e/specs/config-priority.e2e.ts b/e2e/specs/config-priority.e2e.ts index e782e6b..9a4d991 100644 --- a/e2e/specs/config-priority.e2e.ts +++ b/e2e/specs/config-priority.e2e.ts @@ -77,74 +77,21 @@ describe('E2E: Config priority (piece / autoPr)', () => { it('should default auto_pr to true when unset in config/env', () => { const piecePath = resolve(__dirname, '../fixtures/pieces/mock-single-step.yaml'); - const scenarioPath = resolve(__dirname, '../fixtures/scenarios/execute-done.json'); - - runTakt({ - args: [ - '--task', 'Auto PR default behavior', - '--piece', piecePath, - '--create-worktree', 'yes', - '--provider', 'mock', - ], - cwd: testRepo.path, - env: { - ...isolatedEnv.env, - TAKT_MOCK_SCENARIO: scenarioPath, - }, - timeout: 240_000, - }); - - const task = readFirstTask(testRepo.path); - expect(task['auto_pr']).toBe(true); - }, 240_000); - - it('should use auto_pr from config when set', () => { - const piecePath = resolve(__dirname, '../fixtures/pieces/mock-single-step.yaml'); - const scenarioPath = resolve(__dirname, '../fixtures/scenarios/execute-done.json'); - updateIsolatedConfig(isolatedEnv.taktDir, { auto_pr: false }); - const result = runTakt({ args: [ - '--task', 'Auto PR from config', '--piece', piecePath, - '--create-worktree', 'yes', - '--provider', 'mock', + 'add', + 'Auto PR default behavior', ], cwd: testRepo.path, - env: { - ...isolatedEnv.env, - TAKT_MOCK_SCENARIO: scenarioPath, - }, + env: isolatedEnv.env, timeout: 240_000, }); expect(result.exitCode).toBe(0); - const task = readFirstTask(testRepo.path); - expect(task['auto_pr']).toBe(false); - }, 240_000); - - it('should prioritize env auto_pr over config', () => { - const piecePath = resolve(__dirname, '../fixtures/pieces/mock-single-step.yaml'); - const scenarioPath = resolve(__dirname, '../fixtures/scenarios/execute-done.json'); - updateIsolatedConfig(isolatedEnv.taktDir, { auto_pr: false }); - - runTakt({ - args: [ - '--task', 'Auto PR from env override', - '--piece', piecePath, - '--create-worktree', 'yes', - '--provider', 'mock', - ], - cwd: testRepo.path, - env: { - ...isolatedEnv.env, - TAKT_AUTO_PR: 'true', - TAKT_MOCK_SCENARIO: scenarioPath, - }, - timeout: 240_000, - }); const task = readFirstTask(testRepo.path); expect(task['auto_pr']).toBe(true); }, 240_000); + }); diff --git a/e2e/specs/cycle-detection.e2e.ts b/e2e/specs/cycle-detection.e2e.ts index 4c3503a..dffdd52 100644 --- a/e2e/specs/cycle-detection.e2e.ts +++ b/e2e/specs/cycle-detection.e2e.ts @@ -39,7 +39,6 @@ describe('E2E: Cycle detection via loop_monitors (mock)', () => { args: [ '--task', 'Test cycle detection abort', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, @@ -68,7 +67,6 @@ describe('E2E: Cycle detection via loop_monitors (mock)', () => { args: [ '--task', 'Test cycle detection pass', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, diff --git a/e2e/specs/direct-task.e2e.ts b/e2e/specs/direct-task.e2e.ts index c2a3f1c..f878706 100644 --- a/e2e/specs/direct-task.e2e.ts +++ b/e2e/specs/direct-task.e2e.ts @@ -9,7 +9,7 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // E2E更新時は docs/testing/e2e.md も更新すること -describe('E2E: Direct task execution (--task --create-worktree no)', () => { +describe('E2E: Direct task execution (--task)', () => { let isolatedEnv: IsolatedEnv; let testRepo: TestRepo; @@ -39,7 +39,6 @@ describe('E2E: Direct task execution (--task --create-worktree no)', () => { args: [ '--task', 'Create a file called noop.txt', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: testRepo.path, diff --git a/e2e/specs/error-handling.e2e.ts b/e2e/specs/error-handling.e2e.ts index 92dadb7..11dd233 100644 --- a/e2e/specs/error-handling.e2e.ts +++ b/e2e/specs/error-handling.e2e.ts @@ -31,7 +31,6 @@ describe('E2E: Error handling edge cases (mock)', () => { args: [ '--task', 'test', '--piece', '/nonexistent/path/to/piece.yaml', - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, @@ -53,7 +52,6 @@ describe('E2E: Error handling edge cases (mock)', () => { args: [ '--task', 'test', '--piece', 'nonexistent-piece-name-xyz', - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, @@ -90,8 +88,8 @@ describe('E2E: Error handling edge cases (mock)', () => { expect(combined).toMatch(/task|issue|required/i); }, 240_000); - it('should error when --create-worktree receives an invalid value', () => { - // Given: invalid worktree value + it('should error when deprecated --create-worktree option is used', () => { + // Given: deprecated option value const piecePath = resolve(__dirname, '../fixtures/pieces/mock-single-step.yaml'); // When: running with invalid worktree option @@ -107,10 +105,10 @@ describe('E2E: Error handling edge cases (mock)', () => { timeout: 240_000, }); - // Then: exits with error or warning about invalid value + // Then: exits with migration error const combined = result.stdout + result.stderr; - const hasError = result.exitCode !== 0 || combined.match(/invalid|error|must be/i); - expect(hasError).toBeTruthy(); + expect(result.exitCode).not.toBe(0); + expect(combined).toContain('--create-worktree has been removed'); }, 240_000); it('should error when piece file contains invalid YAML', () => { @@ -122,7 +120,6 @@ describe('E2E: Error handling edge cases (mock)', () => { args: [ '--task', 'test', '--piece', brokenPiecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, diff --git a/e2e/specs/model-override.e2e.ts b/e2e/specs/model-override.e2e.ts index 89a842b..e3037a1 100644 --- a/e2e/specs/model-override.e2e.ts +++ b/e2e/specs/model-override.e2e.ts @@ -31,7 +31,6 @@ describe('E2E: --model option override (mock)', () => { args: [ '--task', 'Test model override direct', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', '--model', 'mock-model-override', ], diff --git a/e2e/specs/multi-step-parallel.e2e.ts b/e2e/specs/multi-step-parallel.e2e.ts index 6ea5f39..514f560 100644 --- a/e2e/specs/multi-step-parallel.e2e.ts +++ b/e2e/specs/multi-step-parallel.e2e.ts @@ -40,7 +40,6 @@ describe('E2E: Multi-step with parallel movements (mock)', () => { args: [ '--task', 'Implement a feature', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: testRepo.path, @@ -62,7 +61,6 @@ describe('E2E: Multi-step with parallel movements (mock)', () => { args: [ '--task', 'Implement a feature with issues', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: testRepo.path, diff --git a/e2e/specs/multi-step-sequential.e2e.ts b/e2e/specs/multi-step-sequential.e2e.ts index e5f063e..8abbb64 100644 --- a/e2e/specs/multi-step-sequential.e2e.ts +++ b/e2e/specs/multi-step-sequential.e2e.ts @@ -32,7 +32,6 @@ describe('E2E: Sequential multi-step session log transitions (mock)', () => { args: [ '--task', 'Test sequential transitions', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, diff --git a/e2e/specs/piece-error-handling.e2e.ts b/e2e/specs/piece-error-handling.e2e.ts index 0cfae86..b1ac71a 100644 --- a/e2e/specs/piece-error-handling.e2e.ts +++ b/e2e/specs/piece-error-handling.e2e.ts @@ -33,7 +33,6 @@ describe('E2E: Piece error handling (mock)', () => { args: [ '--task', 'Test error status abort', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, @@ -60,7 +59,6 @@ describe('E2E: Piece error handling (mock)', () => { args: [ '--task', 'Test max movements', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, @@ -87,7 +85,6 @@ describe('E2E: Piece error handling (mock)', () => { args: [ '--task', 'Test previous response passing', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, diff --git a/e2e/specs/piece-selection-branches.e2e.ts b/e2e/specs/piece-selection-branches.e2e.ts index 92c8576..18e2d90 100644 --- a/e2e/specs/piece-selection-branches.e2e.ts +++ b/e2e/specs/piece-selection-branches.e2e.ts @@ -54,7 +54,7 @@ function runTaskWithPiece(args: { env: NodeJS.ProcessEnv; }): ReturnType { const scenarioPath = resolve(__dirname, '../fixtures/scenarios/execute-done.json'); - const baseArgs = ['--task', 'Create a file called noop.txt', '--create-worktree', 'no', '--provider', 'mock']; + const baseArgs = ['--task', 'Create a file called noop.txt', '--provider', 'mock']; const fullArgs = args.piece ? [...baseArgs, '--piece', args.piece] : baseArgs; return runTakt({ args: fullArgs, diff --git a/e2e/specs/provider-error.e2e.ts b/e2e/specs/provider-error.e2e.ts index 511a72e..b77f062 100644 --- a/e2e/specs/provider-error.e2e.ts +++ b/e2e/specs/provider-error.e2e.ts @@ -41,7 +41,6 @@ describe('E2E: Provider error handling (mock)', () => { args: [ '--task', 'Test provider override', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, @@ -67,7 +66,6 @@ describe('E2E: Provider error handling (mock)', () => { args: [ '--task', 'Test scenario exhaustion', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, @@ -93,7 +91,6 @@ describe('E2E: Provider error handling (mock)', () => { args: [ '--task', 'Test bad scenario', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, diff --git a/e2e/specs/quiet-mode.e2e.ts b/e2e/specs/quiet-mode.e2e.ts index 5475fbe..9ca5643 100644 --- a/e2e/specs/quiet-mode.e2e.ts +++ b/e2e/specs/quiet-mode.e2e.ts @@ -33,7 +33,6 @@ describe('E2E: Quiet mode (--quiet)', () => { args: [ '--task', 'Test quiet mode', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', '--quiet', ], diff --git a/e2e/specs/report-file-output.e2e.ts b/e2e/specs/report-file-output.e2e.ts index e570713..e081599 100644 --- a/e2e/specs/report-file-output.e2e.ts +++ b/e2e/specs/report-file-output.e2e.ts @@ -39,7 +39,6 @@ describe('E2E: Report file output (mock)', () => { args: [ '--task', 'Test report output', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, diff --git a/e2e/specs/report-judge.e2e.ts b/e2e/specs/report-judge.e2e.ts index 21158a6..793651e 100644 --- a/e2e/specs/report-judge.e2e.ts +++ b/e2e/specs/report-judge.e2e.ts @@ -39,7 +39,6 @@ describe('E2E: Report + Judge phases (mock)', () => { args: [ '--task', 'Create a short report and finish', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: testRepo.path, diff --git a/e2e/specs/runtime-config-provider.e2e.ts b/e2e/specs/runtime-config-provider.e2e.ts index 4c8a29b..97b6d1b 100644 --- a/e2e/specs/runtime-config-provider.e2e.ts +++ b/e2e/specs/runtime-config-provider.e2e.ts @@ -113,7 +113,6 @@ describe('E2E: runtime.prepare with provider', () => { 'If both commands succeed, respond exactly with: Task completed', ].join(' '), '--piece', piecePath, - '--create-worktree', 'no', ], cwd: repo.path, env: isolatedEnv.env, @@ -151,7 +150,6 @@ describe('E2E: runtime.prepare with provider', () => { 'If both commands succeed, respond exactly with: Task completed', ].join(' '), '--piece', piecePath, - '--create-worktree', 'no', ], cwd: repo.path, env: isolatedEnv.env, diff --git a/e2e/specs/session-log.e2e.ts b/e2e/specs/session-log.e2e.ts index a65cdc2..2708af4 100644 --- a/e2e/specs/session-log.e2e.ts +++ b/e2e/specs/session-log.e2e.ts @@ -32,7 +32,6 @@ describe('E2E: Session NDJSON log output (mock)', () => { args: [ '--task', 'Test session log success', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, @@ -59,7 +58,6 @@ describe('E2E: Session NDJSON log output (mock)', () => { args: [ '--task', 'Test session log abort', '--piece', piecePath, - '--create-worktree', 'no', '--provider', 'mock', ], cwd: repo.path, diff --git a/e2e/specs/structured-output.e2e.ts b/e2e/specs/structured-output.e2e.ts index 1742e63..047d246 100644 --- a/e2e/specs/structured-output.e2e.ts +++ b/e2e/specs/structured-output.e2e.ts @@ -52,7 +52,6 @@ describe('E2E: Structured output rule matching', () => { args: [ '--task', 'Say hello', '--piece', piecePath, - '--create-worktree', 'no', ], cwd: repo.path, env: isolatedEnv.env, diff --git a/e2e/specs/team-leader-refill-threshold.e2e.ts b/e2e/specs/team-leader-refill-threshold.e2e.ts index 3db08d7..9890a52 100644 --- a/e2e/specs/team-leader-refill-threshold.e2e.ts +++ b/e2e/specs/team-leader-refill-threshold.e2e.ts @@ -39,8 +39,6 @@ describe('E2E: Team leader refill threshold', () => { 'Create exactly seven files: rt-1.txt, rt-2.txt, rt-3.txt, rt-4.txt, rt-5.txt, rt-6.txt, rt-7.txt. Each file must contain its own filename as content. Each part must create exactly one file.', '--piece', piecePath, - '--create-worktree', - 'no', ], cwd: repo.path, env: { diff --git a/e2e/specs/team-leader-worker-pool.e2e.ts b/e2e/specs/team-leader-worker-pool.e2e.ts index d7e6015..4855c28 100644 --- a/e2e/specs/team-leader-worker-pool.e2e.ts +++ b/e2e/specs/team-leader-worker-pool.e2e.ts @@ -38,8 +38,6 @@ describe('E2E: Team leader worker-pool dynamic scheduling', () => { 'Create exactly five files: wp-1.txt, wp-2.txt, wp-3.txt, wp-4.txt, wp-5.txt. Each file must contain its own filename as content. Each part must create exactly one file, and you must complete all five files.', '--piece', piecePath, - '--create-worktree', - 'no', ], cwd: repo.path, env: isolatedEnv.env, diff --git a/e2e/specs/team-leader.e2e.ts b/e2e/specs/team-leader.e2e.ts index 14dd6ec..d558c44 100644 --- a/e2e/specs/team-leader.e2e.ts +++ b/e2e/specs/team-leader.e2e.ts @@ -45,7 +45,6 @@ describe('E2E: Team leader movement', () => { args: [ '--task', 'Create two files: hello-en.txt containing "Hello World" and hello-ja.txt containing "こんにちは世界"', '--piece', piecePath, - '--create-worktree', 'no', ], cwd: repo.path, env: isolatedEnv.env, diff --git a/e2e/specs/worktree.e2e.ts b/e2e/specs/worktree.e2e.ts index d8e6b51..9a95217 100644 --- a/e2e/specs/worktree.e2e.ts +++ b/e2e/specs/worktree.e2e.ts @@ -9,7 +9,7 @@ const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // E2E更新時は docs/testing/e2e.md も更新すること -describe('E2E: Worktree/Clone isolation (--create-worktree yes)', () => { +describe('E2E: Removed --create-worktree option', () => { let isolatedEnv: IsolatedEnv; let testRepo: TestRepo; @@ -31,7 +31,7 @@ describe('E2E: Worktree/Clone isolation (--create-worktree yes)', () => { } }); - it('should execute task in an isolated worktree/clone', () => { + it('should fail fast with migration guidance', () => { const piecePath = resolve(__dirname, '../fixtures/pieces/simple.yaml'); const result = runTakt({ @@ -45,7 +45,8 @@ describe('E2E: Worktree/Clone isolation (--create-worktree yes)', () => { timeout: 240_000, }); - // Task should succeed - expect(result.exitCode).toBe(0); + expect(result.exitCode).not.toBe(0); + const combined = result.stdout + result.stderr; + expect(combined).toContain('--create-worktree has been removed'); }, 240_000); }); diff --git a/src/__tests__/cli-routing-issue-resolve.test.ts b/src/__tests__/cli-routing-issue-resolve.test.ts index b5b3296..8426388 100644 --- a/src/__tests__/cli-routing-issue-resolve.test.ts +++ b/src/__tests__/cli-routing-issue-resolve.test.ts @@ -110,7 +110,6 @@ vi.mock('../app/cli/program.js', () => { vi.mock('../app/cli/helpers.js', () => ({ resolveAgentOverrides: vi.fn(), - parseCreateWorktreeOption: vi.fn(), isDirectTask: vi.fn(() => false), })); @@ -120,7 +119,7 @@ import { interactiveMode } from '../features/interactive/index.js'; import { resolveConfigValues, loadPersonaSessions } from '../infra/config/index.js'; import { isDirectTask } from '../app/cli/helpers.js'; import { executeDefaultAction } from '../app/cli/routing.js'; -import { info } from '../shared/ui/index.js'; +import { info, error } from '../shared/ui/index.js'; import type { Issue } from '../infra/git/index.js'; const mockFormatIssueAsTask = vi.mocked(formatIssueAsTask); @@ -133,6 +132,7 @@ const mockLoadPersonaSessions = vi.mocked(loadPersonaSessions); const mockResolveConfigValues = vi.mocked(resolveConfigValues); const mockIsDirectTask = vi.mocked(isDirectTask); const mockInfo = vi.mocked(info); +const mockError = vi.mocked(error); const mockTaskRunnerListAllTaskItems = vi.mocked(mockListAllTaskItems); function createMockIssue(number: number): Issue { @@ -161,6 +161,43 @@ beforeEach(() => { }); describe('Issue resolution in routing', () => { + it('should show error and exit when --auto-pr/--draft are used outside pipeline mode', async () => { + mockOpts.autoPr = true; + mockOpts.draft = true; + + const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => { + throw new Error('process.exit called'); + }); + + await expect(executeDefaultAction()).rejects.toThrow('process.exit called'); + + expect(mockError).toHaveBeenCalledWith('--auto-pr/--draft are supported only in --pipeline mode'); + expect(mockExit).toHaveBeenCalledWith(1); + expect(mockInteractiveMode).not.toHaveBeenCalled(); + expect(mockSelectAndExecuteTask).not.toHaveBeenCalled(); + + mockExit.mockRestore(); + }); + + it('should show migration error and exit when deprecated --create-worktree is used', async () => { + mockOpts.createWorktree = 'yes'; + + const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => { + throw new Error('process.exit called'); + }); + + await expect(executeDefaultAction()).rejects.toThrow('process.exit called'); + + expect(mockError).toHaveBeenCalledWith( + '--create-worktree has been removed. execute now always runs in-place. Use "takt add" (save_task) + "takt run" for worktree-based execution.' + ); + expect(mockExit).toHaveBeenCalledWith(1); + expect(mockInteractiveMode).not.toHaveBeenCalled(); + expect(mockSelectAndExecuteTask).not.toHaveBeenCalled(); + + mockExit.mockRestore(); + }); + describe('--issue option', () => { it('should resolve issue and pass to interactive mode when --issue is specified', async () => { // Given diff --git a/src/__tests__/cli-routing-pr-resolve.test.ts b/src/__tests__/cli-routing-pr-resolve.test.ts index 9bd20ef..8e77ccd 100644 --- a/src/__tests__/cli-routing-pr-resolve.test.ts +++ b/src/__tests__/cli-routing-pr-resolve.test.ts @@ -112,7 +112,6 @@ vi.mock('../app/cli/program.js', () => { vi.mock('../app/cli/helpers.js', () => ({ resolveAgentOverrides: vi.fn(), - parseCreateWorktreeOption: vi.fn(), isDirectTask: vi.fn(() => false), })); diff --git a/src/__tests__/selectAndExecute-autoPr.test.ts b/src/__tests__/selectAndExecute-autoPr.test.ts index 0418f8b..29eaa95 100644 --- a/src/__tests__/selectAndExecute-autoPr.test.ts +++ b/src/__tests__/selectAndExecute-autoPr.test.ts @@ -1,5 +1,5 @@ /** - * Tests for resolveAutoPr default behavior in selectAndExecuteTask + * Tests for selectAndExecuteTask behavior in execute path */ import { describe, it, expect, vi, beforeEach } from 'vitest'; @@ -25,10 +25,6 @@ const { mockResolvePieceConfigValue: vi.fn((_: string, key: string) => (key === 'autoPr' ? undefined : 'default')), })); -vi.mock('../shared/prompt/index.js', () => ({ - confirm: vi.fn(), -})); - vi.mock('../infra/config/index.js', () => ({ resolvePieceConfigValue: (...args: unknown[]) => mockResolvePieceConfigValue(...args), listPieces: vi.fn(() => ['default']), @@ -86,17 +82,13 @@ vi.mock('../features/pieceSelection/index.js', () => ({ selectPiece: vi.fn(), })); -import { confirm } from '../shared/prompt/index.js'; import { loadPieceByIdentifier } from '../infra/config/index.js'; -import { createSharedClone, autoCommitAndPush, summarizeTaskName } from '../infra/task/index.js'; +import { autoCommitAndPush } 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); const mockSelectPiece = vi.mocked(selectPiece); beforeEach(() => { @@ -104,74 +96,14 @@ beforeEach(() => { mockExecuteTask.mockResolvedValue(true); }); -describe('resolveAutoPr default in selectAndExecuteTask', () => { - it('should call auto-PR confirm with default true when no CLI option or config', async () => { - // Given: worktree is enabled via override, no autoPr option, no config autoPr - mockConfirm.mockResolvedValue(true); - mockSummarizeTaskName.mockResolvedValue('test-task'); - mockCreateSharedClone.mockReturnValue({ - path: '/project/../clone', - branch: 'takt/test-task', - }); - - mockAutoCommitAndPush.mockReturnValue({ - success: false, - message: 'no changes', - }); - - // When +describe('selectAndExecuteTask (execute path)', () => { + it('should execute in-place without worktree setup or PR prompts', async () => { await selectAndExecuteTask('/project', 'test task', { piece: 'default', - createWorktree: true, }); - const autoPrCall = mockConfirm.mock.calls.find((call) => call[0] === 'Create pull request?'); - expect(autoPrCall).toBeDefined(); - expect(autoPrCall![1]).toBe(true); - }); - - it('shouldCreatePr=true の場合、"Create as draft?" プロンプトが表示される', async () => { - // confirm はすべての呼び出しに対して true を返す(autoPr=true → draftPr prompt) - mockConfirm.mockResolvedValue(true); - mockSummarizeTaskName.mockResolvedValue('test-task'); - mockCreateSharedClone.mockReturnValue({ - path: '/project/../clone', - branch: 'takt/test-task', - }); - mockAutoCommitAndPush.mockReturnValue({ - success: false, - message: 'no changes', - }); - - await selectAndExecuteTask('/project', 'test task', { - piece: 'default', - createWorktree: true, - }); - - const draftPrCall = mockConfirm.mock.calls.find((call) => call[0] === 'Create as draft?'); - expect(draftPrCall).toBeDefined(); - expect(draftPrCall![1]).toBe(true); - }); - - it('shouldCreatePr=false の場合、"Create as draft?" プロンプトは表示されない', async () => { - mockConfirm.mockResolvedValue(false); // autoPr=false → draft prompt skipped - mockSummarizeTaskName.mockResolvedValue('test-task'); - mockCreateSharedClone.mockReturnValue({ - path: '/project/../clone', - branch: 'takt/test-task', - }); - mockAutoCommitAndPush.mockReturnValue({ - success: false, - message: 'no changes', - }); - - await selectAndExecuteTask('/project', 'test task', { - piece: 'default', - createWorktree: true, - }); - - const draftPrCall = mockConfirm.mock.calls.find((call) => call[0] === 'Create as draft?'); - expect(draftPrCall).toBeUndefined(); + expect(mockAutoCommitAndPush).not.toHaveBeenCalled(); + expect(mockAddTask).toHaveBeenCalledWith('test task', { piece: 'default' }); }); it('should call selectPiece when no override is provided', async () => { @@ -192,17 +124,10 @@ describe('resolveAutoPr default in selectAndExecuteTask', () => { }); it('should fail task record when executeTask throws', async () => { - mockConfirm.mockResolvedValue(true); - mockSummarizeTaskName.mockResolvedValue('test-task'); - mockCreateSharedClone.mockReturnValue({ - path: '/project/../clone', - branch: 'takt/test-task', - }); mockExecuteTask.mockRejectedValue(new Error('boom')); await expect(selectAndExecuteTask('/project', 'test task', { piece: 'default', - createWorktree: true, })).rejects.toThrow('boom'); expect(mockAddTask).toHaveBeenCalledTimes(1); @@ -211,38 +136,18 @@ describe('resolveAutoPr default in selectAndExecuteTask', () => { }); it('should record task and complete when executeTask returns true', async () => { - mockConfirm.mockResolvedValue(true); - mockSummarizeTaskName.mockResolvedValue('test-task'); - mockCreateSharedClone.mockReturnValue({ - path: '/project/../clone', - branch: 'takt/test-task', - }); mockExecuteTask.mockResolvedValue(true); await selectAndExecuteTask('/project', 'test task', { piece: 'default', - createWorktree: true, }); - expect(mockAddTask).toHaveBeenCalledWith('test task', expect.objectContaining({ - piece: 'default', - worktree: true, - branch: 'takt/test-task', - worktree_path: '/project/../clone', - auto_pr: true, - draft_pr: true, - })); + expect(mockAddTask).toHaveBeenCalledWith('test task', { piece: 'default' }); expect(mockCompleteTask).toHaveBeenCalledTimes(1); expect(mockFailTask).not.toHaveBeenCalled(); }); it('should record task and fail when executeTask returns false', async () => { - mockConfirm.mockResolvedValue(false); - mockSummarizeTaskName.mockResolvedValue('test-task'); - mockCreateSharedClone.mockReturnValue({ - path: '/project/../clone', - branch: 'takt/test-task', - }); mockExecuteTask.mockResolvedValue(false); const processExitSpy = vi.spyOn(process, 'exit').mockImplementation((() => { @@ -251,16 +156,9 @@ describe('resolveAutoPr default in selectAndExecuteTask', () => { await expect(selectAndExecuteTask('/project', 'test task', { piece: 'default', - createWorktree: true, })).rejects.toThrow('process exit'); - expect(mockAddTask).toHaveBeenCalledWith('test task', expect.objectContaining({ - piece: 'default', - worktree: true, - branch: 'takt/test-task', - worktree_path: '/project/../clone', - auto_pr: false, - })); + expect(mockAddTask).toHaveBeenCalledWith('test task', { piece: 'default' }); expect(mockFailTask).toHaveBeenCalledTimes(1); expect(mockCompleteTask).not.toHaveBeenCalled(); processExitSpy.mockRestore(); diff --git a/src/__tests__/selectAndExecute-skipTaskList.test.ts b/src/__tests__/selectAndExecute-skipTaskList.test.ts index 3e994f9..f426914 100644 --- a/src/__tests__/selectAndExecute-skipTaskList.test.ts +++ b/src/__tests__/selectAndExecute-skipTaskList.test.ts @@ -26,7 +26,6 @@ const { })); vi.mock('../shared/prompt/index.js', () => ({ - confirm: vi.fn(), })); vi.mock('../infra/config/index.js', () => ({ @@ -85,16 +84,11 @@ vi.mock('../features/pieceSelection/index.js', () => ({ selectPiece: vi.fn(), })); -import { confirm } from '../shared/prompt/index.js'; import { selectAndExecuteTask } from '../features/tasks/execute/selectAndExecute.js'; -const mockConfirm = vi.mocked(confirm); - beforeEach(() => { vi.clearAllMocks(); mockExecuteTask.mockResolvedValue(true); - // worktree を使わない(confirm で false) - mockConfirm.mockResolvedValue(false); }); describe('skipTaskList option in selectAndExecuteTask', () => { diff --git a/src/app/cli/helpers.ts b/src/app/cli/helpers.ts index 2b5adce..ccbf448 100644 --- a/src/app/cli/helpers.ts +++ b/src/app/cli/helpers.ts @@ -7,7 +7,6 @@ import type { Command } from 'commander'; import type { TaskExecutionOptions } from '../../features/tasks/index.js'; import type { ProviderType } from '../../infra/providers/index.js'; -import { error } from '../../shared/ui/index.js'; import { isIssueReference } from '../../infra/github/index.js'; /** @@ -26,28 +25,6 @@ export function resolveAgentOverrides(program: Command): TaskExecutionOptions | return { provider, model }; } -/** - * Parse --create-worktree option value (yes/no/true/false). - * Returns undefined if not specified, boolean otherwise. - * Exits with error on invalid value. - */ -export function parseCreateWorktreeOption(value?: string): boolean | undefined { - if (!value) { - return undefined; - } - - const normalized = value.toLowerCase(); - if (normalized === 'yes' || normalized === 'true') { - return true; - } - if (normalized === 'no' || normalized === 'false') { - return false; - } - - error('Invalid value for --create-worktree. Use yes or no.'); - process.exit(1); -} - /** * Check if the input is a task description that should execute directly * vs one that should enter interactive mode. diff --git a/src/app/cli/program.ts b/src/app/cli/program.ts index be27a9b..9fe0108 100644 --- a/src/app/cli/program.ts +++ b/src/app/cli/program.ts @@ -6,7 +6,7 @@ */ import { createRequire } from 'node:module'; -import { Command } from 'commander'; +import { Command, Option } from 'commander'; import { resolve } from 'node:path'; import { initGlobalDirs, @@ -52,7 +52,8 @@ program .option('-t, --task ', 'Task content (as alternative to GitHub issue)') .option('--pipeline', 'Pipeline mode: non-interactive, no worktree, direct branch creation') .option('--skip-git', 'Skip branch creation, commit, and push (pipeline mode)') - .option('--create-worktree ', 'Skip the worktree prompt by explicitly specifying yes or no') + // Deprecated compatibility option: keep parsing to show migration guidance. + .addOption(new Option('--create-worktree ').hideHelp()) .option('-q, --quiet', 'Minimal output mode: suppress AI output (for CI)') .option('-c, --continue', 'Continue from the last assistant session'); diff --git a/src/app/cli/routing.ts b/src/app/cli/routing.ts index 648e583..4dc6911 100644 --- a/src/app/cli/routing.ts +++ b/src/app/cli/routing.ts @@ -25,7 +25,7 @@ import { } from '../../features/interactive/index.js'; import { getPieceDescription, resolveConfigValue, resolveConfigValues, loadPersonaSessions } from '../../infra/config/index.js'; import { program, resolvedCwd, pipelineMode } from './program.js'; -import { resolveAgentOverrides, parseCreateWorktreeOption, isDirectTask } from './helpers.js'; +import { resolveAgentOverrides, isDirectTask } from './helpers.js'; import { loadTaskHistory } from './taskHistory.js'; /** @@ -113,6 +113,18 @@ async function resolvePrInput( */ export async function executeDefaultAction(task?: string): Promise { const opts = program.opts(); + if (opts.createWorktree !== undefined) { + logError( + '--create-worktree has been removed. ' + + 'execute now always runs in-place. ' + + 'Use "takt add" (save_task) + "takt run" for worktree-based execution.' + ); + process.exit(1); + } + if (!pipelineMode && (opts.autoPr === true || opts.draft === true)) { + logError('--auto-pr/--draft are supported only in --pipeline mode'); + process.exit(1); + } const prNumber = opts.pr as number | undefined; const issueNumber = opts.issue as number | undefined; @@ -125,9 +137,7 @@ export async function executeDefaultAction(task?: string): Promise { logError('--pr and --task cannot be used together'); process.exit(1); } - const agentOverrides = resolveAgentOverrides(program); - const createWorktreeOverride = parseCreateWorktreeOption(opts.createWorktree as string | undefined); const resolvedPipelinePiece = (opts.piece as string | undefined) ?? resolveConfigValue(resolvedCwd, 'piece'); const resolvedPipelineAutoPr = opts.autoPr === true ? true @@ -136,11 +146,8 @@ export async function executeDefaultAction(task?: string): Promise { ? true : (resolveConfigValue(resolvedCwd, 'draftPr') ?? false); const selectOptions: SelectAndExecuteOptions = { - autoPr: opts.autoPr === true ? true : undefined, - draftPr: opts.draft === true ? true : undefined, repo: opts.repo as string | undefined, piece: opts.piece as string | undefined, - createWorktree: createWorktreeOverride, }; // --- Pipeline mode (non-interactive): triggered by --pipeline --- @@ -158,7 +165,6 @@ export async function executeDefaultAction(task?: string): Promise { cwd: resolvedCwd, provider: agentOverrides?.provider, model: agentOverrides?.model, - createWorktree: createWorktreeOverride, }); if (exitCode !== 0) { diff --git a/src/features/tasks/execute/selectAndExecute.ts b/src/features/tasks/execute/selectAndExecute.ts index 965a798..5fda6d0 100644 --- a/src/features/tasks/execute/selectAndExecute.ts +++ b/src/features/tasks/execute/selectAndExecute.ts @@ -1,7 +1,7 @@ /** * Task execution orchestration. * - * Coordinates piece selection, worktree creation, task execution, + * Coordinates piece selection and task execution, * auto-commit, and PR creation. Extracted from cli.ts to avoid * mixing CLI parsing with business logic. */ @@ -15,7 +15,6 @@ import { createSharedClone, summarizeTaskName, resolveBaseBranch, TaskRunner } f import { info, error, withProgress } from '../../../shared/ui/index.js'; import { createLogger } from '../../../shared/utils/index.js'; import { executeTask } from './taskExecution.js'; -import { resolveAutoPr, resolveDraftPr, postExecutionFlow } from './postExecution.js'; import type { TaskExecutionOptions, WorktreeConfirmationResult, SelectAndExecuteOptions } from './types.js'; import { selectPiece } from '../../pieceSelection/index.js'; import { buildBooleanTaskResult, persistTaskError, persistTaskResult } from './taskResultHandler.js'; @@ -76,7 +75,7 @@ export async function confirmAndCreateWorktree( } /** - * Execute a task with piece selection, optional worktree, and auto-commit. + * Execute a task with piece selection. * Shared by direct task execution and interactive mode. */ export async function selectAndExecuteTask( @@ -92,35 +91,14 @@ export async function selectAndExecuteTask( return; } - const { execCwd, isWorktree, branch, baseBranch, taskSlug } = await confirmAndCreateWorktree( - cwd, - task, - options?.createWorktree, - options?.branch, - ); - - // Ask for PR creation BEFORE execution (only if worktree is enabled) - let shouldCreatePr = false; - let shouldDraftPr = false; - if (isWorktree) { - shouldCreatePr = await resolveAutoPr(options?.autoPr, cwd); - if (shouldCreatePr) { - shouldDraftPr = await resolveDraftPr(options?.draftPr, cwd); - } - } - - log.info('Starting task execution', { piece: pieceIdentifier, worktree: isWorktree, autoPr: shouldCreatePr, draftPr: shouldDraftPr }); + // execute action always runs in-place (no worktree prompt/creation). + const execCwd = cwd; + log.info('Starting task execution', { piece: pieceIdentifier, worktree: false }); const taskRunner = new TaskRunner(cwd); let taskRecord: Awaited> | null = null; - if (options?.skipTaskList !== true || isWorktree) { + if (options?.skipTaskList !== true) { taskRecord = taskRunner.addTask(task, { piece: pieceIdentifier, - ...(isWorktree ? { worktree: true } : {}), - ...(branch ? { branch } : {}), - ...(isWorktree ? { worktree_path: execCwd } : {}), - auto_pr: shouldCreatePr, - draft_pr: shouldDraftPr, - ...(taskSlug ? { slug: taskSlug } : {}), }); } const startedAt = new Date().toISOString(); @@ -148,36 +126,15 @@ export async function selectAndExecuteTask( const completedAt = new Date().toISOString(); - let prFailed = false; - let prError: string | undefined; - if (taskSuccess && isWorktree) { - const postResult = await postExecutionFlow({ - execCwd, - projectCwd: cwd, - task, - branch, - baseBranch, - shouldCreatePr, - draftPr: shouldDraftPr, - pieceIdentifier, - issues: options?.issues, - repo: options?.repo, - }); - prFailed = postResult.prFailed ?? false; - prError = postResult.prError; - } - - const effectiveSuccess = taskSuccess && !prFailed; + const effectiveSuccess = taskSuccess; if (taskRecord) { const taskResult = buildBooleanTaskResult({ task: taskRecord, taskSuccess: effectiveSuccess, successResponse: 'Task completed successfully', - failureResponse: prFailed ? `PR creation failed: ${prError}` : 'Task failed', + failureResponse: 'Task failed', startedAt, completedAt, - branch, - ...(isWorktree ? { worktreePath: execCwd } : {}), }); persistTaskResult(taskRunner, taskResult); } diff --git a/src/features/tasks/execute/types.ts b/src/features/tasks/execute/types.ts index ae1dd44..78a1b34 100644 --- a/src/features/tasks/execute/types.ts +++ b/src/features/tasks/execute/types.ts @@ -136,11 +136,8 @@ export interface WorktreeConfirmationResult { } export interface SelectAndExecuteOptions { - autoPr?: boolean; - draftPr?: boolean; repo?: string; piece?: string; - createWorktree?: boolean | undefined; /** Override branch name (e.g., PR head branch for --pr) */ branch?: string; /** Enable interactive user input during step transitions */