Files
ai-chat-logger/extension.js
2026-04-10 15:35:46 +02:00

156 lines
6.1 KiB
JavaScript

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 };