fix: keep created teams in watch scope

This commit is contained in:
777genius 2026-05-30 16:51:47 +03:00
parent f4155a6742
commit a18009cc0f
3 changed files with 31 additions and 0 deletions

View file

@ -1431,6 +1431,7 @@ function wireFileWatcherEvents(context: ServiceContext): void {
teamChangeCleanup = () => { teamChangeCleanup = () => {
context.fileWatcher.off('team-change', teamChangeHandler); context.fileWatcher.off('team-change', teamChangeHandler);
setAliveTeamsProvider(null);
setTeamWatchScopeChangeListener(null); setTeamWatchScopeChangeListener(null);
context.fileWatcher.setTeamWatchScopeProvider(null); context.fileWatcher.setTeamWatchScopeProvider(null);
reconcileScheduler?.dispose(); reconcileScheduler?.dispose();

View file

@ -1939,6 +1939,9 @@ async function handleCreateTeam(
return wrapTeamHandler('create', async () => { return wrapTeamHandler('create', async () => {
addMainBreadcrumb('team', 'create', { teamName: validation.value.teamName }); addMainBreadcrumb('team', 'create', { teamName: validation.value.teamName });
launchIoGovernor?.noteLaunchIntent(validation.value.teamName, 'create'); launchIoGovernor?.noteLaunchIntent(validation.value.teamName, 'create');
// Keep this team's team-root/task artifacts file-watched while createTeam writes
// its initial config, tasks, inboxes, and launch state.
markTeamEngaged(validation.value.teamName);
try { try {
const response = await getTeamProvisioningService().createTeam( const response = await getTeamProvisioningService().createTeam(
validation.value, validation.value,
@ -2104,6 +2107,9 @@ async function handleLaunchTeam(
return wrapTeamHandler('create', async () => { return wrapTeamHandler('create', async () => {
launchIoGovernor?.noteLaunchIntent(tn, 'draft-launch'); launchIoGovernor?.noteLaunchIntent(tn, 'draft-launch');
// Draft launch runs through createTeam, so it needs the same immediate watch scope
// as a normal launch before startup files begin changing.
markTeamEngaged(tn);
try { try {
const response = await getTeamProvisioningService().createTeam( const response = await getTeamProvisioningService().createTeam(
createRequest, createRequest,

View file

@ -101,6 +101,10 @@ import {
removeTeamHandlers, removeTeamHandlers,
} from '../../../src/main/ipc/teams'; } from '../../../src/main/ipc/teams';
import { ConfigManager } from '../../../src/main/services/infrastructure/ConfigManager'; import { ConfigManager } from '../../../src/main/services/infrastructure/ConfigManager';
import {
computeTeamWatchScope,
resetTeamWatchScopeForTests,
} from '../../../src/main/services/infrastructure/teamWatchScope';
import { LaunchIoGovernor } from '../../../src/main/services/team/LaunchIoGovernor'; import { LaunchIoGovernor } from '../../../src/main/services/team/LaunchIoGovernor';
import { getAppDataPath } from '../../../src/main/utils/pathDecoder'; import { getAppDataPath } from '../../../src/main/utils/pathDecoder';
import { import {
@ -355,6 +359,7 @@ describe('ipc teams handlers', () => {
}; };
beforeEach(() => { beforeEach(() => {
resetTeamWatchScopeForTests();
handlers.clear(); handlers.clear();
vi.clearAllMocks(); vi.clearAllMocks();
service.listTeams.mockReset(); service.listTeams.mockReset();
@ -427,6 +432,7 @@ describe('ipc teams handlers', () => {
}); });
afterEach(() => { afterEach(() => {
resetTeamWatchScopeForTests();
launchIoGovernor.clearForTests(); launchIoGovernor.clearForTests();
vi.useRealTimers(); vi.useRealTimers();
setClaudeBasePathOverride(null); setClaudeBasePathOverride(null);
@ -1314,6 +1320,23 @@ describe('ipc teams handlers', () => {
}); });
}); });
it('marks created teams engaged before provisioning writes startup artifacts', async () => {
const createTeam = 'created-watch-scope';
provisioningService.createTeam.mockImplementationOnce(async () => {
expect(computeTeamWatchScope().has(createTeam)).toBe(true);
return { runId: 'run-created-watch-scope' };
});
const result = (await handlers.get(TEAM_CREATE)!({ sender: { send: vi.fn() } } as never, {
teamName: createTeam,
members: [{ name: 'alice' }],
cwd: os.tmpdir(),
})) as { success: boolean };
expect(result.success).toBe(true);
expect(computeTeamWatchScope().has(createTeam)).toBe(true);
});
it('returns cached TEAM_LIST data under active launch pressure without starting another scan', async () => { it('returns cached TEAM_LIST data under active launch pressure without starting another scan', async () => {
const first = (await handlers.get(TEAM_LIST)!({} as never)) as { const first = (await handlers.get(TEAM_LIST)!({} as never)) as {
success: boolean; success: boolean;
@ -4378,6 +4401,7 @@ describe('ipc teams handlers', () => {
})) as { success: boolean }; })) as { success: boolean };
expect(result.success).toBe(true); expect(result.success).toBe(true);
expect(computeTeamWatchScope().has('draft-team')).toBe(true);
expect(provisioningService.launchTeam).not.toHaveBeenCalled(); expect(provisioningService.launchTeam).not.toHaveBeenCalled();
expect(provisioningService.createTeam).toHaveBeenCalledWith( expect(provisioningService.createTeam).toHaveBeenCalledWith(
{ {