1+ import { Octokit } from '@octokit/rest' ;
2+
3+ const GITHUB_TOKEN = process .env .GITHUB_TOKEN ;
4+ const GITHUB_REPO_OWNER = process .env .GITHUB_REPO_OWNER ;
5+ const GITHUB_REPO_NAME = process .env .GITHUB_REPO_NAME ;
6+
7+ / * *
8+ * Creates a GitHub issue from the provided description and assigns it to @copilot - swe - agent if available .
9+ * Uses GraphQL for efficient repo / actor queries and issue creation with assignment .
10+ * Returns the issue URL on success , null on failure .
11+ * /
12+ export async function createIssueWithCopilot (description : string ): Promise < string | null > {
13+ if (!GITHUB_TOKEN | | !GITHUB_REPO_OWNER | | !GITHUB_REPO_NAME ) {
14+ return null ;
15+ }
16+
17+ if (!description .trim ()) {
18+ return null ;
19+ }
20+
21+ const octokit = new Octokit ({ auth : GITHUB_TOKEN });
22+
23+ try {
24+ // Fetch repo ID and check for @copilot - swe - agent
25+ const repoInfoQuery = `
26+ query ($owner : String !, $name : String !) {
27+ repository (owner : $owner , name : $name ) {
28+ id
29+ suggestedActors (capabilities : [CAN_BE_ASSIGNED ], first : 100 ) {
30+ nodes {
31+ login
32+ id
33+ }
34+ }
35+ }
36+ }
37+ `;
38+
39+ const repoInfo : any = await octokit .graphql (repoInfoQuery , {
40+ owner : GITHUB_REPO_OWNER ,
41+ name : GITHUB_REPO_NAME ,
42+ });
43+
44+ const repoId = repoInfo ?.repository ?.id ;
45+ if (!repoId ) {
46+ return null ;
47+ }
48+
49+ const copilotBot = repoInfo .repository .suggestedActors .nodes .find (
50+ (node : any ) = > node .login == = 'copilot-swe-agent'
51+ );
52+
53+ const title = description .split ('\n ' )[0 ].slice (0 , 100 );
54+
55+ if (!copilotBot ) {
56+ // Fallback : Create issue without assignment via REST
57+ const issue = await octokit .issues .create ({
58+ owner : GITHUB_REPO_OWNER ,
59+ repo : GITHUB_REPO_NAME ,
60+ title ,
61+ body : description ,
62+ });
63+
64+ return issue .data .html_url ;
65+ }
66+
67+ // Create issue with assignment via GraphQL
68+ const createIssueMutation = `
69+ mutation ($repoId : ID !, $title : String !, $body : String !, $assigneeIds : [ID !]) {
70+ createIssue (input : { repositoryId : $repoId , title : $title , body : $body , assigneeIds : $assigneeIds }) {
71+ issue {
72+ number
73+ title
74+ url
75+ assignees (first : 10 ) { nodes { login } }
76+ }
77+ }
78+ }
79+ `;
80+
81+ const response : any = await octokit .graphql (createIssueMutation , {
82+ repoId ,
83+ title ,
84+ body : description ,
85+ assigneeIds : [copilotBot .id ],
86+ });
87+
88+ const issue = response ?.createIssue ?.issue ;
89+ if (!issue ) {
90+ return null ;
91+ }
92+
93+ return issue .url ;
94+ } catch (error ) {
95+ console .error ('Error creating issue:' , error );
96+ return null ;
97+ }
98+ }
99+
100+ // CLI entry point
101+ const description = process .argv [2 ];
102+ if (!description ) {
103+ console .error ('Usage: npx tsx create-issue-assigned-to-copilot.py <description>' );
104+ process .exit (1 );
105+ }
106+ createIssueWithCopilot (description ).then ((url ) = > {
107+ if (url ) {
108+ console .log (`Issue created: ${url}` );
109+ } else {
110+ console .error ('Failed to create issue' );
111+ process .exit (1 );
112+ }
113+ });
0 commit comments