@@ -35,6 +35,7 @@ export interface ICopilotRemoteAgentCommandArgs {
35
35
userPrompt : string ;
36
36
summary ?: string ;
37
37
source ?: string ;
38
+ followup ?: string ;
38
39
}
39
40
40
41
const LEARN_MORE = vscode . l10n . t ( 'Learn about Coding Agent' ) ;
@@ -44,6 +45,9 @@ const CONTINUE = vscode.l10n.t('Continue');
44
45
const PUSH_CHANGES = vscode . l10n . t ( 'Include changes' ) ;
45
46
const CONTINUE_WITHOUT_PUSHING = vscode . l10n . t ( 'Ignore changes' ) ;
46
47
48
+ const FOLLOW_UP_REGEX = / o p e n - p u l l - r e q u e s t - w e b v i e w .* ( ( % 7 B .* ?% 7 D ) | ( \{ .* ?\} ) ) / ;
49
+ const COPILOT = '@copilot' ;
50
+
47
51
export class CopilotRemoteAgentManager extends Disposable {
48
52
public static ID = 'CopilotRemoteAgentManager' ;
49
53
@@ -201,12 +205,39 @@ export class CopilotRemoteAgentManager extends Disposable {
201
205
return { owner, repo, baseRef, remote, repository, ghRepository, fm } ;
202
206
}
203
207
208
+ private parseFollowup ( followup : string | undefined , repoInfo : { owner : string ; repo : string } ) : number | undefined {
209
+ if ( ! followup ) {
210
+ return ;
211
+ }
212
+ const match = followup . match ( FOLLOW_UP_REGEX ) ;
213
+ if ( ! match || match . length < 2 ) {
214
+ Logger . error ( `Ignoring. Invalid followup format: ${ followup } ` , CopilotRemoteAgentManager . ID ) ;
215
+ return ;
216
+ }
217
+
218
+ try {
219
+ const followUpData = JSON . parse ( decodeURIComponent ( match [ 1 ] ) ) ;
220
+ if ( ! followUpData || ! followUpData . owner || ! followUpData . repo || ! followUpData . pullRequestNumber ) {
221
+ Logger . error ( `Ignoring. Invalid followup data: ${ followUpData } ` , CopilotRemoteAgentManager . ID ) ;
222
+ return ;
223
+ }
224
+
225
+ if ( repoInfo . owner !== followUpData . owner || repoInfo . repo !== followUpData . repo ) {
226
+ Logger . error ( `Ignoring. Follow up data does not match current repository: ${ JSON . stringify ( followUpData ) } ` , CopilotRemoteAgentManager . ID ) ;
227
+ return ;
228
+ }
229
+ return followUpData . pullRequestNumber ;
230
+ } catch ( error ) {
231
+ Logger . error ( `Ignoring. Error while parsing follow up data: ${ followup } ` , CopilotRemoteAgentManager . ID ) ;
232
+ }
233
+ }
234
+
204
235
async commandImpl ( args ?: ICopilotRemoteAgentCommandArgs ) : Promise < string | undefined > {
205
236
if ( ! args ) {
206
237
return ;
207
238
}
208
239
209
- const { userPrompt, summary, source } = args ;
240
+ const { userPrompt, summary, source, followup } = args ;
210
241
if ( ! userPrompt || userPrompt . trim ( ) . length === 0 ) {
211
242
return ;
212
243
}
@@ -216,6 +247,36 @@ export class CopilotRemoteAgentManager extends Disposable {
216
247
return ;
217
248
}
218
249
const { repository, owner, repo } = repoInfo ;
250
+
251
+ // If this is a followup, parse out the necessary data
252
+ // Group 2 is this, url-encoded:
253
+ // {"owner":"monalisa","repo":"app","pullRequestNumber":18}
254
+ let followUpPR : number | undefined = this . parseFollowup ( followup , repoInfo ) ;
255
+ if ( followUpPR ) {
256
+ try {
257
+ const ghRepo = repoInfo . ghRepository ;
258
+ // Fetch the PullRequestModel by number
259
+ const pr = await ghRepo . getPullRequest ( followUpPR ) ;
260
+ if ( ! pr ) {
261
+ Logger . error ( `Could not find pull request #${ followUpPR } ` , CopilotRemoteAgentManager . ID ) ;
262
+ return ;
263
+ }
264
+ // Add a comment tagging @copilot with the user's prompt
265
+ const commentBody = `${ COPILOT } ${ userPrompt } \n\n --- \n\n ${ summary ?? '' } ` ;
266
+ const commentResult = await pr . createIssueComment ( commentBody ) ;
267
+ if ( ! commentResult ) {
268
+ Logger . error ( `Failed to add comment to PR #${ followUpPR } ` , CopilotRemoteAgentManager . ID ) ;
269
+ return ;
270
+ }
271
+ Logger . appendLine ( `Added comment ${ commentResult . htmlUrl } ` , CopilotRemoteAgentManager . ID ) ;
272
+ // allow-any-unicode-next-line
273
+ return vscode . l10n . t ( '🚀 Follow-up comment added to [#{0}]({1})' , followUpPR , commentResult . htmlUrl ) ;
274
+ } catch ( err ) {
275
+ Logger . error ( `Failed to add follow-up comment to PR #${ followUpPR } : ${ err } ` , CopilotRemoteAgentManager . ID ) ;
276
+ return ;
277
+ }
278
+ }
279
+
219
280
const repoName = `${ owner } /${ repo } ` ;
220
281
const hasChanges = repository . state . workingTreeChanges . length > 0 || repository . state . indexChanges . length > 0 ;
221
282
const learnMoreCb = async ( ) => {
0 commit comments