feat: Auto-branch initiative system with per-project default branches
Planning tasks (research, discuss, plan, detail, refine) now run on the project's defaultBranch instead of hardcoded 'main'. Execution tasks (execute, verify, merge, review) auto-generate an initiative branch (cw/<slug>) on first dispatch. Branch configuration removed from initiative creation — it's now fully automatic. - Add PLANNING_CATEGORIES/EXECUTION_CATEGORIES to branch-naming - Dispatch manager splits logic by task category - ProcessManager uses per-project defaultBranch fallback - Phase dispatch uses project.defaultBranch for ensureBranch base - Remove mergeTarget from createInitiative input - Rename updateInitiativeMergeConfig → updateInitiativeConfig - Add defaultBranch field to registerProject + UI - Rename mergeTarget → branch across all frontend components
This commit is contained in:
@@ -49,7 +49,7 @@ describe('writeInputFiles', () => {
|
||||
name: 'Test Initiative',
|
||||
status: 'active',
|
||||
mergeRequiresApproval: true,
|
||||
mergeTarget: 'main',
|
||||
branch: 'cw/test-initiative',
|
||||
executionMode: 'review_per_phase',
|
||||
createdAt: new Date('2026-01-01'),
|
||||
updatedAt: new Date('2026-01-02'),
|
||||
|
||||
@@ -125,7 +125,7 @@ export function writeInputFiles(options: WriteInputFilesOptions): void {
|
||||
name: ini.name,
|
||||
status: ini.status,
|
||||
mergeRequiresApproval: ini.mergeRequiresApproval,
|
||||
mergeTarget: ini.mergeTarget,
|
||||
branch: ini.branch,
|
||||
},
|
||||
'',
|
||||
);
|
||||
|
||||
@@ -222,7 +222,7 @@ export class MultiProviderAgentManager implements AgentManager {
|
||||
let agentCwd: string;
|
||||
if (initiativeId) {
|
||||
log.debug({ alias, initiativeId, baseBranch, branchName }, 'creating initiative-based worktrees');
|
||||
agentCwd = await this.processManager.createProjectWorktrees(alias, initiativeId, baseBranch ?? 'main', branchName);
|
||||
agentCwd = await this.processManager.createProjectWorktrees(alias, initiativeId, baseBranch, branchName);
|
||||
|
||||
// Log projects linked to the initiative
|
||||
const projects = await this.projectRepository.findProjectsByInitiativeId(initiativeId);
|
||||
|
||||
@@ -54,7 +54,7 @@ export class ProcessManager {
|
||||
async createProjectWorktrees(
|
||||
alias: string,
|
||||
initiativeId: string,
|
||||
baseBranch: string = 'main',
|
||||
baseBranch?: string,
|
||||
branchName?: string,
|
||||
): Promise<string> {
|
||||
const projects = await this.projectRepository.findProjectsByInitiativeId(initiativeId);
|
||||
@@ -78,7 +78,8 @@ export class ProcessManager {
|
||||
for (const project of projects) {
|
||||
const clonePath = await ensureProjectClone(project, this.workspaceRoot);
|
||||
const worktreeManager = new SimpleGitWorktreeManager(clonePath, undefined, agentWorkdir);
|
||||
const worktree = await worktreeManager.create(project.name, branchName ?? `agent/${alias}`, baseBranch);
|
||||
const effectiveBaseBranch = baseBranch ?? project.defaultBranch;
|
||||
const worktree = await worktreeManager.create(project.name, branchName ?? `agent/${alias}`, effectiveBaseBranch);
|
||||
const worktreePath = worktree.path;
|
||||
const pathExists = existsSync(worktreePath);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user