fix: resolve new member status and notify lead to spawn teammate
- Fix member status resolution: members without messages now show as idle/active instead of unknown based on task ownership - Notify running team lead via stdin when a new member is added so the lead can spawn the teammate process - Map unknown presence label to idle for better UX clarity
This commit is contained in:
parent
a212171faa
commit
a50cd2a713
3 changed files with 28 additions and 9 deletions
|
|
@ -1286,12 +1286,29 @@ async function handleAddMember(
|
||||||
return { success: false, error: 'role must be a string' };
|
return { success: false, error: 'role must be a string' };
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrapTeamHandler('addMember', () =>
|
return wrapTeamHandler('addMember', async () => {
|
||||||
getTeamDataService().addMember(vTeam.value!, {
|
const tn = vTeam.value!;
|
||||||
name: vName.value!,
|
const memberName = vName.value!;
|
||||||
|
await getTeamDataService().addMember(tn, {
|
||||||
|
name: memberName,
|
||||||
role: role,
|
role: role,
|
||||||
})
|
});
|
||||||
);
|
|
||||||
|
// If team is alive, notify the lead to spawn the new teammate
|
||||||
|
const provisioning = getTeamProvisioningService();
|
||||||
|
if (provisioning.isTeamAlive(tn)) {
|
||||||
|
const roleHint = typeof role === 'string' && role.trim() ? ` with role "${role.trim()}"` : '';
|
||||||
|
const spawnMessage =
|
||||||
|
`A new teammate "${memberName}"${roleHint} has been added to the team. ` +
|
||||||
|
`Please spawn them immediately using the Task tool with team_name="${tn}" and name="${memberName}".`;
|
||||||
|
try {
|
||||||
|
await provisioning.sendMessageToTeam(tn, spawnMessage);
|
||||||
|
} catch {
|
||||||
|
// Best-effort: lead process may not be responsive
|
||||||
|
logger.warn(`Failed to notify lead about new member "${memberName}" in ${tn}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleRemoveMember(
|
async function handleRemoveMember(
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ export class TeamMemberResolver {
|
||||||
) ?? null;
|
) ?? null;
|
||||||
const memberMessages = messages.filter((message) => message.from === name);
|
const memberMessages = messages.filter((message) => message.from === name);
|
||||||
const latestMessage = memberMessages[0] ?? null;
|
const latestMessage = memberMessages[0] ?? null;
|
||||||
const status = this.resolveStatus(latestMessage);
|
const status = this.resolveStatus(latestMessage, currentTask !== null);
|
||||||
const configMember = configMemberMap.get(name);
|
const configMember = configMemberMap.get(name);
|
||||||
const metaMember = metaMemberMap.get(name);
|
const metaMember = metaMemberMap.get(name);
|
||||||
members.push({
|
members.push({
|
||||||
|
|
@ -103,9 +103,11 @@ export class TeamMemberResolver {
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
private resolveStatus(message: InboxMessage | null): MemberStatus {
|
private resolveStatus(message: InboxMessage | null, hasActiveTask: boolean): MemberStatus {
|
||||||
if (!message) {
|
if (!message) {
|
||||||
return 'unknown';
|
// Member exists in config but has no messages yet —
|
||||||
|
// if they own an in_progress task they're clearly active, otherwise idle
|
||||||
|
return hasActiveTask ? 'active' : 'idle';
|
||||||
}
|
}
|
||||||
|
|
||||||
const structured = this.parseStructuredMessage(message.text);
|
const structured = this.parseStructuredMessage(message.text);
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ export function getPresenceLabel(
|
||||||
if (member.status === 'terminated') return 'terminated';
|
if (member.status === 'terminated') return 'terminated';
|
||||||
if (isTeamProvisioning) return 'connecting';
|
if (isTeamProvisioning) return 'connecting';
|
||||||
if (isTeamAlive === false) return 'offline';
|
if (isTeamAlive === false) return 'offline';
|
||||||
if (member.status === 'unknown') return 'unknown';
|
if (member.status === 'unknown') return 'idle';
|
||||||
return member.currentTaskId ? 'working' : 'idle';
|
return member.currentTaskId ? 'working' : 'idle';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue