copilotSlashCommandCompletionProvider.ts ×6

Frontier kind: Code frontier

unlabeled · c_4a0827362006

226 tests · 21590 LOC · 81 files · introduces 0 tests · 74 LOC · 1 file

Introduces — evidence that enters the hierarchy at this concept

Code
6 ranges74 lines · 1 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1799 ranges21590 lines · 81 files · Browse complete extent
All tests (intent)
226 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

1 file ranked by introduced lines: 74 introduced LOC across 6 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/node/copilot/copilotSlashCommandCompletionProvider.ts 74 introduced LOC · 6 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- copilotSlashCommandCompletionProvider.ts
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 [];
84 return await this._getRuntimeSlashCommandCompletionInfo(sessionId, typed, leading, returnJustSkills);
85 }
87 > private async _getKnownSkills(sessionId: string) {
88 const knownCommands = new Set<string>();
89 const customizations = await this._sessionInfo.getSessionCustomizations(sessionId) ?? [];
100 return knownCommands;
101 }
103 > private _toSlashCommandCandidate(container: PluginCustomization | DirectoryCustomization, skill: SkillCustomization): string {
104 // see getCanonicalPluginCommandId
105 let slashCommandName = skill.name;
109 return slashCommandName;
110 }
112 > private async _getRuntimeSlashCommandCompletionInfo(sessionId: string, typed: string, { rangeStart, rangeEnd }: { rangeStart: number; rangeEnd: number }, returnJustSkills: boolean): Promise<CompletionItem[]> {
113 const [runtimeCommands, knownSkills] = await Promise.all([
114 this._sessionInfo.getRuntimeSlashCommands?.(sessionId, { maxWaitMs: this._runtimeSlashCommandCompletionWaitMs }) ?? [],
222 return completionItems.sort((a, b) => getSortText(a).localeCompare(getSortText(b)));
223 }
225 >
226 > export type ICopilotRuntimeSlashCommandInfo = Awaited<ReturnType<CopilotSession['rpc']['commands']['list']>>['commands'][number];
227 >
228 function isSyncedCustomization(container: PluginCustomization): boolean {
229 return container.uri.startsWith(SYNCED_CUSTOMIZATION_SCHEME + ':');