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