fix(team): proactively add all agent-teams MCP tools on first approval
When user approves any mcp__agent-teams__* tool, also add all other agent-teams tools to settings.local.json preemptively. This prevents teammates from getting stuck on subsequent tool calls (task_get, task_start, task_complete, etc.) since each generates a separate permission_request and the teammate blocks until resolved. FACT: Settings file approach only prevents FUTURE blocks, not current ones. Pre-adding all tools on first approval covers the common case.
This commit is contained in:
parent
d2487e41c9
commit
34f1f0d612
2 changed files with 39 additions and 14 deletions
|
|
@ -6370,11 +6370,31 @@ export class TeamProvisioningService {
|
|||
for (const suggestion of suggestions) {
|
||||
if (suggestion.type !== 'addRules' || !Array.isArray(suggestion.rules)) continue;
|
||||
|
||||
const toolNames = suggestion.rules
|
||||
let toolNames = suggestion.rules
|
||||
.map((r) => r.toolName)
|
||||
.filter((name): name is string => typeof name === 'string' && name.length > 0);
|
||||
if (toolNames.length === 0) continue;
|
||||
|
||||
// When approving ANY mcp__agent-teams__ tool, proactively add ALL agent-teams tools.
|
||||
// FACT: Teammates need multiple MCP tools (member_briefing, task_get, task_start, etc.)
|
||||
// FACT: Each tool generates a separate permission_request, but by the time we process it
|
||||
// the teammate is already stuck waiting. Pre-adding all tools prevents future blocks.
|
||||
if (toolNames.some((name) => name.startsWith('mcp__agent-teams__'))) {
|
||||
const agentTeamsTools = [
|
||||
'mcp__agent-teams__member_briefing',
|
||||
'mcp__agent-teams__task_briefing',
|
||||
'mcp__agent-teams__task_create',
|
||||
'mcp__agent-teams__task_get',
|
||||
'mcp__agent-teams__task_list',
|
||||
'mcp__agent-teams__task_start',
|
||||
'mcp__agent-teams__task_complete',
|
||||
'mcp__agent-teams__task_set_status',
|
||||
'mcp__agent-teams__task_add_comment',
|
||||
];
|
||||
const merged = new Set([...toolNames, ...agentTeamsTools]);
|
||||
toolNames = Array.from(merged);
|
||||
}
|
||||
|
||||
const behavior = suggestion.behavior ?? 'allow';
|
||||
// FACT: observed destinations are "localSettings" (project-level .claude/settings.local.json)
|
||||
const settingsPath =
|
||||
|
|
|
|||
|
|
@ -223,22 +223,27 @@ function MemberPopoverContent({
|
|||
Recent tools
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
{node.recentTools.slice(0, 3).map((tool) => (
|
||||
<div
|
||||
key={`${tool.name}:${tool.finishedAt}:${tool.startedAt}`}
|
||||
className="rounded border border-[var(--color-border)] bg-[var(--color-surface-secondary)] px-2 py-1 text-[10px]"
|
||||
>
|
||||
{node.recentTools.slice(0, 3).map((tool) => {
|
||||
const shortName = formatToolName(tool.name);
|
||||
const shortPreview = formatToolPreview(tool.preview);
|
||||
return (
|
||||
<div
|
||||
className="font-mono"
|
||||
style={{ color: tool.state === 'error' ? '#ef4444' : '#22c55e' }}
|
||||
key={`${tool.name}:${tool.finishedAt}:${tool.startedAt}`}
|
||||
className="flex items-center gap-1.5 rounded border border-[var(--color-border)] bg-[var(--color-surface-secondary)] px-2 py-1 text-[10px]"
|
||||
>
|
||||
{tool.preview ? `${tool.name}: ${tool.preview}` : tool.name}
|
||||
<span
|
||||
className="size-1.5 shrink-0 rounded-full"
|
||||
style={{ background: tool.state === 'error' ? '#ef4444' : '#22c55e' }}
|
||||
/>
|
||||
<span className="font-mono font-medium text-[var(--color-text)]">
|
||||
{shortName}
|
||||
</span>
|
||||
{shortPreview && (
|
||||
<span className="truncate text-[var(--color-text-muted)]">{shortPreview}</span>
|
||||
)}
|
||||
</div>
|
||||
{tool.resultPreview && (
|
||||
<div className="mt-0.5 text-[var(--color-text-muted)]">{tool.resultPreview}</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Reference in a new issue