File tree Expand file tree Collapse file tree
services/linear-integration Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ import { FoldersService } from "../services/folders/service";
2121import { FsService } from "../services/fs/service" ;
2222import { GitService } from "../services/git/service" ;
2323import { GitHubIntegrationService } from "../services/github-integration/service" ;
24+ import { LinearIntegrationService } from "../services/linear-integration/service" ;
2425import { LlmGatewayService } from "../services/llm-gateway/service" ;
2526import { McpCallbackService } from "../services/mcp-callback/service" ;
2627import { NotificationService } from "../services/notification/service" ;
@@ -68,6 +69,9 @@ container
6869 . bind ( MAIN_TOKENS . GitHubIntegrationService )
6970 . to ( GitHubIntegrationService ) ;
7071container . bind ( MAIN_TOKENS . GitService ) . to ( GitService ) ;
72+ container
73+ . bind ( MAIN_TOKENS . LinearIntegrationService )
74+ . to ( LinearIntegrationService ) ;
7175container . bind ( MAIN_TOKENS . McpCallbackService ) . to ( McpCallbackService ) ;
7276container . bind ( MAIN_TOKENS . NotificationService ) . to ( NotificationService ) ;
7377container . bind ( MAIN_TOKENS . OAuthService ) . to ( OAuthService ) ;
Original file line number Diff line number Diff line change @@ -34,6 +34,7 @@ export const MAIN_TOKENS = Object.freeze({
3434 FsService : Symbol . for ( "Main.FsService" ) ,
3535 GitService : Symbol . for ( "Main.GitService" ) ,
3636 GitHubIntegrationService : Symbol . for ( "Main.GitHubIntegrationService" ) ,
37+ LinearIntegrationService : Symbol . for ( "Main.LinearIntegrationService" ) ,
3738 DeepLinkService : Symbol . for ( "Main.DeepLinkService" ) ,
3839 NotificationService : Symbol . for ( "Main.NotificationService" ) ,
3940 McpCallbackService : Symbol . for ( "Main.McpCallbackService" ) ,
Original file line number Diff line number Diff line change 1+ export {
2+ type CloudRegion ,
3+ cloudRegion ,
4+ type StartIntegrationFlowInput as StartLinearFlowInput ,
5+ type StartIntegrationFlowOutput as StartLinearFlowOutput ,
6+ startIntegrationFlowInput as startLinearFlowInput ,
7+ startIntegrationFlowOutput as startLinearFlowOutput ,
8+ } from "../integration-flow-schemas" ;
Original file line number Diff line number Diff line change 1+ import { getCloudUrlFromRegion } from "@shared/constants/oauth.js" ;
2+ import { shell } from "electron" ;
3+ import { injectable } from "inversify" ;
4+ import { logger } from "../../utils/logger.js" ;
5+ import type { CloudRegion , StartLinearFlowOutput } from "./schemas.js" ;
6+
7+ const log = logger . scope ( "linear-integration-service" ) ;
8+
9+ @injectable ( )
10+ export class LinearIntegrationService {
11+ public async startFlow (
12+ region : CloudRegion ,
13+ projectId : number ,
14+ ) : Promise < StartLinearFlowOutput > {
15+ try {
16+ const cloudUrl = getCloudUrlFromRegion ( region ) ;
17+ const next = `${ cloudUrl } /projects/${ projectId } ` ;
18+ const authorizeUrl = `${ cloudUrl } /api/environments/${ projectId } /integrations/authorize/?kind=linear&next=${ encodeURIComponent ( next ) } ` ;
19+
20+ log . info ( "Opening Linear authorization URL in browser" ) ;
21+ await shell . openExternal ( authorizeUrl ) ;
22+
23+ return { success : true } ;
24+ } catch ( error ) {
25+ return {
26+ success : false ,
27+ error : error instanceof Error ? error . message : "Unknown error" ,
28+ } ;
29+ }
30+ }
31+ }
Original file line number Diff line number Diff line change @@ -14,6 +14,7 @@ import { foldersRouter } from "./routers/folders";
1414import { fsRouter } from "./routers/fs" ;
1515import { gitRouter } from "./routers/git" ;
1616import { githubIntegrationRouter } from "./routers/github-integration" ;
17+ import { linearIntegrationRouter } from "./routers/linear-integration.js" ;
1718import { llmGatewayRouter } from "./routers/llm-gateway" ;
1819import { logsRouter } from "./routers/logs" ;
1920import { mcpCallbackRouter } from "./routers/mcp-callback" ;
@@ -46,6 +47,7 @@ export const trpcRouter = router({
4647 fs : fsRouter ,
4748 git : gitRouter ,
4849 githubIntegration : githubIntegrationRouter ,
50+ linearIntegration : linearIntegrationRouter ,
4951 llmGateway : llmGatewayRouter ,
5052 mcpCallback : mcpCallbackRouter ,
5153 notification : notificationRouter ,
Original file line number Diff line number Diff line change 1+ import { container } from "../../di/container.js" ;
2+ import { MAIN_TOKENS } from "../../di/tokens.js" ;
3+ import {
4+ startLinearFlowInput ,
5+ startLinearFlowOutput ,
6+ } from "../../services/linear-integration/schemas.js" ;
7+ import type { LinearIntegrationService } from "../../services/linear-integration/service.js" ;
8+ import { publicProcedure , router } from "../trpc.js" ;
9+
10+ const getService = ( ) =>
11+ container . get < LinearIntegrationService > ( MAIN_TOKENS . LinearIntegrationService ) ;
12+
13+ export const linearIntegrationRouter = router ( {
14+ startFlow : publicProcedure
15+ . input ( startLinearFlowInput )
16+ . output ( startLinearFlowOutput )
17+ . mutation ( ( { input } ) =>
18+ getService ( ) . startFlow ( input . region , input . projectId ) ,
19+ ) ,
20+ } ) ;
You can’t perform that action at this time.
0 commit comments