const vscode = require("vscode"); const path = require("path"); function activate(context) { const config = vscode.workspace.getConfiguration("aiChatLogger"); const outputDir = config.get("outputDir") || ".ai_logs"; const logFormat = config.get("format") || "markdown"; const workspaceFolder = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0] : null; if (!workspaceFolder) { console.log("AI Chat Logger: brak workspace — plugin nie działa."); return; } const workspaceRoot = workspaceFolder.uri; const fullOutputDir = vscode.Uri.joinPath(workspaceRoot, outputDir); // Inicjalizacja folderu logów vscode.workspace.fs.createDirectory(fullOutputDir); // Rejestracja komendy ręcznego zapisu let disposable = vscode.commands.registerCommand('ai-chat-logger.saveChat', async () => { // Log all document schemes to debug const allDocs = vscode.workspace.textDocuments; const schemes = [...new Set(allDocs.map(d => d.uri.scheme))]; console.log("All open documents:", allDocs.map(d => `${d.uri.scheme}:${d.uri.path}`)); // 1. Proba pobrania tekstu ze schowka (najskuteczniejsza metoda dla nowoczesnego Copilota) try { // Próbujemy skopiować całą treść czatu do schowka await vscode.commands.executeCommand('workbench.action.chat.copyAll'); const clipboardText = await vscode.env.clipboard.readText(); if (clipboardText && clipboardText.trim()) { await saveToFile(clipboardText, "clipboard-chat"); vscode.window.showInformationMessage("Czat zapisany pomyślnie na podstawie zawartości okna."); return; } } catch (err) { console.log("Metoda copyAll nie powiodła się, próbuję metodę dokumentową..."); } // 2. Metoda dokumentowa dla starszych wersji lub specyficznych widoków const chatDocs = vscode.workspace.textDocuments.filter(doc => doc.uri.scheme === "vscode-chat" || doc.uri.scheme === "vscode-chat-result" || doc.uri.scheme === "chat-session-history" || doc.uri.scheme === "comment" || doc.uri.scheme === "vscode-chat-editor" || doc.uri.scheme === "chat-editing-text-model" || doc.uri.scheme === "chat-editing-snapshot-text-model"); if (chatDocs.length === 0) { vscode.window.showErrorMessage(`Nie znaleziono otwartej sesji czatu AI w pamięci ani w schowku. (Dostępne schematy: ${schemes.join(", ")})`); return; } // Jeśli jest więcej niż jeden czat, spróbujmy wybrać najnowszy lub połączyć let chosenDoc = chatDocs[0]; if (chatDocs.length > 1) { const items = chatDocs.map(d => ({ label: `Czat: ${d.uri.path} (${d.uri.scheme})`, doc: d })); const selection = await vscode.window.showQuickPick(items, { placeHolder: "Wybierz sesję czatu do zapisu" }); if (!selection) return; chosenDoc = selection.doc; } const content = chosenDoc.getText(); if (!content.trim()) { vscode.window.showWarningMessage("Czat jest pusty."); return; } await saveToFile(content, "manual-chat"); }); context.subscriptions.push(disposable); // Rejestracja zdarzenia zmiany dokumentu dla automatycznego logowania const documentChangeDisposable = vscode.workspace.onDidChangeTextDocument(async event => { const doc = event.document; // Lista obsługiwanych schematów chatu const chatSchemes = ["vscode-chat", "vscode-chat-result", "chat-session-history", "chat-editing-text-model"]; if (!chatSchemes.includes(doc.uri.scheme)) return; // Optymalizacja: zapisujemy tylko nowe zmiany (contentChanges) if (event.contentChanges.length === 0) return; const date = new Date().toISOString().slice(0, 10); const extension = logFormat === "markdown" ? "md" : "txt"; const fileName = `chat-${date}.${extension}`; const fileUri = vscode.Uri.joinPath(fullOutputDir, fileName); let newText = event.contentChanges .map(change => change.text) .join(""); if (!newText.trim()) return; const timestamp = new Date().toLocaleString(); let entryText = ""; if (logFormat === "markdown") { entryText = `\n\n---\n### [${timestamp}]\n\n${newText}\n`; } else { entryText = `\n\n---\n[${timestamp}]\n\n${newText}\n`; } const entry = Buffer.from(entryText); try { let existingContent = Buffer.from(""); try { existingContent = await vscode.workspace.fs.readFile(fileUri); } catch (e) { // Plik może nie istnieć, to normalne przy pierwszym wpisie dnia } const combinedContent = Buffer.concat([existingContent, entry]); await vscode.workspace.fs.writeFile(fileUri, combinedContent); } catch (err) { console.error("AI Chat Logger error:", err); } }); context.subscriptions.push(documentChangeDisposable); // Pomocnicza funkcja do zapisu (manualnego) async function saveToFile(content, prefix) { const date = new Date().toISOString().slice(0, 10); const time = new Date().toTimeString().slice(0, 8).replace(/:/g, "-"); const extension = logFormat === "markdown" ? "md" : "txt"; const fileName = `${prefix}-${date}-${time}.${extension}`; const fileUri = vscode.Uri.joinPath(fullOutputDir, fileName); const entry = Buffer.from(content); try { await vscode.workspace.fs.writeFile(fileUri, entry); vscode.window.showInformationMessage(`Czat zapisany w: ${outputDir}/${fileName}`); } catch (err) { vscode.window.showErrorMessage(`Błąd zapisu: ${err.message}`); } } console.log("AI Chat Logger aktywny."); } function deactivate() {} module.exports = { activate, deactivate };