From d1956b53acb1c20b12ed3c608d64444faf691617 Mon Sep 17 00:00:00 2001 From: nrslib <38722970+nrslib@users.noreply.github.com> Date: Thu, 29 Jan 2026 14:22:57 +0900 Subject: [PATCH] =?UTF-8?q?takt:=20review=E3=81=98=E3=82=83=E3=81=AA?= =?UTF-8?q?=E3=81=8F=E3=81=A6list=E3=81=AB=E3=81=97=E3=81=9F=E3=81=84?= =?UTF-8?q?=E3=80=82list=E3=81=A8list-tasks=E3=81=A8=E3=81=84=E3=81=86?= =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89=E3=81=AB=E3=81=8B=E3=81=88?= =?UTF-8?q?=E3=81=A6=E3=81=8F=E3=82=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CLAUDE.md | 6 +-- README.md | 12 ++--- docs/README.ja.md | 2 +- src/__tests__/cli-worktree.test.ts | 2 +- src/__tests__/getOriginalInstruction.test.ts | 2 +- ...{reviewTasks.test.ts => listTasks.test.ts} | 20 ++++----- src/cli.ts | 10 ++--- src/commands/help.ts | 4 +- src/commands/index.ts | 2 +- src/commands/{reviewTasks.ts => listTasks.ts} | 44 +++++++++---------- src/task/{branchReview.ts => branchList.ts} | 16 +++---- src/task/index.ts | 6 +-- 12 files changed, 63 insertions(+), 63 deletions(-) rename src/__tests__/{reviewTasks.test.ts => listTasks.test.ts} (90%) rename src/commands/{reviewTasks.ts => listTasks.ts} (91%) rename src/task/{branchReview.ts => branchList.ts} (93%) diff --git a/CLAUDE.md b/CLAUDE.md index 1cad2f9..5487825 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -24,7 +24,7 @@ TAKT (Task Agent Koordination Tool) is a multi-agent orchestration system for Cl | `takt /run-tasks` | `/run` | Execute all pending tasks from `.takt/tasks/` once | | `takt /watch` | | Watch `.takt/tasks/` and auto-execute tasks (resident process) | | `takt /add-task` | `/add` | Add a new task interactively (YAML format, multiline supported) | -| `takt /review-tasks` | `/review` | Review task branches (try merge, merge & cleanup, or delete) | +| `takt /list-tasks` | `/list` | List task branches (try merge, merge & cleanup, or delete) | | `takt /switch` | | Switch workflow interactively | | `takt /clear` | | Clear agent conversation sessions (reset state) | | `takt /refresh-builtin` | | Update builtin resources from `resources/` to `~/.takt/` | @@ -37,7 +37,7 @@ TAKT (Task Agent Koordination Tool) is a multi-agent orchestration system for Cl ``` CLI (cli.ts) - → Slash commands (/run-tasks, /watch, /add-task, /switch, /clear, /refresh-builtin, /help, /config) + → Slash commands (/run-tasks, /watch, /add-task, /list-tasks, /switch, /clear, /refresh-builtin, /help, /config) → or executeTask() → WorkflowEngine (workflow/engine.ts) → runAgent() (agents/runner.ts) @@ -199,7 +199,7 @@ Key constraints: - **Session isolation**: Claude Code sessions are stored per-cwd in `~/.claude/projects/{encoded-path}/`. Sessions from the main project cannot be resumed in a clone. The engine skips session resume when `cwd !== projectCwd`. - **No node_modules**: Clones only contain tracked files. `node_modules/` is absent. - **Dual cwd**: `cwd` = clone path (where agents run), `projectCwd` = project root (where `.takt/` lives). Reports, logs, and session data always write to `projectCwd`. -- **Review**: Use `takt /review-tasks` to review branches. Instruct action creates a temporary clone for the branch, executes, pushes, then removes the clone. +- **List**: Use `takt /list-tasks` to list branches. Instruct action creates a temporary clone for the branch, executes, pushes, then removes the clone. ## Error Propagation diff --git a/README.md b/README.md index 9bcb9f4..a48f4f7 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,8 @@ takt /run-tasks # Watch for tasks and auto-execute takt /watch -# Review task branches (merge or delete) -takt /review-tasks +# List task branches (merge or delete) +takt /list-tasks # Switch workflow takt /switch @@ -51,7 +51,7 @@ takt /switch | `takt /run-tasks` | `/run` | Run all pending tasks from `.takt/tasks/` | | `takt /watch` | | Watch `.takt/tasks/` and auto-execute tasks (stays resident) | | `takt /add-task` | `/add` | Add a new task interactively (YAML format, multiline supported) | -| `takt /review-tasks` | `/review` | Review task branches (try merge, merge & cleanup, or delete) | +| `takt /list-tasks` | `/list` | List task branches (try merge, merge & cleanup, or delete) | | `takt /switch` | | Switch workflow interactively | | `takt /clear` | | Clear agent conversation sessions | | `takt /refresh-builtin` | | Update builtin agents/workflows to latest version | @@ -353,7 +353,7 @@ YAML task files can specify `worktree` to run each task in an isolated `git clon > **Note**: The YAML field is named `worktree` for backward compatibility. Internally, `git clone --shared` is used instead of `git worktree` because git worktrees have a `.git` file with `gitdir:` that points back to the main repository, causing Claude Code to recognize the main repo as the project root. Shared clones have an independent `.git` directory that avoids this issue. -Clones are ephemeral. When a task completes successfully, TAKT automatically commits all changes and pushes the branch to the main repository, then deletes the clone. Use `takt /review-tasks` to review, try-merge, or delete task branches. +Clones are ephemeral. When a task completes successfully, TAKT automatically commits all changes and pushes the branch to the main repository, then deletes the clone. Use `takt /list-tasks` to list, try-merge, or delete task branches. #### Running Tasks with `/run-tasks` @@ -376,10 +376,10 @@ Watch mode polls `.takt/tasks/` for new task files and auto-executes them as the - Automated workflows where tasks are added by external processes - Long-running development sessions where tasks are queued over time -#### Reviewing Task Branches with `/review-tasks` +#### Listing Task Branches with `/list-tasks` ```bash -takt /review-tasks +takt /list-tasks ``` Lists all `takt/`-prefixed branches with file change counts. For each branch you can: diff --git a/docs/README.ja.md b/docs/README.ja.md index 0d8f2b3..a0f0b79 100644 --- a/docs/README.ja.md +++ b/docs/README.ja.md @@ -116,7 +116,7 @@ YAMLタスクファイルで`worktree`を指定すると、各タスクを`git c > **Note**: YAMLフィールド名は後方互換のため`worktree`のままです。内部的には`git worktree`ではなく`git clone --shared`を使用しています。git worktreeの`.git`ファイルには`gitdir:`でメインリポジトリへのパスが記載されており、Claude Codeがそれを辿ってメインリポジトリをプロジェクトルートと認識してしまうためです。共有クローンは独立した`.git`ディレクトリを持つため、この問題が発生しません。 -クローンは使い捨てです。タスク完了後に自動的にコミット+プッシュし、クローンを削除します。ブランチが唯一の永続的な成果物です。`takt /review-tasks`でブランチのレビュー・マージ・削除ができます。 +クローンは使い捨てです。タスク完了後に自動的にコミット+プッシュし、クローンを削除します。ブランチが唯一の永続的な成果物です。`takt /list-tasks`でブランチの一覧表示・マージ・削除ができます。 #### `/run-tasks` でタスクを実行 diff --git a/src/__tests__/cli-worktree.test.ts b/src/__tests__/cli-worktree.test.ts index 8f55185..fc18013 100644 --- a/src/__tests__/cli-worktree.test.ts +++ b/src/__tests__/cli-worktree.test.ts @@ -65,7 +65,7 @@ vi.mock('../commands/index.js', () => ({ addTask: vi.fn(), refreshBuiltin: vi.fn(), watchTasks: vi.fn(), - reviewTasks: vi.fn(), + listTasks: vi.fn(), })); vi.mock('../config/workflowLoader.js', () => ({ diff --git a/src/__tests__/getOriginalInstruction.test.ts b/src/__tests__/getOriginalInstruction.test.ts index f00cc1d..56f3c43 100644 --- a/src/__tests__/getOriginalInstruction.test.ts +++ b/src/__tests__/getOriginalInstruction.test.ts @@ -12,7 +12,7 @@ vi.mock('node:child_process', () => ({ import { execFileSync } from 'node:child_process'; const mockExecFileSync = vi.mocked(execFileSync); -import { getOriginalInstruction } from '../task/branchReview.js'; +import { getOriginalInstruction } from '../task/branchList.js'; beforeEach(() => { vi.clearAllMocks(); diff --git a/src/__tests__/reviewTasks.test.ts b/src/__tests__/listTasks.test.ts similarity index 90% rename from src/__tests__/reviewTasks.test.ts rename to src/__tests__/listTasks.test.ts index 383715b..c620fac 100644 --- a/src/__tests__/reviewTasks.test.ts +++ b/src/__tests__/listTasks.test.ts @@ -1,15 +1,15 @@ /** - * Tests for review-tasks command + * Tests for list-tasks command */ import { describe, it, expect, vi } from 'vitest'; import { parseTaktBranches, extractTaskSlug, - buildReviewItems, + buildListItems, type BranchInfo, -} from '../task/branchReview.js'; -import { isBranchMerged, showFullDiff, type ReviewAction } from '../commands/reviewTasks.js'; +} from '../task/branchList.js'; +import { isBranchMerged, showFullDiff, type ListAction } from '../commands/listTasks.js'; describe('parseTaktBranches', () => { it('should parse takt/ branches from git branch output', () => { @@ -92,7 +92,7 @@ describe('extractTaskSlug', () => { }); }); -describe('buildReviewItems', () => { +describe('buildListItems', () => { it('should build items with correct task slug and originalInstruction', () => { const branches: BranchInfo[] = [ { @@ -101,7 +101,7 @@ describe('buildReviewItems', () => { }, ]; - const items = buildReviewItems('/project', branches, 'main'); + const items = buildListItems('/project', branches, 'main'); expect(items).toHaveLength(1); expect(items[0]!.taskSlug).toBe('fix-auth'); expect(items[0]!.info).toBe(branches[0]); @@ -123,21 +123,21 @@ describe('buildReviewItems', () => { }, ]; - const items = buildReviewItems('/project', branches, 'main'); + const items = buildListItems('/project', branches, 'main'); expect(items).toHaveLength(2); expect(items[0]!.taskSlug).toBe('fix-auth'); expect(items[1]!.taskSlug).toBe('add-search'); }); it('should handle empty branch list', () => { - const items = buildReviewItems('/project', [], 'main'); + const items = buildListItems('/project', [], 'main'); expect(items).toHaveLength(0); }); }); -describe('ReviewAction type', () => { +describe('ListAction type', () => { it('should include diff, instruct, try, merge, delete (no skip)', () => { - const actions: ReviewAction[] = ['diff', 'instruct', 'try', 'merge', 'delete']; + const actions: ListAction[] = ['diff', 'instruct', 'try', 'merge', 'delete']; expect(actions).toHaveLength(5); expect(actions).toContain('diff'); expect(actions).toContain('instruct'); diff --git a/src/cli.ts b/src/cli.ts index 276b12f..9ebe5b3 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -32,7 +32,7 @@ import { addTask, refreshBuiltin, watchTasks, - reviewTasks, + listTasks, } from './commands/index.js'; import { listWorkflows } from './config/workflowLoader.js'; import { selectOptionWithDefault, confirm } from './prompt/index.js'; @@ -167,14 +167,14 @@ program await watchTasks(cwd); return; - case 'review-tasks': - case 'review': - await reviewTasks(cwd); + case 'list-tasks': + case 'list': + await listTasks(cwd); return; default: error(`Unknown command: /${command}`); - info('Available: /run-tasks (/run), /watch, /add-task (/add), /review-tasks (/review), /switch (/sw), /clear, /refresh-builtin, /help, /config'); + info('Available: /run-tasks (/run), /watch, /add-task (/add), /list-tasks (/list), /switch (/sw), /clear, /refresh-builtin, /help, /config'); process.exit(1); } } diff --git a/src/commands/help.ts b/src/commands/help.ts index 5e74ba2..66defef 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -17,7 +17,7 @@ Usage: takt /run-tasks (/run) Run all pending tasks from .takt/tasks/ takt /watch Watch for tasks and auto-execute (stays resident) takt /add-task (/add) Add a new task (interactive, YAML format) - takt /review-tasks (/review) Review task branches (merge/delete) + takt /list-tasks (/list) List task branches (merge/delete) takt /switch Switch workflow interactively takt /clear Clear agent conversation sessions (reset to initial state) takt /refresh-builtin Overwrite builtin agents/workflows with latest version @@ -30,7 +30,7 @@ Examples: takt /clear # Clear sessions, start fresh takt /watch # Watch & auto-execute tasks takt /refresh-builtin # Update builtin resources - takt /review-tasks # Review & merge task branches + takt /list-tasks # List & merge task branches takt /switch takt /run-tasks diff --git a/src/commands/index.ts b/src/commands/index.ts index ac3e89f..af84605 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -11,4 +11,4 @@ export { showHelp } from './help.js'; export { withAgentSession } from './session.js'; export { switchWorkflow } from './workflow.js'; export { switchConfig, getCurrentPermissionMode, setPermissionMode, type PermissionMode } from './config.js'; -export { reviewTasks } from './reviewTasks.js'; +export { listTasks } from './listTasks.js'; diff --git a/src/commands/reviewTasks.ts b/src/commands/listTasks.ts similarity index 91% rename from src/commands/reviewTasks.ts rename to src/commands/listTasks.ts index 4965a02..4bade02 100644 --- a/src/commands/reviewTasks.ts +++ b/src/commands/listTasks.ts @@ -1,5 +1,5 @@ /** - * Review tasks command + * List tasks command * * Interactive UI for reviewing branch-based task results: * try merge, merge & cleanup, or delete actions. @@ -17,9 +17,9 @@ import { import { detectDefaultBranch, listTaktBranches, - buildReviewItems, - type BranchReviewItem, -} from '../task/branchReview.js'; + buildListItems, + type BranchListItem, +} from '../task/branchList.js'; import { autoCommitAndPush } from '../task/autoCommit.js'; import { selectOption, confirm, promptInput } from '../prompt/index.js'; import { info, success, error as logError, warn } from '../utils/ui.js'; @@ -29,10 +29,10 @@ import { listWorkflows } from '../config/workflowLoader.js'; import { getCurrentWorkflow } from '../config/paths.js'; import { DEFAULT_WORKFLOW_NAME } from '../constants.js'; -const log = createLogger('review-tasks'); +const log = createLogger('list-tasks'); -/** Actions available for a reviewed branch */ -export type ReviewAction = 'diff' | 'instruct' | 'try' | 'merge' | 'delete'; +/** Actions available for a listed branch */ +export type ListAction = 'diff' | 'instruct' | 'try' | 'merge' | 'delete'; /** * Check if a branch has already been merged into HEAD. @@ -78,8 +78,8 @@ export function showFullDiff( async function showDiffAndPromptAction( cwd: string, defaultBranch: string, - item: BranchReviewItem, -): Promise { + item: BranchListItem, +): Promise { console.log(); console.log(chalk.bold.cyan(`=== ${item.info.branch} ===`)); if (item.originalInstruction) { @@ -99,7 +99,7 @@ async function showDiffAndPromptAction( } // Prompt action - const action = await selectOption( + const action = await selectOption( `Action for ${item.info.branch}:`, [ { label: 'View diff', value: 'diff', description: 'Show full diff in pager' }, @@ -117,7 +117,7 @@ async function showDiffAndPromptAction( * Try-merge (squash): stage changes from branch without committing. * User can inspect staged changes and commit manually if satisfied. */ -export function tryMergeBranch(projectDir: string, item: BranchReviewItem): boolean { +export function tryMergeBranch(projectDir: string, item: BranchListItem): boolean { const { branch } = item.info; try { @@ -145,7 +145,7 @@ export function tryMergeBranch(projectDir: string, item: BranchReviewItem): bool * Otherwise merge first, then delete the branch. * No worktree removal needed — clones are ephemeral. */ -export function mergeBranch(projectDir: string, item: BranchReviewItem): boolean { +export function mergeBranch(projectDir: string, item: BranchListItem): boolean { const { branch } = item.info; const alreadyMerged = isBranchMerged(projectDir, branch); @@ -192,7 +192,7 @@ export function mergeBranch(projectDir: string, item: BranchReviewItem): boolean * Delete a branch (discard changes). * No worktree removal needed — clones are ephemeral. */ -export function deleteBranch(projectDir: string, item: BranchReviewItem): boolean { +export function deleteBranch(projectDir: string, item: BranchListItem): boolean { const { branch } = item.info; try { @@ -291,7 +291,7 @@ function getBranchContext(projectDir: string, branch: string): string { */ export async function instructBranch( projectDir: string, - item: BranchReviewItem, + item: BranchListItem, ): Promise { const { branch } = item.info; @@ -349,22 +349,22 @@ export async function instructBranch( } /** - * Main entry point: review branch-based tasks interactively. + * Main entry point: list branch-based tasks interactively. */ -export async function reviewTasks(cwd: string): Promise { - log.info('Starting review-tasks'); +export async function listTasks(cwd: string): Promise { + log.info('Starting list-tasks'); const defaultBranch = detectDefaultBranch(cwd); let branches = listTaktBranches(cwd); if (branches.length === 0) { - info('No tasks to review.'); + info('No tasks to list.'); return; } // Interactive loop while (branches.length > 0) { - const items = buildReviewItems(cwd, branches, defaultBranch); + const items = buildListItems(cwd, branches, defaultBranch); // Build selection options const options = items.map((item, idx) => { @@ -380,7 +380,7 @@ export async function reviewTasks(cwd: string): Promise { }); const selected = await selectOption( - 'Review Tasks (Branches)', + 'List Tasks (Branches)', options, ); @@ -393,7 +393,7 @@ export async function reviewTasks(cwd: string): Promise { if (!item) continue; // Action loop: re-show menu after viewing diff - let action: ReviewAction | null; + let action: ListAction | null; do { action = await showDiffAndPromptAction(cwd, defaultBranch, item); @@ -430,5 +430,5 @@ export async function reviewTasks(cwd: string): Promise { branches = listTaktBranches(cwd); } - info('All tasks reviewed.'); + info('All tasks listed.'); } diff --git a/src/task/branchReview.ts b/src/task/branchList.ts similarity index 93% rename from src/task/branchReview.ts rename to src/task/branchList.ts index 74b147f..1d62982 100644 --- a/src/task/branchReview.ts +++ b/src/task/branchList.ts @@ -1,15 +1,15 @@ /** - * Branch review helpers + * Branch list helpers * * Functions for listing, parsing, and enriching takt-managed branches * with metadata (diff stats, original instruction, task slug). - * Used by the /review command. + * Used by the /list command. */ import { execFileSync } from 'node:child_process'; import { createLogger } from '../utils/debug.js'; -const log = createLogger('branchReview'); +const log = createLogger('branchList'); /** Branch info from `git branch --list` */ export interface BranchInfo { @@ -17,8 +17,8 @@ export interface BranchInfo { commit: string; } -/** Branch with review metadata */ -export interface BranchReviewItem { +/** Branch with list metadata */ +export interface BranchListItem { info: BranchInfo; filesChanged: number; taskSlug: string; @@ -159,13 +159,13 @@ export function getOriginalInstruction( } /** - * Build review items from branch list, enriching with diff stats. + * Build list items from branch list, enriching with diff stats. */ -export function buildReviewItems( +export function buildListItems( projectDir: string, branches: BranchInfo[], defaultBranch: string, -): BranchReviewItem[] { +): BranchListItem[] { return branches.map(br => ({ info: br, filesChanged: getFilesChanged(projectDir, defaultBranch, br.branch), diff --git a/src/task/index.ts b/src/task/index.ts index 4857468..5e8a846 100644 --- a/src/task/index.ts +++ b/src/task/index.ts @@ -29,9 +29,9 @@ export { getFilesChanged, extractTaskSlug, getOriginalInstruction, - buildReviewItems, + buildListItems, type BranchInfo, - type BranchReviewItem, -} from './branchReview.js'; + type BranchListItem, +} from './branchList.js'; export { autoCommitAndPush, type AutoCommitResult } from './autoCommit.js'; export { TaskWatcher, type TaskWatcherOptions } from './watcher.js';