feat: implement unconditionally dropping of CLI provisioner artifacts
- Added a new function to drop CLI provisioner members from the member map, ensuring these internal artifacts are never displayed to users. - Updated the createCliProvisionerNameGuard function to unconditionally hide provisioner names, regardless of the presence of base members. - Modified unit tests to reflect the new behavior of dropping provisioner names even when the base member is absent.
This commit is contained in:
parent
65a9928cb5
commit
96c9b00d92
4 changed files with 33 additions and 16 deletions
|
|
@ -370,6 +370,9 @@ export class TeamMemberLogsFinder {
|
|||
results.length = 0;
|
||||
results.push(...nonSubagent, ...subagentsByKey.values());
|
||||
}
|
||||
// NOTE: dedup assumes cumulative snapshots (largest file = superset of all smaller ones).
|
||||
// Safety net: filterChunksByWorkIntervals on frontend still filters content by time,
|
||||
// so even if the wrong file is picked, only task-relevant chunks are shown.
|
||||
|
||||
const sorted = results.sort(
|
||||
(a, b) => new Date(b.startTime).getTime() - new Date(a.startTime).getTime()
|
||||
|
|
|
|||
|
|
@ -285,6 +285,26 @@ function dropCliAutoSuffixedMembers(
|
|||
}
|
||||
}
|
||||
|
||||
const PROVISIONER_SUFFIX = '-provisioner';
|
||||
|
||||
/**
|
||||
* Drop CLI provisioner artifacts ("{name}-provisioner") unconditionally.
|
||||
* These are temporary internal agents created during team provisioning
|
||||
* and should never be shown to the user.
|
||||
*/
|
||||
function dropCliProvisionerMembers(
|
||||
memberMap: Map<string, { name: string; role?: string; color?: string }>
|
||||
): void {
|
||||
for (const [key, member] of Array.from(memberMap.entries())) {
|
||||
const lower = member.name.trim().toLowerCase();
|
||||
if (!lower.endsWith(PROVISIONER_SUFFIX)) continue;
|
||||
const base = lower.slice(0, -PROVISIONER_SUFFIX.length);
|
||||
if (base) {
|
||||
memberMap.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function listTeams(
|
||||
payload: ListTeamsPayload
|
||||
): Promise<{ teams: unknown[]; diag: ListTeamsDiag }> {
|
||||
|
|
@ -428,6 +448,7 @@ async function listTeams(
|
|||
}
|
||||
|
||||
dropCliAutoSuffixedMembers(memberMap);
|
||||
dropCliProvisionerMembers(memberMap);
|
||||
|
||||
const members = Array.from(memberMap.values());
|
||||
const summary = {
|
||||
|
|
|
|||
|
|
@ -43,27 +43,20 @@ const PROVISIONER_SUFFIX = '-provisioner';
|
|||
|
||||
/**
|
||||
* Claude CLI creates temporary "{name}-provisioner" agents during team provisioning
|
||||
* to spawn real teammates. These are internal artifacts and should be hidden when
|
||||
* the real base member (e.g. "alice") also exists.
|
||||
* to spawn real teammates. These are always internal artifacts — never real teammates.
|
||||
*
|
||||
* Only removes "alice-provisioner" if "alice" is present — if the base is missing,
|
||||
* the provisioner entry is kept for visibility.
|
||||
* Unlike numeric suffixes (alice-2) which can be intentional, "-provisioner" is a
|
||||
* hardcoded CLI pattern that should never be exposed to the user. We unconditionally
|
||||
* hide any name ending with "-provisioner" regardless of whether the base name exists.
|
||||
*/
|
||||
export function createCliProvisionerNameGuard(
|
||||
allNames: Iterable<string>
|
||||
_allNames: Iterable<string>
|
||||
): (name: string) => boolean {
|
||||
const allLower = new Set<string>();
|
||||
for (const n of allNames) {
|
||||
if (typeof n !== 'string') continue;
|
||||
const t = n.trim().toLowerCase();
|
||||
if (t) allLower.add(t);
|
||||
}
|
||||
|
||||
return (name: string): boolean => {
|
||||
const lower = name.trim().toLowerCase();
|
||||
if (!lower.endsWith(PROVISIONER_SUFFIX)) return true;
|
||||
const base = lower.slice(0, -PROVISIONER_SUFFIX.length);
|
||||
if (!base) return true;
|
||||
return !allLower.has(base);
|
||||
// Keep bare "-provisioner" (no base) — that's not a CLI artifact pattern
|
||||
return !base;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,10 +56,10 @@ describe('createCliProvisionerNameGuard', () => {
|
|||
expect(keep('bob-provisioner')).toBe(false);
|
||||
});
|
||||
|
||||
it('keeps provisioner names when the base member is absent', () => {
|
||||
it('drops provisioner names even when the base member is absent', () => {
|
||||
const keep = createCliProvisionerNameGuard(['carol-provisioner']);
|
||||
|
||||
expect(keep('carol-provisioner')).toBe(true);
|
||||
expect(keep('carol-provisioner')).toBe(false);
|
||||
});
|
||||
|
||||
it('treats base-name collisions case-insensitively', () => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue