import { defineTool } from '@earendil-works/pi-coding-agent'; import { Type } from 'typebox'; import { withLinearAuth, linearGraphQL } from '../client'; import { PaginationParams, paginationVariables, FilterParam } from '../params'; import { TEAM_SELECTION } from '../selections'; import type { LinearTeam, JsonObject, LinearConnection } from '../types'; import { compactObject, asObject } from '../util'; import { renderLinearGetTeamCall, renderLinearTeamListCall, renderLinearTeamListResult, renderLinearTeamResult, } from '../renderers/teams'; export function teamTools() { return [ defineTool({ name: 'linear_list_teams', label: 'Linear List Teams', description: 'List Linear teams and states. Supports full teams query args: after, before, filter, first, includeArchived, last, orderBy.', parameters: Type.Object({ ...PaginationParams, ...FilterParam, }), renderCall: renderLinearTeamListCall, async execute(_toolCallId, params, signal, _onUpdate, ctx) { return withLinearAuth(ctx, signal, async (apiKey) => { const variables = compactObject({ ...paginationVariables(params, 50), filter: asObject(params.filter), }); const data = await linearGraphQL<{ teams: LinearConnection }>( apiKey, `query ListTeams( $after: String $before: String $filter: TeamFilter $first: Int $includeArchived: Boolean $last: Int $orderBy: PaginationOrderBy ) { teams( after: $after before: $before filter: $filter first: $first includeArchived: $includeArchived last: $last orderBy: $orderBy ) { nodes { ${TEAM_SELECTION} states(first: 50) { nodes { id name type } } } pageInfo { hasNextPage hasPreviousPage startCursor endCursor } } }`, variables, signal, ); const teams = data.teams.nodes; const pageInfo = data.teams.pageInfo; return { content: [{ type: 'text', text: JSON.stringify({ teams, pageInfo }, null, 2) }], details: { teams, pageInfo }, }; }); }, renderResult: renderLinearTeamListResult, }), defineTool({ name: 'linear_get_team', label: 'Linear Get Team', description: 'Get a specific team by id.', parameters: Type.Object({ teamId: Type.String(), }), renderCall: renderLinearGetTeamCall, async execute(_toolCallId, params, signal, _onUpdate, ctx) { return withLinearAuth(ctx, signal, async (apiKey) => { const data = await linearGraphQL<{ team: JsonObject | null }>( apiKey, `query GetTeam($id: String!) { team(id: $id) { ${TEAM_SELECTION} } }`, { id: params.teamId }, signal, ); const team = data.team; return { content: [{ type: 'text', text: JSON.stringify({ team }, null, 2) }], details: { team }, }; }); }, renderResult: renderLinearTeamResult('Team'), }), ]; }