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 = () => {
context.fileWatcher.off('team-change', teamChangeHandler);
setAliveTeamsProvider(null);
setTeamWatchScopeChangeListener(null);
context.fileWatcher.setTeamWatchScopeProvider(null);
reconcileScheduler?.dispose();

View file

@ -1939,6 +1939,9 @@ async function handleCreateTeam(
return wrapTeamHandler('create', async () => {
addMainBreadcrumb('team', 'create', { teamName: validation.value.teamName });
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 {
const response = await getTeamProvisioningService().createTeam(
validation.value,
@ -2104,6 +2107,9 @@ async function handleLaunchTeam(
return wrapTeamHandler('create', async () => {
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 {
const response = await getTeamProvisioningService().createTeam(
createRequest,

View file

@ -101,6 +101,10 @@ import {
removeTeamHandlers,
} from '../../../src/main/ipc/teams';
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 { getAppDataPath } from '../../../src/main/utils/pathDecoder';
import {
@ -355,6 +359,7 @@ describe('ipc teams handlers', () => {
};
beforeEach(() => {
resetTeamWatchScopeForTests();
handlers.clear();
vi.clearAllMocks();
service.listTeams.mockReset();
@ -427,6 +432,7 @@ describe('ipc teams handlers', () => {
});
afterEach(() => {
resetTeamWatchScopeForTests();
launchIoGovernor.clearForTests();
vi.useRealTimers();
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 () => {
const first = (await handlers.get(TEAM_LIST)!({} as never)) as {
success: boolean;
@ -4378,6 +4401,7 @@ describe('ipc teams handlers', () => {
})) as { success: boolean };
expect(result.success).toBe(true);
expect(computeTeamWatchScope().has('draft-team')).toBe(true);
expect(provisioningService.launchTeam).not.toHaveBeenCalled();
expect(provisioningService.createTeam).toHaveBeenCalledWith(
{