/** * Linear Integration for WORKWAY * * GraphQL-based integration for Linear project management. * Zuhandenheit: Developer thinks "create task" not "GraphQL mutation with teamId lookup" * * @example * ```typescript * import { Linear } from '@workwayco/integrations/linear'; * * const linear = new Linear({ accessToken: tokens.linear.access_token }); * * // Create an issue (Zuhandenheit: assignee by name, not ID) * const issue = await linear.createIssue({ * teamId: 'TEAM-123', * title: 'Fix login bug', * description: 'Users cannot login with SSO', * assigneeByName: 'john', * labels: ['bug', 'urgent'] * }); * * // List issues * const issues = await linear.listIssues({ teamId: 'TEAM-123', limit: 20 }); * * // Get current user * const me = await linear.getViewer(); * ``` */ import { ActionResult, type StandardTask, type StandardList } from '@workwayco/sdk'; /** * Linear issue object */ export interface LinearIssue { id: string; identifier: string; title: string; description?: string; priority: number; estimate?: number; url: string; createdAt: string; updatedAt: string; archivedAt?: string; state: { id: string; name: string; type: string; }; team: { id: string; name: string; key: string; }; assignee?: { id: string; name: string; email: string; }; creator?: { id: string; name: string; email: string; }; labels: { nodes: Array<{ id: string; name: string; color: string; }>; }; project?: { id: string; name: string; }; cycle?: { id: string; name: string; number: number; }; parent?: { id: string; identifier: string; title: string; }; children?: { nodes: Array<{ id: string; identifier: string; title: string; }>; }; comments?: { nodes: Array<{ id: string; body: string; createdAt: string; user: { id: string; name: string; }; }>; }; } /** * Linear team object */ export interface LinearTeam { id: string; name: string; key: string; description?: string; icon?: string; color?: string; private: boolean; states: { nodes: Array<{ id: string; name: string; type: string; position: number; }>; }; labels: { nodes: Array<{ id: string; name: string; color: string; }>; }; } /** * Linear user object */ export interface LinearUser { id: string; name: string; displayName: string; email: string; avatarUrl?: string; active: boolean; admin: boolean; createdAt: string; } /** * Linear project object */ export interface LinearProject { id: string; name: string; description?: string; icon?: string; color?: string; state: string; progress: number; targetDate?: string; startedAt?: string; completedAt?: string; url: string; } /** * Linear comment object */ export interface LinearComment { id: string; body: string; createdAt: string; updatedAt: string; user: { id: string; name: string; email: string; }; issue: { id: string; identifier: string; }; } export interface LinearConfig { /** OAuth access token or API key */ accessToken: string; /** Request timeout in ms (default: 30000) */ timeout?: number; } /** * Linear GraphQL API client * * Zuhandenheit principles: * - `assigneeByName` resolves user IDs automatically * - `labels` accepts names, not IDs * - Consistent ActionResult pattern across all methods * * Weniger, aber besser: No caching layer. Let GraphQL handle efficiency. */ export declare class Linear { private readonly accessToken; private readonly apiUrl; private readonly timeout; constructor(config: LinearConfig); /** * Execute a GraphQL query/mutation */ private graphql; /** * Execute GraphQL and return ActionResult */ private execute; /** * Create an issue * * Zuhandenheit: Developer thinks "assign to john" not "lookup john's user ID" * * @example * ```typescript * const issue = await linear.createIssue({ * teamId: 'TEAM-123', * title: 'Fix login bug', * assigneeByName: 'john', * labels: ['bug', 'urgent'] * }); * ``` */ createIssue(options: { teamId: string; title: string; description?: string; priority?: 0 | 1 | 2 | 3 | 4; estimate?: number; assigneeId?: string; assigneeByName?: string; stateId?: string; projectId?: string; cycleId?: string; parentId?: string; labelIds?: string[]; labels?: string[]; }): Promise>; /** * Update an issue */ updateIssue(options: { issueId: string; title?: string; description?: string; priority?: 0 | 1 | 2 | 3 | 4; estimate?: number; assigneeId?: string; assigneeByName?: string; stateId?: string; projectId?: string; cycleId?: string; parentId?: string; labelIds?: string[]; }): Promise>; /** * Get an issue by ID or identifier (e.g., "ENG-123") */ getIssue(issueId: string): Promise>; /** * List issues with filtering */ listIssues(options?: { teamId?: string; projectId?: string; assigneeId?: string; stateType?: 'backlog' | 'unstarted' | 'started' | 'completed' | 'canceled'; first?: number; after?: string; }): Promise>>; /** * Archive an issue (soft delete) */ archiveIssue(issueId: string): Promise>; /** * Add a comment to an issue */ createComment(options: { issueId: string; body: string; }): Promise>; /** * List teams */ listTeams(options?: { first?: number; }): Promise>>; /** * Get a team by ID * * Weniger, aber besser: Direct fetch, no caching complexity. */ getTeamById(teamId: string): Promise>; /** * Get the current authenticated user */ getViewer(): Promise>; /** * List users in the organization * * Weniger, aber besser: Direct fetch, no caching complexity. */ listUsers(options?: { first?: number; }): Promise>>; /** * Find user by name or email (Zuhandenheit helper) * * Weniger, aber besser: Simple search, no caching layer. */ findUserByName(nameOrEmail: string): Promise; /** * List projects */ listProjects(options?: { teamId?: string; first?: number; }): Promise>>; /** * Namespace for issue operations (matches workflow integration pattern) */ issues: { /** * Create an issue with Zuhandenheit patterns */ create: (options: Parameters[0]) => Promise>; /** * Update an issue */ update: (options: Parameters[0]) => Promise>; /** * Get an issue by ID */ get: (issueId: string) => Promise>; /** * List issues with filtering */ list: (options?: Parameters[0]) => Promise>>; /** * Archive an issue */ archive: (issueId: string) => Promise>; /** * Add a comment */ comment: (issueId: string, body: string) => Promise>; }; /** * Namespace for team operations */ teams: { list: (options?: Parameters[0]) => Promise>>; get: (teamId: string) => Promise>; }; /** * Namespace for user operations */ users: { list: (options?: Parameters[0]) => Promise>>; me: () => Promise>; find: (nameOrEmail: string) => Promise; }; /** * Namespace for project operations */ projects: { list: (options?: Parameters[0]) => Promise>>; }; } /** * Convert Linear issue to StandardTask */ export declare function toStandardTask(issue: LinearIssue): StandardTask; /** * Export default class */ export default Linear; //# sourceMappingURL=index.d.ts.map