Skip to content

Commit e82cc9c

Browse files
Misc feedback from slash command handling (microsoft#3006)
* Misc feedback from slash command handling Addresses some CCR feedback in microsoft#2994 * change the regex
1 parent df1a569 commit e82cc9c

File tree

2 files changed

+18
-20
lines changed

2 files changed

+18
-20
lines changed

src/extension/agents/claude/vscode-node/claudeSlashCommandService.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as vscode from 'vscode';
7-
import { CancellationToken } from 'vscode';
7+
import { ILogService } from '../../../../platform/log/common/logService';
8+
import { CancellationToken } from '../../../../util/vs/base/common/cancellation';
9+
import { Disposable } from '../../../../util/vs/base/common/lifecycle';
810
import { createDecorator, IInstantiationService } from '../../../../util/vs/platform/instantiation/common/instantiation';
911
import { getClaudeSlashCommandRegistry, IClaudeSlashCommandHandler } from './slashCommands/claudeSlashCommandRegistry';
1012

@@ -41,16 +43,17 @@ export interface IClaudeSlashCommandService {
4143

4244
export const IClaudeSlashCommandService = createDecorator<IClaudeSlashCommandService>('claudeSlashCommandService');
4345

44-
export class ClaudeSlashCommandService implements IClaudeSlashCommandService {
46+
export class ClaudeSlashCommandService extends Disposable implements IClaudeSlashCommandService {
4547
readonly _serviceBrand: undefined;
4648

4749
private _handlerCache = new Map<string, IClaudeSlashCommandHandler>();
48-
private _commandDisposables: vscode.Disposable[] = [];
4950
private _initialized = false;
5051

5152
constructor(
5253
@IInstantiationService private readonly instantiationService: IInstantiationService,
54+
@ILogService private readonly logService: ILogService,
5355
) {
56+
super();
5457
// Initialize eagerly to register VS Code commands at startup
5558
this._ensureInitialized();
5659
}
@@ -95,28 +98,23 @@ export class ClaudeSlashCommandService implements IClaudeSlashCommandService {
9598
const ctors = getClaudeSlashCommandRegistry();
9699
for (const ctor of ctors) {
97100
const handler = this.instantiationService.createInstance(ctor);
98-
this._handlerCache.set(handler.commandName.toLowerCase(), handler);
101+
const commandKey = handler.commandName.toLowerCase();
102+
// This shouldn't happen unless we accidentally register duplicates
103+
if (this._handlerCache.has(commandKey)) {
104+
this.logService.warn(`Duplicate Claude slash command name "${handler.commandName}" detected. Ignoring handler ${ctor.name || 'unknown constructor'}.`);
105+
continue;
106+
}
107+
this._handlerCache.set(commandKey, handler);
99108

100109
// Register VS Code command if commandId is provided
101110
if (handler.commandId) {
102-
const disposable = vscode.commands.registerCommand(handler.commandId, () => {
103-
// Invoke with no args, no stream (Command Palette mode), and a cancellation token
104-
const tokenSource = new vscode.CancellationTokenSource();
105-
handler.handle('', undefined, tokenSource.token).catch(err => {
106-
vscode.window.showErrorMessage(`Command failed: ${err.message || err}`);
107-
});
108-
});
109-
this._commandDisposables.push(disposable);
111+
this._register(vscode.commands.registerCommand(handler.commandId, () => {
112+
// Invoke with no args and no stream (Command Palette mode)
113+
return handler.handle('', undefined, CancellationToken.None);
114+
}));
110115
}
111116
}
112117

113118
this._initialized = true;
114119
}
115-
116-
dispose(): void {
117-
for (const disposable of this._commandDisposables) {
118-
disposable.dispose();
119-
}
120-
this._commandDisposables = [];
121-
}
122120
}

src/extension/chatSessions/vscode-node/chatSessions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ export class ChatSessionsContrib extends Disposable implements IExtensionContrib
8989

9090
const claudeAgentManager = this._register(claudeAgentInstaService.createInstance(ClaudeAgentManager));
9191
const chatSessionContentProvider = this._register(claudeAgentInstaService.createInstance(ClaudeChatSessionContentProvider));
92-
const slashCommandService = claudeAgentInstaService.createInstance(ClaudeSlashCommandService);
92+
const slashCommandService = this._register(claudeAgentInstaService.createInstance(ClaudeSlashCommandService));
9393
const claudeChatSessionParticipant = new ClaudeChatSessionParticipant(ClaudeChatSessionItemProvider.claudeSessionType, claudeAgentManager, sessionItemProvider, chatSessionContentProvider, slashCommandService);
9494
const chatParticipant = vscode.chat.createChatParticipant(ClaudeChatSessionItemProvider.claudeSessionType, claudeChatSessionParticipant.createHandler());
9595
this._register(vscode.chat.registerChatSessionContentProvider(ClaudeChatSessionItemProvider.claudeSessionType, chatSessionContentProvider, chatParticipant));

0 commit comments

Comments
 (0)