diff --git a/get-shit-done/bin/gsd-tools.js b/get-shit-done/bin/gsd-tools.js index b04e65b93..3a9e5b72e 100755 --- a/get-shit-done/bin/gsd-tools.js +++ b/get-shit-done/bin/gsd-tools.js @@ -3652,6 +3652,7 @@ function cmdInitPlanPhase(cwd, phase, includes, raw) { research_enabled: config.research, plan_checker_enabled: config.plan_checker, commit_docs: config.commit_docs, + branching_strategy: config.branching_strategy, // Phase info phase_found: !!phaseInfo, @@ -3661,6 +3662,17 @@ function cmdInitPlanPhase(cwd, phase, includes, raw) { phase_slug: phaseInfo?.phase_slug || null, padded_phase: phaseInfo?.phase_number?.padStart(2, '0') || null, + // Branch name (pre-computed) — ensures early branching before first commit + branch_name: config.branching_strategy === 'phase' && phaseInfo + ? config.phase_branch_template + .replace('{phase}', phaseInfo.phase_number) + .replace('{slug}', phaseInfo.phase_slug || 'phase') + : config.branching_strategy === 'milestone' + ? config.milestone_branch_template + .replace('{milestone}', getMilestoneInfo(cwd).version) + .replace('{slug}', generateSlugInternal(getMilestoneInfo(cwd).name) || 'milestone') + : null, + // Existing artifacts has_research: phaseInfo?.has_research || false, has_context: phaseInfo?.has_context || false, @@ -3919,11 +3931,13 @@ function cmdInitVerifyWork(cwd, phase, raw) { function cmdInitPhaseOp(cwd, phase, raw) { const config = loadConfig(cwd); const phaseInfo = findPhaseInternal(cwd, phase); + const milestone = getMilestoneInfo(cwd); const result = { // Config commit_docs: config.commit_docs, brave_search: config.brave_search, + branching_strategy: config.branching_strategy, // Phase info phase_found: !!phaseInfo, @@ -3933,6 +3947,17 @@ function cmdInitPhaseOp(cwd, phase, raw) { phase_slug: phaseInfo?.phase_slug || null, padded_phase: phaseInfo?.phase_number?.padStart(2, '0') || null, + // Branch name (pre-computed) — ensures early branching before first commit + branch_name: config.branching_strategy === 'phase' && phaseInfo + ? config.phase_branch_template + .replace('{phase}', phaseInfo.phase_number) + .replace('{slug}', phaseInfo.phase_slug || 'phase') + : config.branching_strategy === 'milestone' + ? config.milestone_branch_template + .replace('{milestone}', milestone.version) + .replace('{slug}', generateSlugInternal(milestone.name) || 'milestone') + : null, + // Existing artifacts has_research: phaseInfo?.has_research || false, has_context: phaseInfo?.has_context || false, diff --git a/get-shit-done/workflows/discuss-phase.md b/get-shit-done/workflows/discuss-phase.md index 4f7fb0342..4f8840795 100644 --- a/get-shit-done/workflows/discuss-phase.md +++ b/get-shit-done/workflows/discuss-phase.md @@ -114,7 +114,7 @@ Phase number from argument (required). INIT=$(node ~/.claude/get-shit-done/bin/gsd-tools.js init phase-op "${PHASE}") ``` -Parse JSON for: `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_plans`, `has_verification`, `plan_count`, `roadmap_exists`, `planning_exists`. +Parse JSON for: `commit_docs`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_plans`, `has_verification`, `plan_count`, `roadmap_exists`, `planning_exists`. **If `phase_found` is false:** ``` @@ -124,7 +124,22 @@ Use /gsd:progress to see available phases. ``` Exit workflow. -**If `phase_found` is true:** Continue to check_existing. +**If `phase_found` is true:** Continue to handle_branching. + + + +Check `branching_strategy` from init: + +**"none":** Skip, continue on current branch. + +**"phase" or "milestone":** Use pre-computed `branch_name` from init: +```bash +git checkout -b "$BRANCH_NAME" 2>/dev/null || git checkout "$BRANCH_NAME" +``` + +This ensures all phase documentation commits (context, research, plans) go to the feature branch, not main. + +Continue to check_existing. diff --git a/get-shit-done/workflows/plan-phase.md b/get-shit-done/workflows/plan-phase.md index 7aefc43ab..e298b66d0 100644 --- a/get-shit-done/workflows/plan-phase.md +++ b/get-shit-done/workflows/plan-phase.md @@ -18,12 +18,25 @@ Load all context in one call (include file contents to avoid redundant reads): INIT=$(node ~/.claude/get-shit-done/bin/gsd-tools.js init plan-phase "$PHASE" --include state,roadmap,requirements,context,research,verification,uat) ``` -Parse JSON for: `researcher_model`, `planner_model`, `checker_model`, `research_enabled`, `plan_checker_enabled`, `commit_docs`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_plans`, `plan_count`, `planning_exists`, `roadmap_exists`. +Parse JSON for: `researcher_model`, `planner_model`, `checker_model`, `research_enabled`, `plan_checker_enabled`, `commit_docs`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`, `has_research`, `has_context`, `has_plans`, `plan_count`, `planning_exists`, `roadmap_exists`. **File contents (from --include):** `state_content`, `roadmap_content`, `requirements_content`, `context_content`, `research_content`, `verification_content`, `uat_content`. These are null if files don't exist. **If `planning_exists` is false:** Error — run `/gsd:new-project` first. +## 1.5. Handle Branching + +Check `branching_strategy` from init: + +**"none":** Skip, continue on current branch. + +**"phase" or "milestone":** Use pre-computed `branch_name` from init: +```bash +git checkout -b "$BRANCH_NAME" 2>/dev/null || git checkout "$BRANCH_NAME" +``` + +This ensures research and planning commits go to the feature branch, not main. If `/gsd:discuss-phase` already created the branch, the `git checkout` fallback switches to it. + ## 2. Parse and Normalize Arguments Extract from $ARGUMENTS: phase number (integer or decimal like `2.1`), flags (`--research`, `--skip-research`, `--gaps`, `--skip-verify`).