(input, context)
| 126 | }, |
| 127 | |
| 128 | async call(input, context) { |
| 129 | const { setAppState, getAppState } = context |
| 130 | const { team_name, description: _description, agent_type } = input |
| 131 | |
| 132 | // Check if already in a team - restrict to one team per leader |
| 133 | const appState = getAppState() |
| 134 | const existingTeam = appState.teamContext?.teamName |
| 135 | |
| 136 | if (existingTeam) { |
| 137 | throw new Error( |
| 138 | `Already leading team "${existingTeam}". A leader can only manage one team at a time. Use TeamDelete to end the current team before creating a new one.`, |
| 139 | ) |
| 140 | } |
| 141 | |
| 142 | // If team already exists, generate a unique name instead of failing |
| 143 | const finalTeamName = generateUniqueTeamName(team_name) |
| 144 | |
| 145 | // Generate a deterministic agent ID for the team lead |
| 146 | const leadAgentId = formatAgentId(TEAM_LEAD_NAME, finalTeamName) |
| 147 | const leadAgentType = agent_type || TEAM_LEAD_NAME |
| 148 | // Get the team lead's current model from AppState (handles session model, settings, CLI override) |
| 149 | const leadModel = parseUserSpecifiedModel( |
| 150 | appState.mainLoopModelForSession ?? |
| 151 | appState.mainLoopModel ?? |
| 152 | getDefaultMainLoopModel(), |
| 153 | ) |
| 154 | |
| 155 | const teamFilePath = getTeamFilePath(finalTeamName) |
| 156 | |
| 157 | const teamFile: TeamFile = { |
| 158 | name: finalTeamName, |
| 159 | description: _description, |
| 160 | createdAt: Date.now(), |
| 161 | leadAgentId, |
| 162 | leadSessionId: getSessionId(), // Store actual session ID for team discovery |
| 163 | members: [ |
| 164 | { |
| 165 | agentId: leadAgentId, |
| 166 | name: TEAM_LEAD_NAME, |
| 167 | agentType: leadAgentType, |
| 168 | model: leadModel, |
| 169 | joinedAt: Date.now(), |
| 170 | tmuxPaneId: '', |
| 171 | cwd: getCwd(), |
| 172 | subscriptions: [], |
| 173 | }, |
| 174 | ], |
| 175 | } |
| 176 | |
| 177 | await writeTeamFileAsync(finalTeamName, teamFile) |
| 178 | // Track for session-end cleanup — teams were left on disk forever |
| 179 | // unless explicitly TeamDelete'd (gh-32730). |
| 180 | registerTeamForSessionCleanup(finalTeamName) |
| 181 | |
| 182 | // Reset and create the corresponding task list directory (Team = Project = TaskList) |
| 183 | // This ensures task numbering starts fresh at 1 for each new swarm |
| 184 | const taskListId = sanitizeName(finalTeamName) |
| 185 | await resetTaskList(taskListId) |
nothing calls this directly
no test coverage detected