From f3c7f15397556e7db96c443e3d4e101e3888e5e9 Mon Sep 17 00:00:00 2001 From: Dean Sharon Date: Tue, 10 Mar 2026 01:13:55 +0200 Subject: [PATCH] feat: smart branch naming for /implement Move branch name derivation into Git agent's setup-task operation. When given an issue number, derives {type}/{number}-{slug} from labels and title. When given free text, infers type from keywords and slugifies. Falls back to task-{timestamp} when neither is provided. Removes TASK_ID generation from implement commands - the Git agent now owns branch naming and returns the created branch name as output. --- .../commands/implement-teams.md | 11 +++++----- .../devflow-implement/commands/implement.md | 11 +++++----- shared/agents/git.md | 21 ++++++++++++------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/plugins/devflow-implement/commands/implement-teams.md b/plugins/devflow-implement/commands/implement-teams.md index c4d2065..75fc892 100644 --- a/plugins/devflow-implement/commands/implement-teams.md +++ b/plugins/devflow-implement/commands/implement-teams.md @@ -27,21 +27,20 @@ Orchestrate a single task from exploration through implementation by spawning sp Record the current branch name as `BASE_BRANCH` - this will be the PR target. -Generate a unique `TASK_ID`: `task-{YYYY-MM-DD_HHMM}` (e.g., `task-2025-01-15_1430`). - -Spawn Git agent to set up task environment: +Spawn Git agent to set up task environment. The Git agent derives the branch name automatically from the issue or task description: ``` Task(subagent_type="Git"): "OPERATION: setup-task -TASK_ID: {task-id} BASE_BRANCH: {current branch name} -ISSUE_INPUT: {issue number if provided, otherwise omit} -Create feature branch and fetch issue if specified. +ISSUE_INPUT: {issue number if $ARGUMENTS starts with #, otherwise omit} +TASK_DESCRIPTION: {task description from $ARGUMENTS if not an issue number, otherwise omit} +Derive branch name from issue or description, create feature branch, and fetch issue if specified. Return the branch setup summary." ``` **Capture from Git agent output** (used throughout flow): +- `TASK_ID`: The branch name created by Git agent (use as TASK_ID for rest of flow) - `BASE_BRANCH`: Branch this feature was created from (for PR target) - `ISSUE_NUMBER`: GitHub issue number (if provided) - `ISSUE_CONTENT`: Full issue body including description (if provided) diff --git a/plugins/devflow-implement/commands/implement.md b/plugins/devflow-implement/commands/implement.md index 915f579..72f4338 100644 --- a/plugins/devflow-implement/commands/implement.md +++ b/plugins/devflow-implement/commands/implement.md @@ -27,21 +27,20 @@ Orchestrate a single task from exploration through implementation by spawning sp Record the current branch name as `BASE_BRANCH` - this will be the PR target. -Generate a unique `TASK_ID`: `task-{YYYY-MM-DD_HHMM}` (e.g., `task-2025-01-15_1430`). - -Spawn Git agent to set up task environment: +Spawn Git agent to set up task environment. The Git agent derives the branch name automatically from the issue or task description: ``` Task(subagent_type="Git"): "OPERATION: setup-task -TASK_ID: {task-id} BASE_BRANCH: {current branch name} -ISSUE_INPUT: {issue number if provided, otherwise omit} -Create feature branch and fetch issue if specified. +ISSUE_INPUT: {issue number if $ARGUMENTS starts with #, otherwise omit} +TASK_DESCRIPTION: {task description from $ARGUMENTS if not an issue number, otherwise omit} +Derive branch name from issue or description, create feature branch, and fetch issue if specified. Return the branch setup summary." ``` **Capture from Git agent output** (used throughout flow): +- `TASK_ID`: The branch name created by Git agent (use as TASK_ID for rest of flow) - `BASE_BRANCH`: Branch this feature was created from (for PR target) - `ISSUE_NUMBER`: GitHub issue number (if provided) - `ISSUE_CONTENT`: Full issue body including description (if provided) diff --git a/shared/agents/git.md b/shared/agents/git.md index 5403185..3f71803 100644 --- a/shared/agents/git.md +++ b/shared/agents/git.md @@ -21,7 +21,7 @@ The orchestrator provides: |-----------|---------|----------------| | `ensure-pr-ready` | Pre-flight for /review: commit, push, create PR | - | | `validate-branch` | Pre-flight for /resolve: check branch state | - | -| `setup-task` | Create feature branch and fetch issue | `TASK_ID`, `BASE_BRANCH`, `ISSUE_INPUT` (optional) | +| `setup-task` | Create feature branch and fetch issue | `BASE_BRANCH`, `ISSUE_INPUT` (optional), `TASK_DESCRIPTION` (optional) | | `fetch-issue` | Fetch GitHub issue for implementation | `ISSUE_INPUT` (number or search term) | | `comment-pr` | Create PR inline comments for review findings | `PR_NUMBER`, `REVIEW_BASE_DIR`, `TIMESTAMP` | | `manage-debt` | Update tech debt backlog with pre-existing issues | `REVIEW_DIR`, `TIMESTAMP` | @@ -101,25 +101,30 @@ Pre-flight validation for `/resolve`. Checks branch state without modifications. ## Operation: setup-task -Set up task environment: create feature branch and optionally fetch issue. +Set up task environment: derive branch name, create feature branch, and optionally fetch issue. **Input:** -- `TASK_ID`: Unique task identifier (becomes branch name) - `BASE_BRANCH`: Branch to create from (track this for PR target) - `ISSUE_INPUT` (optional): Issue number to fetch +- `TASK_DESCRIPTION` (optional): Free-text task description (when no issue) **Process:** 1. Record current branch as BASE_BRANCH for later PR targeting -2. Create and checkout feature branch: `git checkout -b {TASK_ID}` -3. If ISSUE_INPUT provided, fetch issue details via GitHub API -4. Return setup summary with BASE_BRANCH recorded +2. **Derive branch name:** + - If `ISSUE_INPUT` provided: fetch issue via GitHub API first, then derive branch name as `{type}/{number}-{slug}` where: + - `type` is inferred from issue labels: `bug` → `fix`, `documentation` or `docs` → `docs`, `refactor` → `refactor`, `chore` or `maintenance` → `chore`, default → `feature` + - `slug` is the issue title: lowercased, non-alphanumeric replaced with hyphens, consecutive hyphens collapsed, trimmed, max 40 characters + - If `TASK_DESCRIPTION` provided (no issue): infer type from description keywords (e.g., "fix login bug" → `fix`, "refactor auth" → `refactor`, "add JWT" → `feature`, "update docs" → `docs`, "chore: cleanup" → `chore`), then slugify description as `{type}/{slug}` (max 40 chars) + - If neither: fallback to `task-{YYYY-MM-DD_HHMM}` +3. Create and checkout feature branch: `git checkout -b {derived-branch-name}` +4. Return setup summary with branch name and BASE_BRANCH recorded **Output:** ```markdown -## Task Setup: {TASK_ID} +## Task Setup: {branch-name} ### Branch -- **Feature branch**: {TASK_ID} +- **Branch name**: {derived-branch-name} - **Base branch**: {BASE_BRANCH} (PR target) ### Issue (if fetched)