Files
Codewalkers/apps/server/git/branch-naming.ts
Lukas May 34578d39c6 refactor: Restructure monorepo to apps/server/ and apps/web/ layout
Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt
standard monorepo conventions (apps/ for runnable apps, packages/
for reusable libraries). Update all config files, shared package
imports, test fixtures, and documentation to reflect new paths.

Key fixes:
- Update workspace config to ["apps/*", "packages/*"]
- Update tsconfig.json rootDir/include for apps/server/
- Add apps/web/** to vitest exclude list
- Update drizzle.config.ts schema path
- Fix ensure-schema.ts migration path detection (3 levels up in dev,
  2 levels up in dist)
- Fix tests/integration/cli-server.test.ts import paths
- Update packages/shared imports to apps/server/ paths
- Update all docs/ files with new paths
2026-03-03 11:22:53 +01:00

68 lines
1.9 KiB
TypeScript

/**
* 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}`;
}