diff --git a/README.md b/README.md index 37e3350..3b4724d 100644 --- a/README.md +++ b/README.md @@ -1,79 +1 @@ -# auto-git-gui - -**Author:** Unknown - -> ⚠️ **This README.md has been automatically generated using AI and might contain hallucinations or inaccuracies. Please proceed with caution!** - -# Repo Monitor - -## Description - -Repo Monitor is a desktop application designed to help developers keep track of their Git repositories. It provides features such as monitoring repository activity, taking snapshots of commits, and managing multiple repositories efficiently. - -## Features - -- **Repository Monitoring**: Automatically monitors selected Git repositories for changes. -- **Snapshot Commits**: Save the state of a commit to a file for later reference. -- **Checkout Commits**: Switch between different commits in your repository. -- **Commit Diff Viewer**: View differences between commits directly within the application. -- **Multiple Repositories**: Manage and switch between multiple Git repositories easily. -- **Tray Integration**: Access quick actions via system tray menu. -- **Cat Assistant**: An interactive cat assistant that provides feedback based on commit activity. - -## Installation - -1. Download the latest release from the [Releases](https://github.com/yourusername/repo-monitor/releases) page. -2. Extract the downloaded archive. -3. Run the application executable (`RepoMonitor.exe` for Windows, `RepoMonitor.app` for macOS, or `RepoMonitor` for Linux). - -## Usage - -1. **Add a Repository**: Click the "Add Folder" button to add a Git repository to be monitored. -2. **Select a Repository**: Click on a repository in the sidebar to view its commits. -3. **View Commits**: Navigate through commits using pagination and view commit details, including diffs. -4. **Take Snapshots**: Use the snapshot button to save the state of a specific commit. -5. **Checkout Commits**: Switch to a different commit by clicking the checkout button. - -## Contributing - -Contributions are welcome! Please read the [CONTRIBUTING.md](CONTRIBUTING.md) file for guidelines on how to contribute to the project. - -## License - -This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. - -## Contact - -For any questions or support, please contact us at [support@repomonitor.com](mailto:support@repomonitor.com). - ---- - -**Repo Monitor** -*Effortlessly manage your Git repositories.* - - - ---- - - -MIT License - -Copyright (c) 2023 Your Name - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +# Projekt in auto-git-gui diff --git a/animeCat.js b/animeCat.js index af6eaa5..18a6994 100644 --- a/animeCat.js +++ b/animeCat.js @@ -13,7 +13,7 @@ window.AnimeCat = class AnimeCat { joy: 'joy.png', mischievous: 'mischievous.png' }, options.images); - + this.blinkMin = options.blinkMin ?? 5000; this.blinkMax = options.blinkMax ?? 15000; this.blinkDuration = options.blinkDuration ?? 175; diff --git a/index.html b/index.html index 906a3f7..80b5ab9 100644 --- a/index.html +++ b/index.html @@ -155,7 +155,10 @@ -webkit-user-select: none; user-select: none; } - + .content-area ul#contentList li { + word-break: break-all; + overflow-wrap: anywhere; + } #folderHierarchyDropdown.open { display: block; } diff --git a/main.js b/main.js index d63c845..09471ad 100644 --- a/main.js +++ b/main.js @@ -13,6 +13,22 @@ const simpleGit = require('simple-git'); const chokidar = require('chokidar'); const micromatch = require('micromatch'); const ignore = require('ignore'); +let isQuiting = false; + +// Wenn wir gebündelt sind (= gepackte App), erweitern wir den PATH um die typischen Ollama-Verzeichnisse: +if (app.isPackaged) { + // Homebrew‐Pfad (M1/M2): /opt/homebrew/bin, bzw. /usr/local/bin + const extraPaths = [ + '/opt/homebrew/bin', + '/usr/local/bin', + '/usr/bin', + '/bin' + ].filter(p => fs.existsSync(p)); + + // Ganz vorne in PATH einfügen, damit "ollama" gefunden wird + process.env.PATH = extraPaths.join(':') + ':' + process.env.PATH; +} + const store = new Store({ defaults: { @@ -25,7 +41,8 @@ const store = new Store({ autostart: false, closeToTray: true, needsRelocation: false, - dailyCommitStats: {} + dailyCommitStats: {}, + giteaToken: '' } }); @@ -38,7 +55,6 @@ store.set('folders', folders); console.log("Startup-Folders:", store.get('folders')); let tray = null; -let isQuiting = false; @@ -95,7 +111,7 @@ function createWindow() { const win = new BrowserWindow({ width: 900, height: 600, - minWidth: 600, + minWidth: 800, minHeight: 500, title: 'Auto-Git', webPreferences: { @@ -117,8 +133,8 @@ function openSettings(win) { settingsWin = new BrowserWindow({ parent: win, modal: true, - width: 450, - height: 450, + width: 600, + height: 500, resizable: false, webPreferences: { preload: path.join(__dirname, 'preload.js'), @@ -127,7 +143,7 @@ function openSettings(win) { }); settingsWin.removeMenu(); settingsWin.loadFile('settings.html'); - settingsWin.webContents.openDevTools({ mode: 'detach' }); + //settingsWin.webContents.openDevTools({ mode: 'detach' }); settingsWin.on('closed', () => settingsWin = null); } @@ -1254,6 +1270,14 @@ async function main() { } }); + win.on('close', (e) => { + // Wenn closeToTray aktiv ist und wir NICHT wirklich beenden wollen, + // wird das Schließen abgefangen und das Fenster nur versteckt. + if (!isQuiting && store.get('closeToTray')) { + e.preventDefault(); + win.hide(); + } + }); /* ──────────────────────────────────────────────────── */ @@ -1322,7 +1346,11 @@ async function main() { role: 'appMenu', submenu: [ { label: 'Settings', click: () => openSettings(win) }, - { label: 'Quit', role: 'quit', click: () => { isQuiting = true; app.quit(); } } + { label: 'Quit', click: () => { + isQuiting = true; + app.quit(); + } + } ] }, { role: 'editMenu' } @@ -1388,7 +1416,11 @@ function buildTrayMenu() { } }, { type: 'separator' }, - { label: 'Beenden', click: () => { isQuiting = true; app.quit(); } } + { label: 'Beenden', click: () => { + isQuiting = true; + app.quit(); + } + } ]); } @@ -1400,13 +1432,6 @@ function buildTrayMenu() { tray.setContextMenu(buildTrayMenu()); }); - // Optional: Minimieren auf Tray bei Fenster-Schließen - win.on('close', (e) => { - if (!app.isQuiting) { - e.preventDefault(); - win.hide(); - } - }); // Doppelklick aufs Tray: Fenster zeigen tray.on('double-click', () => { @@ -1874,15 +1899,14 @@ function buildTrayMenu() { }); ipcMain.handle('ollama-list', async () => { - // Versuche erst JSON-Ausgabe return new Promise(resolve => { exec('ollama list --json', (err, stdout, stderr) => { if (err) { - // ENOENT → ollama CLI fehlt - if (err.code === 'ENOENT') { + // FEHLENDER Befehl kann err.code === 'ENOENT' ODER err.code === 127 sein. + if (err.code === 'ENOENT' || err.code === 127) { return resolve({ status: 'no-cli' }); } - // JSON-Modus nicht unterstützt? Dann Fallback auf plain text + // Falls ollama installiert ist, aber „--json“ nicht unterstützt wird, Fallback auf plain text return parsePlain(); } try { @@ -1896,15 +1920,16 @@ function buildTrayMenu() { } }); - // Fallback-Funktion: parst die tabellarische Ausgabe function parsePlain() { exec('ollama list', (err2, out2, stderr2) => { + // Auch hier prüfen, ob ollama fehlt if (err2) { - if (err2.code === 'ENOENT') return resolve({ status: 'no-cli' }); + if (err2.code === 'ENOENT' || err2.code === 127) { + return resolve({ status: 'no-cli' }); + } return resolve({ status: 'error', msg: stderr2 || err2.message }); } const models = []; - // Jede Zeile nach HEADER ignorieren, Spalten splitten out2.split('\n').slice(1).forEach(line => { const cols = line.trim().split(/\s{2,}/); if (cols[0]) models.push({ name: cols[0] }); @@ -2262,9 +2287,10 @@ Source Code: ipcMain.handle('push-to-gitea', async (_evt, folderPath) => { try { const repoName = path.basename(folderPath); - const GITEA_TOKEN = process.env.GITEA_TOKEN; + // read token from store instead of process.env + const GITEA_TOKEN = store.get('giteaToken'); if (!GITEA_TOKEN) { - throw new Error('No GITEA_TOKEN set in environment'); + throw new Error('No Gitea API token configured – open Settings and enter it first'); } const GITEA_BASE = 'https://giers10.uber.space/api/v1'; @@ -2349,7 +2375,14 @@ ipcMain.handle('push-to-gitea', async (_evt, folderPath) => { } }); + ipcMain.handle('get-gitea-token', () => { + return store.get('giteaToken') || ''; + }); + // Set/save the Gitea token + ipcMain.handle('set-gitea-token', (_e, token) => { + store.set('giteaToken', token); + }); @@ -2362,15 +2395,6 @@ ipcMain.handle('push-to-gitea', async (_evt, folderPath) => { // … Ende der IPC-Handler … - - win.webContents.openDevTools({ mode: 'detach' }); - // clean up on exit - win.on('close', (e) => { - if (!isQuiting && store.get('closeToTray')) { - e.preventDefault(); - win.hide(); - } - }); }; diff --git a/package.json b/package.json index aa57e09..6884aec 100644 --- a/package.json +++ b/package.json @@ -1,32 +1,13 @@ { "productName": "Auto-Git", "name": "Auto-Git", - "description": "Auto-Git: Git-Surveillance with automatic LLM-Commit-Message and README.md compilation", "version": "1.0.0", + "description": "Auto-Git: Git-Überwachung mit automatischer LLM-Commit-Message und README-Erstellung", "author": "Victor Giers", "main": "main.js", "scripts": { "start": "electron .", - "dist": "electron-builder" - }, - "build": { - "appId": "com.victorgiers.auto-git", - "productName": "Auto-Git", - "files": [ - "**/*" - ], - "directories": { - "buildResources": "assets/icon" - }, - "mac": { - "icon": "mac/icon.icns" - }, - "win": { - "icon": "win/icon.ico" - }, - "linux": { - "icon": "linux/icon.png" - } + "dist": "electron-builder --publish never" }, "dependencies": { "chokidar": "^4.0.3", @@ -43,5 +24,32 @@ "electron-builder": "^26.0.12", "postcss": "^8.5.3", "tailwindcss": "^4.1.7" + }, + "build": { + "appId": "com.victorgiers.auto-git", + "productName": "Auto-Git", + "files": [ + "main.js", + "preload.js", + "renderer.js", + "index.html", + "settings.html", + "animeCat.js", + "rewrite-commit-msg.js.template", + "assets/**/*", + "node_modules/**/*" + ], + "directories": { + "buildResources": "assets/icon" + }, + "mac": { + "icon": "mac/icon.icns" + }, + "win": { + "icon": "win/icon.ico" + }, + "linux": { + "icon": "linux/icon.png" + } } -} +} \ No newline at end of file diff --git a/preload.js b/preload.js index 152a8a7..d73df25 100644 --- a/preload.js +++ b/preload.js @@ -18,6 +18,8 @@ contextBridge.exposeInMainWorld('settingsAPI', { setAutostart: val => ipcRenderer.invoke('set-autostart', val), getCloseToTray: () => ipcRenderer.invoke('get-close-to-tray'), setCloseToTray: val => ipcRenderer.invoke('set-close-to-tray', val), + getGiteaToken: () => ipcRenderer.invoke('get-gitea-token'), + setGiteaToken: (token) => ipcRenderer.invoke('set-gitea-token', token), }); contextBridge.exposeInMainWorld('electronAPI', { diff --git a/settings.html b/settings.html index 5a0e08c..dc69680 100644 --- a/settings.html +++ b/settings.html @@ -169,6 +169,7 @@ const cancel = document.getElementById('cancelBtn'); const cbAutostart = document.getElementById('autostart'); const cbCloseToTray= document.getElementById('closeToTray'); + const giteaTokenInput = document.getElementById('giteaTokenInput'); const [initialAutostart, initialCloseToTray] = await Promise.all([ window.settingsAPI.getAutostart(), @@ -196,6 +197,13 @@ await window.settingsAPI.setSkyMode(cbSky.checked); document.body.classList.toggle('sky-mode', cbSky.checked); }); + + + const initialToken = await window.settingsAPI.getGiteaToken(); + giteaTokenInput.value = initialToken || ''; + + + // OK: alles final speichern ok.addEventListener('click', async () => { await window.settingsAPI.setSkipPrompt(cbSkip.checked); @@ -222,6 +230,9 @@ if (commitSel) await window.settingsAPI.setCommitModel(commitSel.value); if (readmeSel) await window.settingsAPI.setReadmeModel(readmeSel.value); + await window.settingsAPI.setGiteaToken(giteaTokenInput.value.trim()); + + window.settingsAPI.close(); }); // Cancel / Close: SkyMode zurücksetzen, dann schließen @@ -238,7 +249,7 @@ if (res.status === 'no-cli') { container.innerHTML = `