π File detail
tools/TeamDeleteTool/TeamDeleteTool.ts
π― Use case
This module implements the βTeamDeleteToolβ tool (Team Delete) β something the model can call at runtime alongside other agent tools. On the API surface it exposes Output, Input, and TeamDeleteTool β mainly types, interfaces, or factory objects. Dependencies touch schema validation. It composes internal code from services, Tool, utils, constants, and prompt (relative imports).
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
import { z } from 'zod/v4' import { logEvent } from '../../services/analytics/index.js' import type { AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from '../../services/analytics/metadata.js' import type { Tool } from '../../Tool.js' import { buildTool, type ToolDef } from '../../Tool.js'
π€ Exports (heuristic)
OutputInputTeamDeleteTool
π External import roots
Package roots from from "β¦" (relative paths omitted).
zod
π₯οΈ Source preview
import { z } from 'zod/v4'
import { logEvent } from '../../services/analytics/index.js'
import type { AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from '../../services/analytics/metadata.js'
import type { Tool } from '../../Tool.js'
import { buildTool, type ToolDef } from '../../Tool.js'
import { isAgentSwarmsEnabled } from '../../utils/agentSwarmsEnabled.js'
import { lazySchema } from '../../utils/lazySchema.js'
import { jsonStringify } from '../../utils/slowOperations.js'
import { TEAM_LEAD_NAME } from '../../utils/swarm/constants.js'
import {
cleanupTeamDirectories,
readTeamFile,
unregisterTeamForSessionCleanup,
} from '../../utils/swarm/teamHelpers.js'
import { clearTeammateColors } from '../../utils/swarm/teammateLayoutManager.js'
import { clearLeaderTeamName } from '../../utils/tasks.js'
import { TEAM_DELETE_TOOL_NAME } from './constants.js'
import { getPrompt } from './prompt.js'
import { renderToolResultMessage, renderToolUseMessage } from './UI.js'
const inputSchema = lazySchema(() => z.strictObject({}))
type InputSchema = ReturnType<typeof inputSchema>
export type Output = {
success: boolean
message: string
team_name?: string
}
export type Input = z.infer<InputSchema>
export const TeamDeleteTool: Tool<InputSchema, Output> = buildTool({
name: TEAM_DELETE_TOOL_NAME,
searchHint: 'disband a swarm team and clean up',
maxResultSizeChars: 100_000,
shouldDefer: true,
userFacingName() {
return ''
},
get inputSchema(): InputSchema {
return inputSchema()
},
isEnabled() {
return isAgentSwarmsEnabled()
},
async description() {
return 'Clean up team and task directories when the swarm is complete'
},
async prompt() {
return getPrompt()
},
mapToolResultToToolResultBlockParam(data, toolUseID) {
return {
tool_use_id: toolUseID,
type: 'tool_result' as const,
content: [
{
type: 'text' as const,
text: jsonStringify(data),
},
],
}
},
async call(_input, context) {
const { setAppState, getAppState } = context
const appState = getAppState()
const teamName = appState.teamContext?.teamName
if (teamName) {
// Read team config to check for active members
const teamFile = readTeamFile(teamName)
if (teamFile) {
// Filter out the team lead - only count non-lead members
const nonLeadMembers = teamFile.members.filter(
m => m.name !== TEAM_LEAD_NAME,
)
// Separate truly active members from idle/dead ones
// Members with isActive === false are idle (finished their turn or crashed)
const activeMembers = nonLeadMembers.filter(m => m.isActive !== false)
if (activeMembers.length > 0) {
const memberNames = activeMembers.map(m => m.name).join(', ')
return {
data: {
success: false,
message: `Cannot cleanup team with ${activeMembers.length} active member(s): ${memberNames}. Use requestShutdown to gracefully terminate teammates first.`,
team_name: teamName,
},
}
}
}
await cleanupTeamDirectories(teamName)
// Already cleaned β don't try again on gracefulShutdown.
unregisterTeamForSessionCleanup(teamName)
// Clear color assignments so new teams start fresh
clearTeammateColors()
// Clear leader team name so getTaskListId() falls back to session ID
clearLeaderTeamName()
logEvent('tengu_team_deleted', {
team_name:
teamName as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
})
}
// Clear team context and inbox from app state
setAppState(prev => ({
...prev,
teamContext: undefined,
inbox: {
messages: [], // Clear any queued messages
},
}))
return {
data: {
success: true,
message: teamName
? `Cleaned up directories and worktrees for team "${teamName}"`
: 'No team name found, nothing to clean up',
team_name: teamName,
},
}
},
renderToolUseMessage,
renderToolResultMessage,
} satisfies ToolDef<InputSchema, Output>)