2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { CancellationToken } from '../../../../base/common/cancellation.js';
7
>
import { AgentSession } from '../../common/agentService.js';
8
>
import { CompletionItem, CompletionItemKind, CompletionsParams } from '../../common/state/protocol/commands.js';
9
>
import { Customization, CustomizationType, DirectoryCustomization, MessageAttachmentKind, PluginCustomization, SkillCustomization } from '../../common/state/protocol/state.js';
10
>
import { getCompletionAction, toCommandCompletionAttachmentMeta } from '../../common/meta/agentCompletionAttachmentMeta.js';
11
>
import { getCopilotConfigSlashCommandItems, ICopilotConfigSlashCommandState, isCopilotConfigSlashCommand } from '../../common/copilotConfigSlashCommands.js';
12
>
import { CompletionTriggerCharacter, IAgentHostCompletionItemProvider } from '../agentHostCompletions.js';
13
>
import { extractLeadingSlashToken, extractWhitespaceDelimitedSlashToken, matchesSlashCompletion } from '../agentHostSlashCompletion.js';
14
>
import { SYNCED_CUSTOMIZATION_SCHEME } from '../../common/agentHostFileSystemService.js';
15
>
import type { CopilotSession } from '@github/copilot-sdk';
16
>
17
>
export { parseLeadingSlashCommand } from '../../common/agentHostSlashCommand.js';
18
>
19
>
const HIDDEN_RUNTIME_COMMANDS = new Set<string>(['agent', 'app', 'changelog', 'context', 'copy', 'exit', 'extensions', 'feedback', 'help', 'ide', 'instructions', 'login', 'logout', 'mcp', 'model', 'new', 'plugin', 'rename', 'restart', 'resume', 'sandbox', 'session', 'settings', 'skills', 'statusline', 'streamer-mode', 'subagents', 'tasks', 'terminal-setup', 'theme', 'undo', 'update', 'user', 'voice', 'worktree', 'autopilot', 'yolo', 'cd', 'cwd', 'after', 'before', 'add-dir', 'allow-all', 'list-dirs', 'reset-allowed-tools']);
20
>
21
>
export const DEFAULT_RUNTIME_SLASH_COMMAND_COMPLETION_WAIT_MS = 300;
22
>
23
>
/**
24
>
* Lookup hooks used by {@link CopilotSlashCommandCompletionProvider} to
25
>
* retrieve runtime slash command metadata and apply feature gating.
26
>
*/
27
>
export interface ICopilotSlashCommandSessionInfo {
28
>
/**
29
>
* Whether the experimental rubber duck critic subagent is enabled via
30
>
* the agent host config. When provided and `false`, `/rubber-duck` is hidden.
31
>
*/
32
>
isRubberDuckEnabled?(): boolean;
33
>
/** Runtime slash commands discovered from the SDK session. */
34
>
getRuntimeSlashCommands?(sessionId: string, options?: ICopilotRuntimeSlashCommandQueryOptions): Promise<readonly ICopilotRuntimeSlashCommandInfo[]>;
35
>
getSessionCustomizations: (session: string) => Promise<readonly Customization[]>;
36
>
/**
37
>
* The session's current config state (`mode` / `autoApprove` axes), used to
38
>
* filter config-action slash command completions so only the state-changing
39
>
* forms are offered. When omitted, all forms are offered.
40
>
*/
41
>
getSessionConfigState?(sessionId: string): ICopilotConfigSlashCommandState | undefined;
42
>
}
43
>
44
>
export interface ICopilotRuntimeSlashCommandQueryOptions {
45
>
readonly maxWaitMs?: number;
46
>
}
47
>
48
>
/**
49
>
* Completion provider for Copilot CLI slash commands. Only fires for
50
>
* sessions whose URI scheme is `copilotcli` and only when the input begins
51
>
* with `/`.
52
>
*
53
>
* The returned items carry a {@link MessageAttachmentKind.Simple}
54
>
* attachment, which the workbench bridge maps into command/skill completion
55
>
* attachments. Runtime command dispatch is text-side in `CopilotAgentSession.send`;
56
>
* client-side config commands also share the same leading slash parser.
57
>
*/
58
>
export class CopilotSlashCommandCompletionProvider implements IAgentHostCompletionItemProvider {
59
>
readonly kinds: ReadonlySet<CompletionItemKind> = new Set([CompletionItemKind.UserMessage]);
60
>
readonly triggerCharacters = [CompletionTriggerCharacter.Slash] as const;
61
>
62
>
constructor(
63
private readonly copilotcliId: string,
64
private readonly _sessionInfo: ICopilotSlashCommandSessionInfo,
65
private readonly _runtimeSlashCommandCompletionWaitMs: number = DEFAULT_RUNTIME_SLASH_COMMAND_COMPLETION_WAIT_MS,
66
) { }
68
>
async provideCompletionItems(params: CompletionsParams, _token: CancellationToken): Promise<readonly CompletionItem[]> {
69
if (AgentSession.provider(params.channel) !== this.copilotcliId) {
70
return [];