Skip to content

Commit c7d5b27

Browse files
authored
Merge PR #470: Fix branch labels stuck on unknown
Fix branch labels stuck on unknown
2 parents 26168fe + ea7dcd7 commit c7d5b27

2 files changed

Lines changed: 47 additions & 3 deletions

File tree

server/sessionManager.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ class SessionManager extends EventEmitter {
6262
this.statusMinHoldMs = parseInt(process.env.STATUS_MIN_HOLD_MS || '1500');
6363
// Extra hysteresis for transitioning to idle (prevents flicker when output pauses briefly).
6464
this.statusIdleHoldMs = parseInt(process.env.STATUS_IDLE_HOLD_MS || '6000');
65-
this.branchRefreshMs = parseInt(process.env.BRANCH_REFRESH_MS || '60000');
65+
// Default to 30s to keep branch labels reasonably fresh without relying on user git commands.
66+
this.branchRefreshMs = parseInt(process.env.BRANCH_REFRESH_MS || '30000');
6667
this.conversationSnapshotTtlMs = parseInt(process.env.CONVERSATION_SNAPSHOT_TTL_MS || '5000');
6768
this.conversationSnapshotCache = { timestamp: 0, files: null };
6869

@@ -1744,6 +1745,10 @@ class SessionManager extends EventEmitter {
17441745
return !!rel && !rel.startsWith('..') && !path.isAbsolute(rel);
17451746
}
17461747

1748+
pathsOverlap(a, b) {
1749+
return this.isSameOrSubpath(a, b) || this.isSameOrSubpath(b, a);
1750+
}
1751+
17471752
async updateGitBranch(worktreeId, worktreePath, skipCache = false) {
17481753
logger.info('🔄 updateGitBranch called', {
17491754
worktreeId,
@@ -1786,7 +1791,7 @@ class SessionManager extends EventEmitter {
17861791
for (const [sessionId, session] of this.sessions) {
17871792
// Check if this session belongs to the same worktree by comparing paths
17881793
if (session.worktreeId === worktreeId && session.config &&
1789-
this.isSameOrSubpath(session.config.cwd, normalizedWorktreePath)) {
1794+
this.pathsOverlap(session.config.cwd, normalizedWorktreePath)) {
17901795
sessionsToUpdate.add(sessionId);
17911796
}
17921797
}
@@ -1798,7 +1803,7 @@ class SessionManager extends EventEmitter {
17981803
if (sessionsToUpdate.size === 0) {
17991804
for (const [sessionId, session] of this.sessions) {
18001805
if (!session?.config?.cwd) continue;
1801-
if (!this.isSameOrSubpath(session.config.cwd, normalizedWorktreePath)) continue;
1806+
if (!this.pathsOverlap(session.config.cwd, normalizedWorktreePath)) continue;
18021807
if (session.type !== 'claude' && session.type !== 'codex' && session.type !== 'server') continue;
18031808
sessionsToUpdate.add(sessionId);
18041809
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
const { SessionManager } = require('../../server/sessionManager');
2+
3+
describe('SessionManager.updateGitBranch matching', () => {
4+
test('updates mixed-repo sessions even when session cwd is a subfolder of worktree path', async () => {
5+
const io = { emit: jest.fn() };
6+
const agentManager = { getAllAgents: () => [] };
7+
const sm = new SessionManager(io, agentManager);
8+
9+
sm.sessions = new Map([
10+
['my-repo-work1-claude', {
11+
id: 'my-repo-work1-claude',
12+
type: 'claude',
13+
worktreeId: 'work1',
14+
repositoryName: 'my-repo',
15+
status: 'idle',
16+
branch: 'unknown',
17+
config: { cwd: '/tmp/repo/work1/src' }
18+
}]
19+
]);
20+
21+
sm.gitHelper = {
22+
getCurrentBranch: jest.fn().mockResolvedValue('feature/test'),
23+
getRemoteUrl: jest.fn().mockResolvedValue(null),
24+
getDefaultBranch: jest.fn().mockResolvedValue('master'),
25+
checkForExistingPR: jest.fn().mockResolvedValue(null),
26+
clearCacheForPath: jest.fn()
27+
};
28+
29+
await sm.updateGitBranch('work1', '/tmp/repo/work1', true);
30+
31+
const updated = sm.sessions.get('my-repo-work1-claude');
32+
expect(updated.branch).toBe('feature/test');
33+
expect(io.emit).toHaveBeenCalledWith('branch-update', expect.objectContaining({
34+
sessionId: 'my-repo-work1-claude',
35+
branch: 'feature/test'
36+
}));
37+
});
38+
});
39+

0 commit comments

Comments
 (0)