@@ -11,11 +11,12 @@ import { EventType, sendTelemetryEvent, UserFlowStatus } from "../telemetry";
11
11
*/
12
12
export async function updateCopilotInstructions (
13
13
trigger : "Command" | "Project" | "Activation" | "ChatToolCall" ,
14
- extensionUri : vscode . Uri ,
14
+ context : vscode . ExtensionContext ,
15
15
) : Promise < string | undefined > {
16
+ const globalStateUri = context . globalStorageUri ;
16
17
const userInvoked = trigger === "Command" ;
17
18
18
- if ( isExtensionInstructionsConfigured ( extensionUri ) ) {
19
+ if ( isExtensionInstructionsConfigured ( globalStateUri ) ) {
19
20
if ( userInvoked ) {
20
21
// fire-and-forget
21
22
showInfoMessage ( "Copilot instructions for Q# are already configured." , {
@@ -53,7 +54,7 @@ export async function updateCopilotInstructions(
53
54
}
54
55
55
56
try {
56
- await addExtensionInstructionsToUserConfig ( extensionUri ) ;
57
+ await addExtensionInstructionsToUserConfig ( globalStateUri ) ;
57
58
const removedOldInstructions = await removeOldQSharpCopilotInstructions ( ) ;
58
59
59
60
// fire-and-forget
@@ -93,8 +94,10 @@ export async function updateCopilotInstructions(
93
94
* Checks the user's instructionsFilesLocations setting to see if
94
95
* our extension's instructions directory is already included.
95
96
*/
96
- function isExtensionInstructionsConfigured ( extensionUri : vscode . Uri ) : boolean {
97
- const extensionInstructionsDir = getExtensionInstructionsDir ( extensionUri ) ;
97
+ function isExtensionInstructionsConfigured (
98
+ globalStateUri : vscode . Uri ,
99
+ ) : boolean {
100
+ const extensionInstructionsDir = getExtensionInstructionsDir ( globalStateUri ) ;
98
101
const instructionsLocations = getConfiguredInstructionsFilesLocations ( ) ;
99
102
100
103
// Check if our directory is in the map as a key and it's enabled (true)
@@ -109,10 +112,10 @@ function isExtensionInstructionsConfigured(extensionUri: vscode.Uri): boolean {
109
112
* our extension's instructions directory.
110
113
*/
111
114
async function addExtensionInstructionsToUserConfig (
112
- extensionUri : vscode . Uri ,
115
+ globalStateUri : vscode . Uri ,
113
116
) : Promise < void > {
114
117
const instructionsLocations = getConfiguredInstructionsFilesLocations ( ) ;
115
- const extensionInstructionsDir = getExtensionInstructionsDir ( extensionUri ) ;
118
+ const extensionInstructionsDir = getExtensionInstructionsDir ( globalStateUri ) ;
116
119
117
120
// Only add the extension's chat-instructions directory
118
121
// if it's not already configured or if it's disabled
@@ -149,9 +152,9 @@ function getConfiguredInstructionsFilesLocations(): Record<string, boolean> {
149
152
*
150
153
* TODO: create GitHub issue to track how we handle this in the browser.
151
154
*/
152
- function getExtensionInstructionsDir ( extensionUri : vscode . Uri ) : string {
155
+ function getExtensionInstructionsDir ( globalStateUri : vscode . Uri ) : string {
153
156
const instructionsUri = vscode . Uri . joinPath (
154
- extensionUri ,
157
+ globalStateUri ,
155
158
"chat-instructions" ,
156
159
) ;
157
160
@@ -298,37 +301,66 @@ function getOldInstructionsFileLocation(
298
301
) ;
299
302
}
300
303
304
+ async function copyInstructionsFileToGlobalStorage (
305
+ context : vscode . ExtensionContext ,
306
+ ) {
307
+ const source = vscode . Uri . joinPath (
308
+ context . extensionUri ,
309
+ "chat-instructions" ,
310
+ "qsharp.instructions.md" ,
311
+ ) ;
312
+
313
+ const target = vscode . Uri . joinPath (
314
+ context . globalStorageUri ,
315
+ "chat-instructions" ,
316
+ "qsharp.instructions.md" ,
317
+ ) ;
318
+
319
+ try {
320
+ await vscode . workspace . fs . copy ( source , target , { overwrite : true } ) ;
321
+ return true ;
322
+ } catch {
323
+ log . warn (
324
+ `Error copying Q# instructions file from ${ source . toString ( ) } to ${ target . toString ( ) } ` ,
325
+ ) ;
326
+ return false ;
327
+ }
328
+ }
329
+
301
330
/**
302
331
* Registers the command to configure GitHub Copilot to use Q# coding instructions.
303
332
* This updates the chat.instructionsFilesLocations setting to include the extension's
304
333
* chat-instructions directory, rather than creating a file in the user's workspace.
305
334
*/
306
- export function registerGhCopilotInstructionsCommand (
335
+ export async function registerGhCopilotInstructionsCommand (
307
336
context : vscode . ExtensionContext ,
308
337
) {
309
338
context . subscriptions . push (
310
339
vscode . commands . registerCommand (
311
340
"qsharp-vscode.updateCopilotInstructions" ,
312
- ( ) => updateCopilotInstructions ( "Command" , context . extensionUri ) ,
341
+ ( ) => updateCopilotInstructions ( "Command" , context ) ,
313
342
) ,
314
343
) ;
315
344
345
+ // Copy the instructions file to the global storage location
346
+ // The global storage location is stable across versions,
347
+ // but our instructions content may change from version to version.
348
+ await copyInstructionsFileToGlobalStorage ( context ) ;
349
+
316
350
// Also do a one-time prompt at activation time
317
351
if (
318
352
context . globalState . get < boolean > (
319
- "showUpdateCopilotInstructionsPromptAtStartup1" ,
353
+ "showUpdateCopilotInstructionsPromptAtStartup2" , // TODO
320
354
true ,
321
355
)
322
356
) {
323
- updateCopilotInstructions ( "Activation" , context . extensionUri ) . then (
324
- ( response ) => {
325
- if ( response === "Don't show again" ) {
326
- context . globalState . update (
327
- "showUpdateCopilotInstructionsPromptAtStartup1" ,
328
- false ,
329
- ) ;
330
- }
331
- } ,
332
- ) ;
357
+ updateCopilotInstructions ( "Activation" , context ) . then ( ( response ) => {
358
+ if ( response === "Don't show again" ) {
359
+ context . globalState . update (
360
+ "showUpdateCopilotInstructionsPromptAtStartup2" , // TODO
361
+ false ,
362
+ ) ;
363
+ }
364
+ } ) ;
333
365
}
334
366
}
0 commit comments