refactor(vscode-ide-companion): migrate session save to CLI /chat save command

- Replace manual checkpoint file writing with CLI's native /chat save command
- Add saveCheckpointViaCommand method to use CLI's built-in save functionality
- Deprecate saveSessionViaAcp as CLI doesn't support session/save ACP method
- Update saveCheckpoint to delegate to CLI command for complete context preservation
- Enhanced error logging in acpSessionManager session load
- Mark saveSessionViaAcp as deprecated with fallback to command-based save
- Fix ESLint errors: remove unused imports and catch variables, wrap case block declarations

This ensures checkpoints are saved with complete session context including tool calls,
leveraging CLI's native save functionality instead of manual file operations.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yiliang114
2025-11-24 01:00:31 +08:00
parent 4dfbdcddca
commit b7f9acf0ff
22 changed files with 1380 additions and 568 deletions

View File

@@ -580,10 +580,29 @@ export const App: React.FC = () => {
// Handle removing context attachment
const handleToolCallUpdate = React.useCallback(
(update: ToolCallUpdate) => {
console.log('[App] handleToolCallUpdate:', {
type: update.type,
toolCallId: update.toolCallId,
kind: update.kind,
title: update.title,
status: update.status,
});
setToolCalls((prevToolCalls) => {
const newMap = new Map(prevToolCalls);
const existing = newMap.get(update.toolCallId);
console.log(
'[App] existing tool call:',
existing
? {
kind: existing.kind,
title: existing.title,
status: existing.status,
}
: 'not found',
);
// Helper function to safely convert title to string
const safeTitle = (title: unknown): string => {
if (typeof title === 'string') {
@@ -627,13 +646,17 @@ export const App: React.FC = () => {
: undefined;
if (existing) {
// Update existing tool call
// Update existing tool call - merge content arrays
const mergedContent = updatedContent
? [...(existing.content || []), ...updatedContent]
: existing.content;
newMap.set(update.toolCallId, {
...existing,
...(update.kind && { kind: update.kind }),
...(update.title && { title: safeTitle(update.title) }),
...(update.status && { status: update.status }),
...(updatedContent && { content: updatedContent }),
content: mergedContent,
...(update.locations && { locations: update.locations }),
});
} else {
@@ -641,7 +664,7 @@ export const App: React.FC = () => {
newMap.set(update.toolCallId, {
toolCallId: update.toolCallId,
kind: update.kind || 'other',
title: safeTitle(update.title),
title: update.title ? safeTitle(update.title) : '',
status: update.status || 'pending',
rawInput: update.rawInput as string | object | undefined,
content: updatedContent,
@@ -840,11 +863,16 @@ export const App: React.FC = () => {
break;
case 'toolCall':
case 'toolCallUpdate':
case 'toolCallUpdate': {
// Handle tool call updates
handleToolCallUpdate(message.data);
// Convert sessionUpdate to type if needed
const toolCallData = message.data;
if (toolCallData.sessionUpdate && !toolCallData.type) {
toolCallData.type = toolCallData.sessionUpdate;
}
handleToolCallUpdate(toolCallData);
break;
}
case 'qwenSessionList': {
const sessions = message.data.sessions || [];
setQwenSessions(sessions);