Skip to content

Commit 34294b4

Browse files
authored
Minor claude code cleanups (#1180)
1 parent 857a249 commit 34294b4

File tree

6 files changed

+69
-45
lines changed

6 files changed

+69
-45
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1775,7 +1775,7 @@
17751775
"commands": [
17761776
{
17771777
"command": "github.copilot.claude.sessions.refresh",
1778-
"title": "Refresh Claude Code Sessions",
1778+
"title": "%github.copilot.command.refreshClaudeCodeSessions%",
17791779
"icon": "$(refresh)",
17801780
"category": "Claude Code"
17811781
},

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@
199199
"github.copilot.command.openWalkthrough": "Open Walkthrough",
200200
"github.copilot.walkthrough.title": "GitHub Copilot",
201201
"github.copilot.walkthrough.description": "Your AI pair programmer to write code faster and smarter",
202+
"github.copilot.command.refreshClaudeCodeSessions": "Refresh Claude Code Sessions",
202203
"github.copilot.walkthrough.signIn.title": "Sign in with GitHub",
203204
"github.copilot.walkthrough.signIn.description": "To get started with Copilot, sign in with your GitHub account.\nMake sure you're using the correct GitHub account. You can also sign in later using the account menu.\n\n[Sign In](command:github.copilot.signIn)",
204205
"github.copilot.walkthrough.signIn.media.altText": "Sign in to GitHub via this walkthrough or VS Code's account menu",

src/extension/agents/claude/node/claudeCodeSessionService.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { createServiceIdentifier } from '../../../../util/common/services';
1515
import { ResourceMap, ResourceSet } from '../../../../util/vs/base/common/map';
1616
import { isEqualOrParent } from '../../../../util/vs/base/common/resources';
1717
import { URI } from '../../../../util/vs/base/common/uri';
18+
import { CancellationError } from '../../../../util/vs/base/common/errors';
1819

1920
type RawStoredSDKMessage = SDKMessage & {
2021
readonly parentUuid: string | null;
@@ -294,6 +295,10 @@ export class ClaudeCodeSessionService implements IClaudeCodeSessionService {
294295
try {
295296
// Read and parse the JSONL file
296297
const content = await this._fileSystem.readFile(fileUri);
298+
if (token.isCancellationRequested) {
299+
throw new CancellationError();
300+
}
301+
297302
const text = Buffer.from(content).toString('utf8');
298303

299304
// Parse JSONL content line by line

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

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import * as vscode from 'vscode';
77
import { Disposable } from '../../../util/vs/base/common/lifecycle';
8-
import { localize } from '../../../util/vs/nls';
98
import { SyncDescriptor } from '../../../util/vs/platform/instantiation/common/descriptors';
109
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
1110
import { ServiceCollection } from '../../../util/vs/platform/instantiation/common/serviceCollection';
@@ -16,6 +15,7 @@ import { ILanguageModelServer, LanguageModelServer } from '../../agents/node/lan
1615
import { IExtensionContribution } from '../../common/contributions';
1716
import { ClaudeChatSessionContentProvider } from './claudeChatSessionContentProvider';
1817
import { ClaudeChatSessionItemProvider } from './claudeChatSessionItemProvider';
18+
import { ClaudeChatSessionParticipant } from './claudeChatSessionParticipant';
1919

2020
export class ChatSessionsContrib extends Disposable implements IExtensionContribution {
2121
readonly id = 'chatSessions';
@@ -40,36 +40,8 @@ export class ChatSessionsContrib extends Disposable implements IExtensionContrib
4040

4141
const claudeAgentManager = this._register(claudeAgentInstaService.createInstance(ClaudeAgentManager));
4242
const chatSessionContentProvider = claudeAgentInstaService.createInstance(ClaudeChatSessionContentProvider);
43-
const chatParticipant = vscode.chat.createChatParticipant(this.sessionType, async (request, context, stream, token) => {
44-
const create = async () => {
45-
const { claudeSessionId } = await claudeAgentManager.handleRequest(undefined, request, context, stream, token);
46-
if (!claudeSessionId) {
47-
stream.warning(localize('claude.failedToCreateSession', "Failed to create a new Claude Code session."));
48-
return;
49-
}
50-
return claudeSessionId;
51-
};
52-
const { chatSessionContext } = context;
53-
if (chatSessionContext) {
54-
if (chatSessionContext.isUntitled) {
55-
/* New, empty session */
56-
const claudeSessionId = await create();
57-
if (claudeSessionId) {
58-
// Tell UI to replace with claude-backed session
59-
sessionItemProvider.swap(chatSessionContext.chatSessionItem, { id: claudeSessionId, label: request.prompt ?? 'Claude Code' });
60-
}
61-
return {};
62-
}
63-
/* Existing session */
64-
const { id } = chatSessionContext.chatSessionItem;
65-
await claudeAgentManager.handleRequest(id, request, context, stream, token);
66-
} else {
67-
/* Via @claude */
68-
// TODO: Think about how this should work
69-
stream.markdown(localize('claude.viaAtClaude', "Start a new Claude Code session"));
70-
stream.button({ command: `workbench.action.chat.openNewSessionEditor.${this.sessionType}`, title: localize('claude.startNewSession', "Start Session") });
71-
}
72-
});
43+
const claudeChatSessionParticipant = claudeAgentInstaService.createInstance(ClaudeChatSessionParticipant, this.sessionType, claudeAgentManager, sessionItemProvider);
44+
const chatParticipant = vscode.chat.createChatParticipant(this.sessionType, claudeChatSessionParticipant.createHandler());
7345
this._register(vscode.chat.registerChatSessionContentProvider(this.sessionType, chatSessionContentProvider, chatParticipant));
7446
}
7547
}

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

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

66
import * as vscode from 'vscode';
7-
import { Emitter } from '../../../util/vs/base/common/event';
7+
import { Emitter, Event } from '../../../util/vs/base/common/event';
88
import { Disposable } from '../../../util/vs/base/common/lifecycle';
99
import { IClaudeCodeSessionService } from '../../agents/claude/node/claudeCodeSessionService';
1010

@@ -14,9 +14,10 @@ import { IClaudeCodeSessionService } from '../../agents/claude/node/claudeCodeSe
1414
*/
1515
export class ClaudeChatSessionItemProvider extends Disposable implements vscode.ChatSessionItemProvider {
1616
private readonly _onDidChangeChatSessionItems = this._register(new Emitter<void>());
17+
public readonly onDidChangeChatSessionItems: Event<void> = this._onDidChangeChatSessionItems.event;
18+
1719
private readonly _onDidCommitChatSessionItem = this._register(new Emitter<{ original: vscode.ChatSessionItem; modified: vscode.ChatSessionItem }>());
18-
public readonly onDidChangeChatSessionItems = this._onDidChangeChatSessionItems.event;
19-
public readonly onDidCommitChatSessionItem = this._onDidCommitChatSessionItem.event;
20+
public readonly onDidCommitChatSessionItem: Event<{ original: vscode.ChatSessionItem; modified: vscode.ChatSessionItem }> = this._onDidCommitChatSessionItem.event;
2021

2122
constructor(
2223
@IClaudeCodeSessionService private readonly claudeCodeSessionService: IClaudeCodeSessionService
@@ -34,15 +35,6 @@ export class ClaudeChatSessionItemProvider extends Disposable implements vscode.
3435

3536
public async provideChatSessionItems(token: vscode.CancellationToken): Promise<vscode.ChatSessionItem[]> {
3637
const sessions = await this.claudeCodeSessionService.getAllSessions(token);
37-
// const newSessions: vscode.ChatSessionItem[] = Array.from(this.sessionStore.getUnresolvedSessions().values()).map(session => ({
38-
// id: session.id,
39-
// label: session.label,
40-
// timing: {
41-
// startTime: Date.now()
42-
// },
43-
// iconPath: new vscode.ThemeIcon('star-add')
44-
// }));
45-
4638
const diskSessions = sessions.map(session => ({
4739
id: session.id,
4840
label: session.label,
@@ -53,7 +45,6 @@ export class ClaudeChatSessionItemProvider extends Disposable implements vscode.
5345
iconPath: new vscode.ThemeIcon('star-add')
5446
} satisfies vscode.ChatSessionItem));
5547

56-
// return [...newSessions, ...diskSessions];
5748
return diskSessions;
5849
}
5950
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*---------------------------------------------------------------------------------------------
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 * as vscode from 'vscode';
7+
import { ChatExtendedRequestHandler } from 'vscode';
8+
import { localize } from '../../../util/vs/nls';
9+
import { ClaudeAgentManager } from '../../agents/claude/node/claudeCodeAgent';
10+
import { ClaudeChatSessionItemProvider } from './claudeChatSessionItemProvider';
11+
12+
export class ClaudeChatSessionParticipant {
13+
constructor(
14+
private readonly sessionType: string,
15+
private readonly claudeAgentManager: ClaudeAgentManager,
16+
private readonly sessionItemProvider: ClaudeChatSessionItemProvider,
17+
) { }
18+
19+
createHandler(): ChatExtendedRequestHandler {
20+
return this.handleRequest.bind(this);
21+
}
22+
23+
private async handleRequest(request: vscode.ChatRequest, context: vscode.ChatContext, stream: vscode.ChatResponseStream, token: vscode.CancellationToken): Promise<vscode.ChatResult | void> {
24+
const create = async () => {
25+
const { claudeSessionId } = await this.claudeAgentManager.handleRequest(undefined, request, context, stream, token);
26+
if (!claudeSessionId) {
27+
stream.warning(localize('claude.failedToCreateSession', "Failed to create a new Claude Code session."));
28+
return undefined;
29+
}
30+
return claudeSessionId;
31+
};
32+
const { chatSessionContext } = context;
33+
if (chatSessionContext) {
34+
if (chatSessionContext.isUntitled) {
35+
/* New, empty session */
36+
const claudeSessionId = await create();
37+
if (claudeSessionId) {
38+
// Tell UI to replace with claude-backed session
39+
this.sessionItemProvider.swap(chatSessionContext.chatSessionItem, { id: claudeSessionId, label: request.prompt ?? 'Claude Code' });
40+
}
41+
return {};
42+
}
43+
44+
/* Existing session */
45+
const { id } = chatSessionContext.chatSessionItem;
46+
await this.claudeAgentManager.handleRequest(id, request, context, stream, token);
47+
return {};
48+
}
49+
/* Via @claude */
50+
// TODO: Think about how this should work
51+
stream.markdown(localize('claude.viaAtClaude', "Start a new Claude Code session"));
52+
stream.button({ command: `workbench.action.chat.openNewSessionEditor.${this.sessionType}`, title: localize('claude.startNewSession', "Start Session") });
53+
return {};
54+
}
55+
}

0 commit comments

Comments
 (0)