# All files / src/git branch-naming.ts

37.5% Statements 3/8
100% Branches 0/0
16.66% Functions 1/6
37.5% Lines 3/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68

    13x

    13x

    87x

     /**
     * Branch Naming Utility
     *
     * Pure functions for computing deterministic branch names
     * in the initiative → phase → task branch hierarchy.
     */

    /**
     * Task categories that run on the project's default branch (no initiative branch needed).
     */
    export const PLANNING_CATEGORIES = ['research', 'discuss', 'plan', 'detail', 'refine'] as const;

    /**
     * Task categories that require an initiative branch.
     */
    export const EXECUTION_CATEGORIES = ['execute', 'verify', 'merge', 'review'] as const;

    /**
     * Check if a task category is a planning category (runs on default branch).
     */
    export function isPlanningCategory(category: string): boolean {
      return (PLANNING_CATEGORIES as readonly string[]).includes(category);
    }

    /**
     * Convert a name to a URL/branch-safe slug.
     * Lowercase, replace non-alphanumeric runs with single hyphens, trim hyphens.
     */
    export function slugify(name: string): string {
      return name
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, '-')
        .replace(/^-|-$/g, '');
    }

    /**
     * Generate an initiative branch name from the initiative name.
     * Format: `cw/<slugified-name>`
     */
    export function generateInitiativeBranch(name: string): string {
      return `cw/${slugify(name)}`;
    }

    /**
     * Compute the initiative branch name.
     * Returns the branch as-is if set, or null if unset.
     */
    export function initiativeBranchName(branch: string | null): string | null {
      return branch;
    }

    /**
     * Compute a phase branch name.
     * Format: `<initiativeBranch>-phase-<slugified-phase-name>`
     */
    export function phaseBranchName(initiativeBranch: string, phaseName: string): string {
      return `${initiativeBranch}-phase-${slugify(phaseName)}`;
    }

    /**
     * Compute a task branch name.
     * Format: `<initiativeBranch>-task-<taskId>`
     * Uses the raw task ID (already unique) to avoid collisions.
     */
    export function taskBranchName(initiativeBranch: string, taskId: string): string {
      return `${initiativeBranch}-task-${taskId}`;
    }