chore: merge main into cw/small-change-flow
Integrates main branch changes (headquarters dashboard, task retry count, agent prompt persistence, remote sync improvements) with the initiative's errand agent feature. Both features coexist in the merged result. Key resolutions: - Schema: take main's errands table (nullable projectId, no conflictFiles, with errandsRelations); migrate to 0035_faulty_human_fly - Router: keep both errandProcedures and headquartersProcedures - Errand prompt: take main's simpler version (no question-asking flow) - Manager: take main's status check (running|idle only, no waiting_for_input) - Tests: update to match removed conflictFiles field and undefined vs null
This commit is contained in:
@@ -453,6 +453,58 @@ describe('SimpleGitWorktreeManager', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ==========================================================================
|
||||
// Cross-Agent Isolation
|
||||
// ==========================================================================
|
||||
|
||||
describe('cross-agent isolation', () => {
|
||||
it('get() only matches worktrees in its own worktreesDir', async () => {
|
||||
// Simulate two agents with separate worktree base dirs but same repo
|
||||
const agentADir = path.join(repoPath, 'workdirs', 'agent-a');
|
||||
const agentBDir = path.join(repoPath, 'workdirs', 'agent-b');
|
||||
await mkdir(agentADir, { recursive: true });
|
||||
await mkdir(agentBDir, { recursive: true });
|
||||
|
||||
const managerA = new SimpleGitWorktreeManager(repoPath, undefined, agentADir);
|
||||
const managerB = new SimpleGitWorktreeManager(repoPath, undefined, agentBDir);
|
||||
|
||||
// Both create worktrees with the same id (project name)
|
||||
await managerA.create('my-project', 'agent/agent-a');
|
||||
await managerB.create('my-project', 'agent/agent-b');
|
||||
|
||||
// Each manager should only see its own worktree
|
||||
const wtA = await managerA.get('my-project');
|
||||
const wtB = await managerB.get('my-project');
|
||||
|
||||
expect(wtA).not.toBeNull();
|
||||
expect(wtB).not.toBeNull();
|
||||
expect(wtA!.path).toContain('agent-a');
|
||||
expect(wtB!.path).toContain('agent-b');
|
||||
expect(wtA!.path).not.toBe(wtB!.path);
|
||||
});
|
||||
|
||||
it('remove() only removes worktrees in its own worktreesDir', async () => {
|
||||
const agentADir = path.join(repoPath, 'workdirs', 'agent-a');
|
||||
const agentBDir = path.join(repoPath, 'workdirs', 'agent-b');
|
||||
await mkdir(agentADir, { recursive: true });
|
||||
await mkdir(agentBDir, { recursive: true });
|
||||
|
||||
const managerA = new SimpleGitWorktreeManager(repoPath, undefined, agentADir);
|
||||
const managerB = new SimpleGitWorktreeManager(repoPath, undefined, agentBDir);
|
||||
|
||||
await managerA.create('my-project', 'agent/agent-a');
|
||||
await managerB.create('my-project', 'agent/agent-b');
|
||||
|
||||
// Remove agent A's worktree
|
||||
await managerA.remove('my-project');
|
||||
|
||||
// Agent B's worktree should still exist
|
||||
const wtB = await managerB.get('my-project');
|
||||
expect(wtB).not.toBeNull();
|
||||
expect(wtB!.path).toContain('agent-b');
|
||||
});
|
||||
});
|
||||
|
||||
// ==========================================================================
|
||||
// Edge Cases
|
||||
// ==========================================================================
|
||||
|
||||
Reference in New Issue
Block a user