commit 1caa48735956fb322c13064c70615bbaef3cc265 Author: MirSobZ Date: Fri Apr 10 15:35:46 2026 +0200 Chat Eksporter diff --git a/.ai_logs/chat-2026-04-10.md b/.ai_logs/chat-2026-04-10.md new file mode 100644 index 0000000..fc5faf7 --- /dev/null +++ b/.ai_logs/chat-2026-04-10.md @@ -0,0 +1,6 @@ + + +--- +### [4/10/2026, 3:25:48 PM] + +3 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f9c34d9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "chat.tools.terminal.autoApprove": { + "npm install": true, + "vsce": true, + "command": true + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..6c57ef7 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,15 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "AI Chat Logger: Generuj VSIX", + "type": "shell", + "command": "./build.sh", + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore new file mode 100644 index 0000000..1050516 --- /dev/null +++ b/.vscodeignore @@ -0,0 +1,7 @@ +.vscode/** +.ai_logs/** +build.sh +node_modules/** +*.vsix +.git/** +.gitignore diff --git a/README.md b/README.md new file mode 100644 index 0000000..25ce2d0 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# AI Chat Logger + +Minimalistyczny plugin zapisujący historię czatu Copilot Chat do plików Markdown. + +## Instalacja + +1. Skopiuj folder `ai-chat-logger` do dowolnego katalogu. +2. W VS Code uruchom: + - `F1 → Developer: Install Extension from Location` +3. Wskaż folder pluginu. + +## Konfiguracja + +W `settings.json`: + +```json +{ + "aiChatLogger.outputDir": ".ai_logs" +} +# ai-chat-logger diff --git a/ai-chat-logger-1.0.3.vsix b/ai-chat-logger-1.0.3.vsix new file mode 100644 index 0000000..51cc249 Binary files /dev/null and b/ai-chat-logger-1.0.3.vsix differ diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..6b1b84b --- /dev/null +++ b/build.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# Skrypt do budowania rozszerzenia .vsix + +# Sprawdź czy vsce jest zainstalowane +if ! command -v vsce &> /dev/null +then + echo "vsce nie jest zainstalowane. Instalowanie globalnie..." + npm install -g @vscode/vsce +fi + +echo "Budowanie rozszerzenia..." +vsce package --no-git-tag-version --allow-missing-repository --skip-license --allow-star-activation diff --git a/extension.js b/extension.js new file mode 100644 index 0000000..f35ca43 --- /dev/null +++ b/extension.js @@ -0,0 +1,155 @@ +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 }; diff --git a/package.json b/package.json new file mode 100644 index 0000000..130a9f0 --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "ai-chat-logger", + "displayName": "AI Chat Logger", + "description": "Automatyczne zapisywanie historii czatu Copilot Chat do pliku.", + "version": "1.0.3", + "publisher": "local", + "engines": { + "vscode": "^1.80.0" + }, + "activationEvents": [], + "main": "./extension.js", + "contributes": { + "commands": [ + { + "command": "ai-chat-logger.saveChat", + "title": "AI Chat Logger: Zapisz Chat" + } + ], + "configuration": { + "type": "object", + "title": "AI Chat Logger", + "properties": { + "aiChatLogger.outputDir": { + "type": "string", + "default": ".ai_logs", + "description": "Folder, w którym będą zapisywane logi czatu." + }, + "aiChatLogger.format": { + "type": "string", + "enum": ["markdown", "plaintext"], + "default": "markdown", + "description": "Format zapisu logów czatu." + } + } + } + }, + "categories": ["Other"] +}