diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts index e881fc4c336..f2cfdd54ec4 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatActions.ts @@ -79,8 +79,8 @@ export const CHAT_SETUP_ACTION_ID = 'workbench.action.chat.triggerSetup'; export const CHAT_SETUP_SUPPORT_ANONYMOUS_ACTION_ID = 'workbench.action.chat.triggerSetupSupportAnonymousAction'; const TOGGLE_CHAT_ACTION_ID = 'workbench.action.chat.toggle'; -export const GENERATE_INSTRUCTIONS_COMMAND_ID = 'workbench.action.chat.generateInstructions'; -export const GENERATE_INSTRUCTION_COMMAND_ID = 'workbench.action.chat.generateInstruction'; +export const GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID = 'workbench.action.chat.generateAgentInstructions'; +export const GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID = 'workbench.action.chat.generateOnDemandInstructions'; export const GENERATE_PROMPT_COMMAND_ID = 'workbench.action.chat.generatePrompt'; export const GENERATE_SKILL_COMMAND_ID = 'workbench.action.chat.generateSkill'; export const GENERATE_AGENT_COMMAND_ID = 'workbench.action.chat.generateAgent'; @@ -1235,9 +1235,8 @@ export function registerChatActions() { registerAction2(class GenerateInstructionsAction extends Action2 { constructor() { super({ - id: GENERATE_INSTRUCTIONS_COMMAND_ID, - title: localize2('generateInstructions', "Generate Workspace Instructions with Agent"), - shortTitle: localize2('generateInstructions.short', "Generate Instructions with Agent"), + id: GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID, + title: localize2('generateInstructions', "Generate Agent Instructions"), category: CHAT_CATEGORY, icon: Codicon.sparkle, f1: true, @@ -1258,9 +1257,8 @@ export function registerChatActions() { registerAction2(class GenerateInstructionAction extends Action2 { constructor() { super({ - id: GENERATE_INSTRUCTION_COMMAND_ID, - title: localize2('generateInstruction', "Generate On-demand Instruction with Agent"), - shortTitle: localize2('generateInstruction.short', "Generate Instruction with Agent"), + id: GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID, + title: localize2('generateOnDemandInstructions', "Generate On-Demand Instructions"), category: CHAT_CATEGORY, icon: Codicon.sparkle, f1: true, @@ -1272,7 +1270,7 @@ export function registerChatActions() { const commandService = accessor.get(ICommandService); await commandService.executeCommand('workbench.action.chat.open', { mode: 'agent', - query: '/create-instruction ', + query: '/create-instructions ', isPartialQuery: true, }); } @@ -1282,8 +1280,8 @@ export function registerChatActions() { constructor() { super({ id: GENERATE_PROMPT_COMMAND_ID, - title: localize2('generatePrompt', "Generate Prompt File with Agent"), - shortTitle: localize2('generatePrompt.short', "Generate Prompt with Agent"), + title: localize2('generatePrompt', "Generate Prompt File"), + shortTitle: localize2('generatePrompt.short', "Generate Prompt"), category: CHAT_CATEGORY, icon: Codicon.sparkle, f1: true, @@ -1305,8 +1303,8 @@ export function registerChatActions() { constructor() { super({ id: GENERATE_SKILL_COMMAND_ID, - title: localize2('generateSkill', "Generate Skill with Agent"), - shortTitle: localize2('generateSkill.short', "Generate Skill with Agent"), + title: localize2('generateSkill', "Generate Skill"), + shortTitle: localize2('generateSkill.short', "Generate Skill"), category: CHAT_CATEGORY, icon: Codicon.sparkle, f1: true, @@ -1328,8 +1326,8 @@ export function registerChatActions() { constructor() { super({ id: GENERATE_AGENT_COMMAND_ID, - title: localize2('generateAgent', "Generate Custom Agent with Agent"), - shortTitle: localize2('generateAgent.short', "Generate Agent with Agent"), + title: localize2('generateAgent', "Generate Custom Agent"), + shortTitle: localize2('generateAgent.short', "Generate Agent"), category: CHAT_CATEGORY, icon: Codicon.sparkle, f1: true, @@ -1351,8 +1349,8 @@ export function registerChatActions() { constructor() { super({ id: GENERATE_HOOK_COMMAND_ID, - title: localize2('generateHook', "Generate Hook with Agent"), - shortTitle: localize2('generateHook.short', "Generate Hook with Agent"), + title: localize2('generateHook', "Generate Hook"), + shortTitle: localize2('generateHook.short', "Generate Hook"), category: CHAT_CATEGORY, icon: Codicon.sparkle, f1: true, diff --git a/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWorkspaceService.ts b/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWorkspaceService.ts index 07684fb6a10..50a5f6acc17 100644 --- a/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWorkspaceService.ts +++ b/src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationWorkspaceService.ts @@ -14,7 +14,7 @@ import { PromptsType } from '../../common/promptSyntax/promptTypes.js'; import { GENERATE_AGENT_COMMAND_ID, GENERATE_HOOK_COMMAND_ID, - GENERATE_INSTRUCTION_COMMAND_ID, + GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID, GENERATE_PROMPT_COMMAND_ID, GENERATE_SKILL_COMMAND_ID, } from '../actions/chatActions.js'; @@ -76,7 +76,7 @@ class AICustomizationWorkspaceService implements IAICustomizationWorkspaceServic const commandIds: Partial> = { [PromptsType.agent]: GENERATE_AGENT_COMMAND_ID, [PromptsType.skill]: GENERATE_SKILL_COMMAND_ID, - [PromptsType.instructions]: GENERATE_INSTRUCTION_COMMAND_ID, + [PromptsType.instructions]: GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID, [PromptsType.prompt]: GENERATE_PROMPT_COMMAND_ID, [PromptsType.hook]: GENERATE_HOOK_COMMAND_ID, }; diff --git a/src/vs/workbench/contrib/chat/browser/chatTipService.ts b/src/vs/workbench/contrib/chat/browser/chatTipService.ts index 7f2559f5895..c830a665e7a 100644 --- a/src/vs/workbench/contrib/chat/browser/chatTipService.ts +++ b/src/vs/workbench/contrib/chat/browser/chatTipService.ts @@ -26,6 +26,7 @@ import { CreateSlashCommandsUsageTracker } from './createSlashCommandsUsageTrack import { ChatEntitlement, IChatEntitlementService } from '../../../services/chat/common/chatEntitlementService.js'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js'; import { ChatRequestDynamicVariablePart, ChatRequestSlashCommandPart, IParsedChatRequest } from '../common/requestParser/chatParserTypes.js'; +import { GENERATE_AGENT_COMMAND_ID, GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID, GENERATE_PROMPT_COMMAND_ID, GENERATE_SKILL_COMMAND_ID } from './actions/chatActions.js'; type ChatTipEvent = { tipId: string; @@ -41,11 +42,11 @@ type ChatTipClassification = { comment: 'Tracks user interactions with chat tips to understand which tips resonate and which are dismissed.'; }; -const ATTACH_FILES_REFERENCE_TRACKING_COMMAND = 'chat.tips.attachFiles.referenceUsed'; -const CREATE_INSTRUCTION_TRACKING_COMMAND = 'chat.tips.createInstruction.commandUsed'; -const CREATE_PROMPT_TRACKING_COMMAND = 'chat.tips.createPrompt.commandUsed'; -const CREATE_AGENT_TRACKING_COMMAND = 'chat.tips.createAgent.commandUsed'; -const CREATE_SKILL_TRACKING_COMMAND = 'chat.tips.createSkill.commandUsed'; +export const ATTACH_FILES_REFERENCE_TRACKING_COMMAND = 'chat.tips.attachFiles.referenceUsed'; +export const CREATE_AGENT_INSTRUCTIONS_TRACKING_COMMAND = 'chat.tips.createAgentInstructions.commandUsed'; +export const CREATE_PROMPT_TRACKING_COMMAND = 'chat.tips.createPrompt.commandUsed'; +export const CREATE_AGENT_TRACKING_COMMAND = 'chat.tips.createAgent.commandUsed'; +export const CREATE_SKILL_TRACKING_COMMAND = 'chat.tips.createSkill.commandUsed'; export const IChatTipService = createDecorator('chatTipService'); @@ -197,25 +198,27 @@ const TIP_CATALOG: ITipDefinition[] = [ id: 'tip.createInstruction', message: localize( 'tip.createInstruction', - "Tip: Use [/create-instruction](command:workbench.action.chat.generateInstruction) to generate an on-demand instruction file with the agent." + "Tip: Use [/create-instructions](command:{0}) to generate an on-demand instructions file with the agent.", + GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID ), when: ChatContextKeys.chatSessionType.isEqualTo(localChatSessionType), - enabledCommands: ['workbench.action.chat.generateInstruction'], + enabledCommands: [GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID], excludeWhenCommandsExecuted: [ - 'workbench.action.chat.generateInstruction', - CREATE_INSTRUCTION_TRACKING_COMMAND, + GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID, + CREATE_AGENT_INSTRUCTIONS_TRACKING_COMMAND, ], }, { id: 'tip.createPrompt', message: localize( 'tip.createPrompt', - "Tip: Use [/create-prompt](command:workbench.action.chat.generatePrompt) to generate a reusable prompt file with the agent." + "Tip: Use [/create-prompt](command:{0}) to generate a reusable prompt file with the agent.", + GENERATE_PROMPT_COMMAND_ID ), when: ChatContextKeys.chatSessionType.isEqualTo(localChatSessionType), - enabledCommands: ['workbench.action.chat.generatePrompt'], + enabledCommands: [GENERATE_PROMPT_COMMAND_ID], excludeWhenCommandsExecuted: [ - 'workbench.action.chat.generatePrompt', + GENERATE_PROMPT_COMMAND_ID, CREATE_PROMPT_TRACKING_COMMAND, ], }, @@ -223,12 +226,13 @@ const TIP_CATALOG: ITipDefinition[] = [ id: 'tip.createAgent', message: localize( 'tip.createAgent', - "Tip: Use [/create-agent](command:workbench.action.chat.generateAgent) to scaffold a custom agent for your workflow." + "Tip: Use [/create-agent](command:{0}) to scaffold a custom agent for your workflow.", + GENERATE_AGENT_COMMAND_ID ), when: ChatContextKeys.chatSessionType.isEqualTo(localChatSessionType), - enabledCommands: ['workbench.action.chat.generateAgent'], + enabledCommands: [GENERATE_AGENT_COMMAND_ID], excludeWhenCommandsExecuted: [ - 'workbench.action.chat.generateAgent', + GENERATE_AGENT_COMMAND_ID, CREATE_AGENT_TRACKING_COMMAND, ], }, @@ -236,12 +240,13 @@ const TIP_CATALOG: ITipDefinition[] = [ id: 'tip.createSkill', message: localize( 'tip.createSkill', - "Tip: Use [/create-skill](command:workbench.action.chat.generateSkill) to create a skill the agent can load when relevant." + "Tip: Use [/create-skill](command:{0}) to create a skill the agent can load when relevant.", + GENERATE_SKILL_COMMAND_ID ), when: ChatContextKeys.chatSessionType.isEqualTo(localChatSessionType), - enabledCommands: ['workbench.action.chat.generateSkill'], + enabledCommands: [GENERATE_SKILL_COMMAND_ID], excludeWhenCommandsExecuted: [ - 'workbench.action.chat.generateSkill', + GENERATE_SKILL_COMMAND_ID, CREATE_SKILL_TRACKING_COMMAND, ], }, @@ -759,14 +764,14 @@ export class ChatTipService extends Disposable implements IChatTipService { } const trimmed = message.text.trimStart(); - const match = /^\/(create-(?:instruction|prompt|agent|skill))(?:\s|$)/.exec(trimmed); + const match = /^\/(create-(?:instructions|prompt|agent|skill))(?:\s|$)/.exec(trimmed); return match ? this._toCreateSlashCommandTrackingId(match[1]) : undefined; } private _toCreateSlashCommandTrackingId(command: string): string | undefined { switch (command) { - case 'create-instruction': - return CREATE_INSTRUCTION_TRACKING_COMMAND; + case 'create-instructions': + return CREATE_AGENT_INSTRUCTIONS_TRACKING_COMMAND; case 'create-prompt': return CREATE_PROMPT_TRACKING_COMMAND; case 'create-agent': diff --git a/src/vs/workbench/contrib/chat/browser/createSlashCommandsUsageTracker.ts b/src/vs/workbench/contrib/chat/browser/createSlashCommandsUsageTracker.ts index c22041aa980..eea1a645a61 100644 --- a/src/vs/workbench/contrib/chat/browser/createSlashCommandsUsageTracker.ts +++ b/src/vs/workbench/contrib/chat/browser/createSlashCommandsUsageTracker.ts @@ -38,7 +38,7 @@ export class CreateSlashCommandsUsageTracker extends Disposable { // Fallback when parsing doesn't produce a slash command part. const trimmed = message.text.trimStart(); - const match = /^\/(create-(?:instruction|prompt|agent|skill))(?:\s|$)/.exec(trimmed); + const match = /^\/(create-(?:instructions|prompt|agent|skill))(?:\s|$)/.exec(trimmed); if (match && CreateSlashCommandsUsageTracker._isCreateSlashCommand(match[1])) { this._markUsed(); } @@ -65,7 +65,7 @@ export class CreateSlashCommandsUsageTracker extends Disposable { private static _isCreateSlashCommand(command: string): boolean { switch (command) { - case 'create-instruction': + case 'create-instructions': case 'create-prompt': case 'create-agent': case 'create-skill': diff --git a/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.ts b/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.ts index 15f6f5b34f6..fc1d34ba099 100644 --- a/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.ts +++ b/src/vs/workbench/contrib/chat/browser/promptSyntax/newPromptFileActions.ts @@ -186,7 +186,7 @@ function getDefaultContentSnippet(promptType: PromptsType, name: string | undefi `. - "src/**/*.ts"`, `---`, ``, - ``, + ``, ``, `\${2:Provide coding guidelines that AI should follow when generating code, answering questions, or reviewing changes.}`, ].join('\n'); @@ -197,7 +197,7 @@ function getDefaultContentSnippet(promptType: PromptsType, name: string | undefi `# applyTo: '\${1|**,**/*.ts|}' # when provided, instructions will automatically be added to the request context when the pattern matches an attached file`, `---`, ``, - ``, + ``, ``, `\${2:Provide project context and coding guidelines that AI should follow when generating code, answering questions, or reviewing changes.}`, ].join('\n'); diff --git a/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.ts b/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.ts index 3f932d05506..54b363863fb 100644 --- a/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.ts +++ b/src/vs/workbench/contrib/chat/browser/promptSyntax/pickers/promptFilePickers.ts @@ -17,7 +17,7 @@ import { ICommandService } from '../../../../../../platform/commands/common/comm import { getCleanPromptName } from '../../../common/promptSyntax/config/promptFileLocations.js'; import { PromptsType, INSTRUCTIONS_DOCUMENTATION_URL, AGENT_DOCUMENTATION_URL, PROMPT_DOCUMENTATION_URL, SKILL_DOCUMENTATION_URL, HOOK_DOCUMENTATION_URL } from '../../../common/promptSyntax/promptTypes.js'; import { NEW_PROMPT_COMMAND_ID, NEW_INSTRUCTIONS_COMMAND_ID, NEW_AGENT_COMMAND_ID, NEW_SKILL_COMMAND_ID } from '../newPromptFileActions.js'; -import { GENERATE_INSTRUCTIONS_COMMAND_ID, GENERATE_INSTRUCTION_COMMAND_ID, GENERATE_PROMPT_COMMAND_ID, GENERATE_SKILL_COMMAND_ID, GENERATE_AGENT_COMMAND_ID } from '../../actions/chatActions.js'; +import { GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID, GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID, GENERATE_PROMPT_COMMAND_ID, GENERATE_SKILL_COMMAND_ID, GENERATE_AGENT_COMMAND_ID } from '../../actions/chatActions.js'; import { IKeyMods, IQuickInputButton, IQuickInputService, IQuickPick, IQuickPickItem, IQuickPickItemButtonEvent, IQuickPickSeparator } from '../../../../../../platform/quickinput/common/quickInput.js'; import { askForPromptFileName } from './askForPromptName.js'; import { IInstantiationService } from '../../../../../../platform/instantiation/common/instantiation.js'; @@ -170,33 +170,33 @@ const NEW_INSTRUCTIONS_FILE_OPTION: IPromptPickerQuickPickItem = { }; /** - * A quick pick item that starts the 'Generate Workspace Instructions' command. + * A quick pick item that starts the 'Generate Agent Instructions' command. */ -const GENERATE_WORKSPACE_INSTRUCTIONS_OPTION: IPromptPickerQuickPickItem = { +const GENERATE_AGENT_INSTRUCTIONS_OPTION: IPromptPickerQuickPickItem = { type: 'item', label: `$(sparkle) ${localize( - 'commands.generate-workspace-instructions.select-dialog.label', - 'Generate workspace instructions with agent...', + 'commands.generate-agent-instructions.select-dialog.label', + 'Generate agent instructions...', )}`, pickable: false, alwaysShow: true, buttons: [newHelpButton(PromptsType.instructions)], - commandId: GENERATE_INSTRUCTIONS_COMMAND_ID, + commandId: GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID, }; /** - * A quick pick item that starts the 'Generate On-demand Instruction' command. + * A quick pick item that starts the 'Generate On-demand Instructions' command. */ -const GENERATE_INSTRUCTION_OPTION: IPromptPickerQuickPickItem = { +const GENERATE_ON_DEMAND_INSTRUCTIONS_OPTION: IPromptPickerQuickPickItem = { type: 'item', label: `$(sparkle) ${localize( - 'commands.generate-instruction.select-dialog.label', - 'Generate on-demand instruction with agent...', + 'commands.generate-on-demand-instructions.select-dialog.label', + 'Generate on-demand instructions...', )}`, pickable: false, alwaysShow: true, buttons: [newHelpButton(PromptsType.instructions)], - commandId: GENERATE_INSTRUCTION_COMMAND_ID, + commandId: GENERATE_ON_DEMAND_INSTRUCTIONS_COMMAND_ID, }; /** @@ -236,7 +236,7 @@ const GENERATE_PROMPT_OPTION: IPromptPickerQuickPickItem = { type: 'item', label: `$(sparkle) ${localize( 'commands.generate-prompt.select-dialog.label', - 'Generate prompt with agent...', + 'Generate prompt...', )}`, pickable: false, alwaysShow: true, @@ -251,7 +251,7 @@ const GENERATE_SKILL_OPTION: IPromptPickerQuickPickItem = { type: 'item', label: `$(sparkle) ${localize( 'commands.generate-skill.select-dialog.label', - 'Generate skill with agent...', + 'Generate skill...', )}`, pickable: false, alwaysShow: true, @@ -266,7 +266,7 @@ const GENERATE_AGENT_OPTION: IPromptPickerQuickPickItem = { type: 'item', label: `$(sparkle) ${localize( 'commands.generate-agent.select-dialog.label', - 'Generate agent with agent...', + 'Generate agent...', )}`, pickable: false, alwaysShow: true, @@ -537,7 +537,7 @@ export class PromptFilePickers { case PromptsType.prompt: return [NEW_PROMPT_FILE_OPTION, GENERATE_PROMPT_OPTION]; case PromptsType.instructions: - return [NEW_INSTRUCTIONS_FILE_OPTION, GENERATE_INSTRUCTION_OPTION, GENERATE_WORKSPACE_INSTRUCTIONS_OPTION]; + return [NEW_INSTRUCTIONS_FILE_OPTION, GENERATE_ON_DEMAND_INSTRUCTIONS_OPTION, GENERATE_AGENT_INSTRUCTIONS_OPTION]; case PromptsType.agent: return [NEW_AGENT_FILE_OPTION, GENERATE_AGENT_OPTION]; case PromptsType.skill: diff --git a/src/vs/workbench/contrib/chat/browser/widget/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/widget/chatWidget.ts index 02c21214878..48e7be78cd2 100644 --- a/src/vs/workbench/contrib/chat/browser/widget/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/widget/chatWidget.ts @@ -72,7 +72,7 @@ import { ComputeAutomaticInstructions } from '../../common/promptSyntax/computeA import { PromptsConfig } from '../../common/promptSyntax/config/config.js'; import { IHandOff, PromptHeader } from '../../common/promptSyntax/promptFileParser.js'; import { IPromptsService, PromptsStorage } from '../../common/promptSyntax/service/promptsService.js'; -import { handleModeSwitch } from '../actions/chatActions.js'; +import { GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID, handleModeSwitch } from '../actions/chatActions.js'; import { ChatTreeItem, IChatAcceptInputOptions, IChatAccessibilityService, IChatCodeBlockInfo, IChatFileTreeInfo, IChatListItemRendererOptions, IChatWidget, IChatWidgetService, IChatWidgetViewContext, IChatWidgetViewModelChangeEvent, IChatWidgetViewOptions, isIChatResourceViewContext, isIChatViewViewContext } from '../chat.js'; import { ChatAttachmentModel } from '../attachments/chatAttachmentModel.js'; import { IChatAttachmentResolveService } from '../attachments/chatAttachmentResolveService.js'; @@ -1077,12 +1077,11 @@ export class ChatWidget extends Disposable implements IChatWidget { return new MarkdownString(''); } else if (this._instructionFilesExist === false) { // Show generate instructions message if no files exist - const generateInstructionsCommand = 'workbench.action.chat.generateInstructions'; return new MarkdownString(localize( 'chatWidget.instructions', "[Generate Agent Instructions]({0}) to onboard AI onto your codebase.", - `command:${generateInstructionsCommand}` - ), { isTrusted: { enabledCommands: [generateInstructionsCommand] } }); + `command:${GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID}` + ), { isTrusted: { enabledCommands: [GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID] } }); } // While checking, don't show the generate instructions message diff --git a/src/vs/workbench/contrib/chat/test/browser/chatTipService.test.ts b/src/vs/workbench/contrib/chat/test/browser/chatTipService.test.ts index 8be5fe9be00..814c6c740b9 100644 --- a/src/vs/workbench/contrib/chat/test/browser/chatTipService.test.ts +++ b/src/vs/workbench/contrib/chat/test/browser/chatTipService.test.ts @@ -15,7 +15,7 @@ import { MockContextKeyService } from '../../../../../platform/keybinding/test/c import { ILogService, NullLogService } from '../../../../../platform/log/common/log.js'; import { IProductService } from '../../../../../platform/product/common/productService.js'; import { IStorageService, InMemoryStorageService, StorageScope, StorageTarget } from '../../../../../platform/storage/common/storage.js'; -import { ChatTipService, IChatTip, ITipDefinition, TipEligibilityTracker } from '../../browser/chatTipService.js'; +import { ChatTipService, CREATE_AGENT_INSTRUCTIONS_TRACKING_COMMAND, CREATE_AGENT_TRACKING_COMMAND, CREATE_PROMPT_TRACKING_COMMAND, CREATE_SKILL_TRACKING_COMMAND, IChatTip, ITipDefinition, TipEligibilityTracker } from '../../browser/chatTipService.js'; import { AgentFileType, IPromptPath, IPromptsService, IResolvedAgentFile, PromptsStorage } from '../../common/promptSyntax/service/promptsService.js'; import { URI } from '../../../../../base/common/uri.js'; import { ChatContextKeys } from '../../common/actions/chatContextKeys.js'; @@ -34,6 +34,7 @@ import { Range } from '../../../../../editor/common/core/range.js'; import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js'; import { NullTelemetryService } from '../../../../../platform/telemetry/common/telemetryUtils.js'; import { localChatSessionType } from '../../common/chatSessionsService.js'; +import { GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID } from '../../browser/actions/chatActions.js'; class MockContextKeyServiceWithRulesMatching extends MockContextKeyService { override contextMatchesRules(rules: ContextKeyExpression): boolean { @@ -167,10 +168,10 @@ suite('ChatTipService', () => { }); const executedCommands = JSON.parse(storageService.get('chat.tips.executedCommands', StorageScope.APPLICATION) ?? '[]') as string[]; - assert.ok(executedCommands.includes('chat.tips.createPrompt.commandUsed')); - assert.ok(!executedCommands.includes('chat.tips.createInstruction.commandUsed')); - assert.ok(!executedCommands.includes('chat.tips.createAgent.commandUsed')); - assert.ok(!executedCommands.includes('chat.tips.createSkill.commandUsed')); + assert.ok(executedCommands.includes(CREATE_PROMPT_TRACKING_COMMAND)); + assert.ok(!executedCommands.includes(CREATE_AGENT_INSTRUCTIONS_TRACKING_COMMAND)); + assert.ok(!executedCommands.includes(CREATE_AGENT_TRACKING_COMMAND)); + assert.ok(!executedCommands.includes(CREATE_SKILL_TRACKING_COMMAND)); }); test('returns Auto switch tip when current model is gpt-4.1', () => { @@ -606,7 +607,7 @@ suite('ChatTipService', () => { const tip: ITipDefinition = { id: 'tip.customInstructions', message: 'test', - excludeWhenCommandsExecuted: ['workbench.action.chat.generateInstructions'], + excludeWhenCommandsExecuted: [GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID], }; const tracker = testDisposables.add(new TipEligibilityTracker( @@ -620,7 +621,7 @@ suite('ChatTipService', () => { assert.strictEqual(tracker.isExcluded(tip), false, 'Should not be excluded before command is executed'); - commandExecutedEmitter.fire({ commandId: 'workbench.action.chat.generateInstructions', args: [] }); + commandExecutedEmitter.fire({ commandId: GENERATE_AGENT_INSTRUCTIONS_COMMAND_ID, args: [] }); assert.strictEqual(tracker.isExcluded(tip), true, 'Should be excluded after generate instructions command is executed'); }); @@ -941,7 +942,7 @@ suite('ChatTipService', () => { }); test('does not show create prompt tip when create prompt was already used', () => { - storageService.store('chat.tips.executedCommands', JSON.stringify(['chat.tips.createPrompt.commandUsed']), StorageScope.APPLICATION, StorageTarget.MACHINE); + storageService.store('chat.tips.executedCommands', JSON.stringify([CREATE_PROMPT_TRACKING_COMMAND]), StorageScope.APPLICATION, StorageTarget.MACHINE); const service = createService(); contextKeyService.createKey(ChatContextKeys.chatSessionType.key, localChatSessionType); @@ -1376,7 +1377,7 @@ suite('CreateSlashCommandsUsageTracker', () => { assert.strictEqual(value, true, 'Context key should be true when create commands have been used'); }); - test('detects create-instruction slash command via text fallback', () => { + test('detects create-instructions slash command via text fallback', () => { const sessionResource = URI.parse('chat:session1'); const tracker = createTracker(); tracker.syncContextKey(contextKeyService); @@ -1384,7 +1385,7 @@ suite('CreateSlashCommandsUsageTracker', () => { sessions.set(sessionResource.toString(), { lastRequest: { message: { - text: '/create-instruction test', + text: '/create-instructions test', parts: [], }, }, @@ -1393,7 +1394,7 @@ suite('CreateSlashCommandsUsageTracker', () => { submitRequestEmitter.fire({ chatSessionResource: sessionResource }); const value = contextKeyService.getContextKeyValue(ChatContextKeys.hasUsedCreateSlashCommands.key); - assert.strictEqual(value, true, 'Context key should be true after /create-instruction is used'); + assert.strictEqual(value, true, 'Context key should be true after /create-instructions is used'); assert.strictEqual( storageService.getBoolean('chat.tips.usedCreateSlashCommands', StorageScope.APPLICATION, false), true, diff --git a/test/smoke/src/areas/accessibility/accessibility.test.ts b/test/smoke/src/areas/accessibility/accessibility.test.ts index ac3868eb55b..ad16a299c01 100644 --- a/test/smoke/src/areas/accessibility/accessibility.test.ts +++ b/test/smoke/src/areas/accessibility/accessibility.test.ts @@ -34,7 +34,7 @@ export function setup(logger: Logger, opts: { web?: boolean }, quality: Quality) selector: '.monaco-workbench', excludeRules: { // Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect - 'link-in-text-block': ['command:workbench.action.chat.generateInstructions'], + 'link-in-text-block': ['command:workbench.action.chat.generateAgentInstructions'], // Monaco lists use aria-multiselectable on role="list" and aria-setsize/aria-posinset/aria-selected on role="dialog" rows // These violations appear intermittently when notification lists or other dynamic lists are visible // Note: patterns match against HTML string, not CSS selectors, so no leading dots @@ -85,7 +85,7 @@ export function setup(logger: Logger, opts: { web?: boolean }, quality: Quality) selector: 'div[id="workbench.panel.chat"]', excludeRules: { // Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect - 'link-in-text-block': ['command:workbench.action.chat.generateInstructions'] + 'link-in-text-block': ['command:workbench.action.chat.generateAgentInstructions'] } }); }); @@ -117,7 +117,7 @@ export function setup(logger: Logger, opts: { web?: boolean }, quality: Quality) selector: 'div[id="workbench.panel.chat"]', excludeRules: { // Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect - 'link-in-text-block': ['command:workbench.action.chat.generateInstructions'], + 'link-in-text-block': ['command:workbench.action.chat.generateAgentInstructions'], // Monaco lists use aria-multiselectable on role="list" and aria-selected on role="listitem" // These are used intentionally for selection semantics even though technically not spec-compliant 'aria-allowed-attr': ['monaco-list', 'monaco-list-row'], @@ -157,7 +157,7 @@ export function setup(logger: Logger, opts: { web?: boolean }, quality: Quality) selector: 'div[id="workbench.panel.chat"]', excludeRules: { // Links in chat welcome view show underline on hover/focus which axe-core static analysis cannot detect - 'link-in-text-block': ['command:workbench.action.chat.generateInstructions'], + 'link-in-text-block': ['command:workbench.action.chat.generateAgentInstructions'], // Monaco lists use aria-multiselectable on role="list" and aria-selected on role="listitem" // These are used intentionally for selection semantics even though technically not spec-compliant 'aria-allowed-attr': ['monaco-list', 'monaco-list-row'],