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) {
|
for (const suggestion of suggestions) {
|
||||||
if (suggestion.type !== 'addRules' || !Array.isArray(suggestion.rules)) continue;
|
if (suggestion.type !== 'addRules' || !Array.isArray(suggestion.rules)) continue;
|
||||||
|
|
||||||
const toolNames = suggestion.rules
|
let toolNames = suggestion.rules
|
||||||
.map((r) => r.toolName)
|
.map((r) => r.toolName)
|
||||||
.filter((name): name is string => typeof name === 'string' && name.length > 0);
|
.filter((name): name is string => typeof name === 'string' && name.length > 0);
|
||||||
if (toolNames.length === 0) continue;
|
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';
|
const behavior = suggestion.behavior ?? 'allow';
|
||||||
// FACT: observed destinations are "localSettings" (project-level .claude/settings.local.json)
|
// FACT: observed destinations are "localSettings" (project-level .claude/settings.local.json)
|
||||||
const settingsPath =
|
const settingsPath =
|
||||||
|
|
|
||||||
|
|
@ -223,22 +223,27 @@ function MemberPopoverContent({
|
||||||
Recent tools
|
Recent tools
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{node.recentTools.slice(0, 3).map((tool) => (
|
{node.recentTools.slice(0, 3).map((tool) => {
|
||||||
|
const shortName = formatToolName(tool.name);
|
||||||
|
const shortPreview = formatToolPreview(tool.preview);
|
||||||
|
return (
|
||||||
<div
|
<div
|
||||||
key={`${tool.name}:${tool.finishedAt}:${tool.startedAt}`}
|
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]"
|
className="flex items-center gap-1.5 rounded border border-[var(--color-border)] bg-[var(--color-surface-secondary)] px-2 py-1 text-[10px]"
|
||||||
>
|
>
|
||||||
<div
|
<span
|
||||||
className="font-mono"
|
className="size-1.5 shrink-0 rounded-full"
|
||||||
style={{ color: tool.state === 'error' ? '#ef4444' : '#22c55e' }}
|
style={{ background: tool.state === 'error' ? '#ef4444' : '#22c55e' }}
|
||||||
>
|
/>
|
||||||
{tool.preview ? `${tool.name}: ${tool.preview}` : tool.name}
|
<span className="font-mono font-medium text-[var(--color-text)]">
|
||||||
</div>
|
{shortName}
|
||||||
{tool.resultPreview && (
|
</span>
|
||||||
<div className="mt-0.5 text-[var(--color-text-muted)]">{tool.resultPreview}</div>
|
{shortPreview && (
|
||||||
|
<span className="truncate text-[var(--color-text-muted)]">{shortPreview}</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
);
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue