585 lines
18 KiB
Markdown
585 lines
18 KiB
Markdown
# Entwicklerhandbuch — Git Manager Explorer Pro
|
|
|
|
Dieses Dokument richtet sich an Entwickler, die an **Git Manager Explorer Pro** beitragen oder das Projekt erweitern möchten.
|
|
|
|
---
|
|
|
|
## Inhaltsverzeichnis
|
|
|
|
1. [Projektstruktur](#projektstruktur)
|
|
2. [Setup & Abhängigkeiten](#setup--abhängigkeiten)
|
|
3. [Entwicklung starten](#entwicklung-starten)
|
|
4. [Wichtige Module](#wichtige-module)
|
|
5. [Neue Features hinzufügen](#neue-features-hinzufügen)
|
|
6. [Build & Release](#build--release)
|
|
7. [Debugging & Testing](#debugging--testing)
|
|
8. [Code-Konventionen](#code-konventionen)
|
|
9. [Häufige Aufgaben](#häufige-aufgaben)
|
|
|
|
---
|
|
|
|
## Projektstruktur
|
|
|
|
```
|
|
git-manager-gui/
|
|
├── main.js # Electron Main Process — Fenster, Menü, IPC
|
|
├── preload.js # Preload Script — sichere Electron API für Renderer
|
|
├── renderer/ # Frontend (React/Vanilla JS)
|
|
│ ├── App.jsx # React-Komponente (optional, optional genutzt)
|
|
│ ├── Settings.jsx # Settings-Modal
|
|
│ ├── index.html # HTML Entry Point
|
|
│ ├── index.js # Renderer Init
|
|
│ ├── renderer.js # Hauptlogik: UI, Grid, Editor, API-Calls
|
|
│ ├── style.css # Styling
|
|
│ └── modules/ # Feature-Module
|
|
│ ├── editor.js # Editor-Funktion (Syntax Highlighting, etc.)
|
|
│ ├── gitea.js # Gitea API Wrapper
|
|
│ ├── github.js # GitHub API Wrapper
|
|
│ ├── progress.js # Progress-Bar & Ladeindikatoren
|
|
│ ├── state.js # State Management (Favoriten, Verlauf, etc.)
|
|
│ └── ui.js # UI Helpers (Dialoge, Toast, etc.)
|
|
├── src/ # Backend (Node.js Main Process)
|
|
│ ├── git/
|
|
│ │ ├── gitHandler.js # Git CLI Wrapper (Commits, Tags, etc.)
|
|
│ │ └── apiHandler.js # Gitea/GitHub API HTTP Client
|
|
│ ├── backup/
|
|
│ │ ├── BackupManager.js # Backup/Restore Logik
|
|
│ │ ├── BackupProvider.js # Provider Interface
|
|
│ │ └── LocalProvider.js # Lokale Datei-Provider
|
|
│ └── utils/
|
|
│ └── helpers.js # Allgemeine Hilfsfunktionen
|
|
├── __tests__/
|
|
│ └── gitHandler.test.js # Jest Unit Tests
|
|
├── updater.js # App-Update-Logik
|
|
├── package.json # Dependencies & Scripts
|
|
├── HANDBUCH.html # Benutzerhandbuch (HTML)
|
|
└── README.md # Projekt-Übersicht
|
|
|
|
```
|
|
|
|
---
|
|
|
|
## Setup & Abhängigkeiten
|
|
|
|
### Voraussetzungen
|
|
- **Node.js** 16+ (empfohlen: LTS)
|
|
- **npm** 7+
|
|
- **Git** (für Git-Operationen)
|
|
- **Visual Studio Code** (optional, empfohlen)
|
|
|
|
### Installation
|
|
|
|
```bash
|
|
# Repository klonen
|
|
git clone https://github.com/dein-username/git-manager-gui.git
|
|
cd git-manager-gui
|
|
|
|
# Dependencies installieren
|
|
npm install
|
|
|
|
# App starten
|
|
npm start
|
|
```
|
|
|
|
### Wichtige Dependencies
|
|
|
|
| Package | Verwendung |
|
|
|---------|-----------|
|
|
| `electron` | Desktop-Framework |
|
|
| `sqlite3` | Lokale Datenspeicherung (Favoriten, Verlauf) |
|
|
| `axios` | HTTP-Requests zu Gitea/GitHub APIs |
|
|
| `crypto` | Verschlüsselung von Credentials |
|
|
| `jest` | Testing Framework |
|
|
|
|
---
|
|
|
|
## Entwicklung starten
|
|
|
|
### Dev-Server / Hot Reload
|
|
|
|
Es gibt aktuell keinen automatischen Hot Reload. Nach Code-Änderungen:
|
|
|
|
```bash
|
|
# App neu starten
|
|
npm start
|
|
|
|
# Oder im laufenden Fenster: DevTools öffnen
|
|
# Strg+Shift+I → Reload (Strg+R)
|
|
```
|
|
|
|
### DevTools debuggen
|
|
|
|
```javascript
|
|
// In main.js, beim Erstellen des Fensters:
|
|
mainWindow.webContents.openDevTools();
|
|
|
|
// Oder per Shortcut im laufenden Fenster:
|
|
// Strg+Shift+I
|
|
```
|
|
|
|
### Logs anschauen
|
|
|
|
```bash
|
|
# Logs der letzten Session anschauen:
|
|
# Windows: %APPDATA%\git-manager-gui\logs\
|
|
# oder direkt im app data folder
|
|
|
|
# Mit Winston logger (falls implementiert):
|
|
npm run logs
|
|
```
|
|
|
|
---
|
|
|
|
## Wichtige Module
|
|
|
|
### `renderer/renderer.js` — Hauptlogik
|
|
|
|
Das Herzstück der App. Enthält:
|
|
|
|
- **Globale State-Variablen**: `favorites`, `recentRepos`, `currentState`, `pinnedRepos`
|
|
- **Grid-Rendering**: `loadRepos()`, `loadGiteaRepos()`, `loadGithubRepos()`
|
|
- **Kontext-Menü**: `showRepoContextMenu()`
|
|
- **Datei-Explorer**: `loadRepoContents()`, `renderExplorer()`
|
|
- **Editor**: `openFileEditor()`, mit Speichern & Syntax-Highlighting
|
|
- **Favoriten/Verlauf**: `addToFavorites()`, `addToRecent()`
|
|
|
|
**Wichtige Funktionen:**
|
|
|
|
```javascript
|
|
// Repository-Liste laden
|
|
loadRepos() → loadGiteaRepos() oder loadGithubRepos()
|
|
|
|
// Repository öffnen (Datei-Explorer)
|
|
loadRepoContents(owner, repo, path)
|
|
|
|
// Datei bearbeiten
|
|
openFileEditor(owner, repo, path, content)
|
|
|
|
// Favoriten hinzufügen
|
|
async addToFavorites(owner, repo, cloneUrl, platform)
|
|
|
|
// Settings speichern
|
|
async saveSettings(settings)
|
|
```
|
|
|
|
### `src/git/gitHandler.js` — Git-Operationen
|
|
|
|
Wrapper um Git CLI. Beispiele:
|
|
|
|
```javascript
|
|
// Commits einsehen
|
|
const commits = await getCommitLog(repoPath, branch);
|
|
|
|
// Tags auflisten
|
|
const tags = await getTagList(repoPath);
|
|
|
|
// Branch wechseln
|
|
await checkoutBranch(repoPath, branchName);
|
|
|
|
// Lokales Repo klonen
|
|
await cloneRepository(cloneUrl, targetPath);
|
|
```
|
|
|
|
### `src/git/apiHandler.js` — API-Calls
|
|
|
|
HTTP-Wrapper für Gitea/GitHub APIs.
|
|
|
|
```javascript
|
|
// Gitea Repositories auflisten
|
|
const repos = await getGiteaRepos(url, token, username);
|
|
|
|
// GitHub Repositories
|
|
const repos = await getGithubRepos(token);
|
|
|
|
// Repository erstellen
|
|
await createGiteaRepo(url, token, { name, description, private });
|
|
|
|
// Datei speichern
|
|
await updateGiteaFile(url, token, owner, repo, path, content, message);
|
|
```
|
|
|
|
### `renderer/modules/state.js` — State Management
|
|
|
|
Persistiert Favoriten, Verlauf und Settings.
|
|
|
|
```javascript
|
|
// State laden/speichern
|
|
loadState() → returns { favorites, recent, pinnedRepos }
|
|
saveState(state) → speichert lokal
|
|
|
|
// Helpers
|
|
addFavorite(repo)
|
|
removeFavorite(repo)
|
|
addRecentRepo(repo)
|
|
clearRecent()
|
|
```
|
|
|
|
---
|
|
|
|
## Neue Features hinzufügen
|
|
|
|
### Beispiel: Neuer API-Endpoint integrieren
|
|
|
|
#### Schritt 1: API-Wrapper in `src/git/apiHandler.js` ergänzen
|
|
|
|
```javascript
|
|
/**
|
|
* Gitea Webhook auflisten
|
|
*/
|
|
async function getGiteaWebhooks(url, token, owner, repo) {
|
|
const path = `/api/v1/repos/${owner}/${repo}/hooks`;
|
|
return axios.get(`${url}${path}`, {
|
|
headers: { 'Authorization': `token ${token}` }
|
|
}).then(r => r.data);
|
|
}
|
|
|
|
module.exports = { getGiteaWebhooks, /* ... other functions */ };
|
|
```
|
|
|
|
#### Schritt 2: IPC-Handler in `main.js` ergänzen
|
|
|
|
```javascript
|
|
// In ipcMain.handle() Bereich:
|
|
ipcMain.handle('getGiteaWebhooks', async (event, { url, token, owner, repo }) => {
|
|
try {
|
|
const webhooks = await apiHandler.getGiteaWebhooks(url, token, owner, repo);
|
|
return { ok: true, webhooks };
|
|
} catch (err) {
|
|
return { ok: false, error: err.message };
|
|
}
|
|
});
|
|
```
|
|
|
|
#### Schritt 3: UI in `renderer/renderer.js` hinzufügen
|
|
|
|
```javascript
|
|
// Button im Repo-Kontextmenü:
|
|
if (option === 'webhooks') {
|
|
const webhooks = await window.electronAPI.getGiteaWebhooks({
|
|
url: currentState.giteaUrl,
|
|
token: credentials.giteaToken,
|
|
owner,
|
|
repo
|
|
});
|
|
if (webhooks.ok) {
|
|
showWebhookList(webhooks.webhooks);
|
|
} else {
|
|
showError('Webhooks laden fehlgeschlagen: ' + webhooks.error);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Build & Release
|
|
|
|
### Production Build
|
|
|
|
```bash
|
|
# Electron App als .exe packagen
|
|
npm run build
|
|
|
|
# Output: dist/git-manager-gui-Setup-2.x.x.exe
|
|
```
|
|
|
|
### Abbrechbare Vorgänge
|
|
|
|
Uploads, Ordner-Downloads und Batch-Clones laufen über **ein** gemeinsames Abbruch-System:
|
|
|
|
- `main.js`: `beginCancellableUpload()` legt einen `AbortController` an, `endCancellableUpload()` räumt auf (immer im `finally`). Der IPC-Kanal `cancel-upload` bricht alle laufenden Vorgänge ab.
|
|
- Das `signal` wird durchgereicht an `simple-git` (`abort`), `execGit`/`runGitAsync` (`signal`), `runLimited` und `uploadItemsViaGiteaApi` (axios `signal`).
|
|
- Ein Abbruch ist **kein Fehler**: Er läuft als `UPLOAD_CANCELLED` durch die Kette (`createUploadCancelledError`, `isUploadCancelledError`, `throwIfUploadCancelled` in `src/git/apiHandler.js`), löst keinen API-Ausweichweg aus und kommt als `{ ok: false, cancelled: true }` im Renderer an.
|
|
- Neuer abbrechbarer Handler: `beginCancellableUpload()` am Anfang, `signal` weiterreichen, im `catch` `isUploadCancelledError(e)` abfangen, im `finally` `endCancellableUpload()`. Im Renderer `showProgress(..., { cancellable: true })`.
|
|
- Unter Windows beendet `spawn(signal)` nur `git.exe`; `execGit` beendet deshalb den ganzen Prozessbaum (`taskkill /T /F`) und kehrt sofort zurück.
|
|
|
|
### Pause, Sperre, Benachrichtigung, Release-Assistent
|
|
|
|
- **Pause:** `src/features/pauseGate.js` (`createPauseGate`). In `main.js` gibt es genau ein `transferGate`. Kontrollpunkte rufen `await transferGate.wait(signal)` auf (in `runLimited`, vor dem Staging der Git-Wege, zwischen den Paketen von `uploadItemsViaGiteaApi` über `waitIfPaused`, vor jedem Batch-Clone). Ein Abbruch löst Wartende sofort aus. Neue langlaufende Schritte brauchen einen eigenen Kontrollpunkt.
|
|
- **Zugangsdaten-Sperre:** `src/features/uploadBlocklist.js` nutzt die Dateinamen-Regeln aus `secretScan.js`. `removeBlockedInPlace()` und `blockedSecretReason()` in `main.js` sind in allen Upload-Handlern eingebaut, die Ergebnisse tragen `blockedFiles`. Neuer Upload-Weg: dort ebenfalls aufrufen. Einstellung `uploadBlockSecrets`.
|
|
- **Benachrichtigung:** `src/features/transferNotice.js` baut den Text aus dem Verlaufseintrag, `maybeNotifyTransfer()` in `main.js` zeigt ihn nur, wenn das Hauptfenster nicht vorn ist (Einstellung `notifyTransfers`).
|
|
- **Release-Assistent:** `src/features/releaseAssist.js` (Version aus Dateiname, Versionsvergleich, Tag-Prüfung, Release-Text mit Prüfsummen). IPC `inspect-release-file` und `prepare-release`, Oberfläche in `showCreateReleaseModal()`. Das Prüfsummen-Format in `buildReleaseBody` muss zu `extractChecksumFromReleaseBody` in `updater.js` passen.
|
|
|
|
### Startanimation
|
|
|
|
Nach dem Vorbild des AeroMC-Launchers (`AeroMC-Launcher/src/startanimation.js`):
|
|
|
|
1. `createWindow()` berechnet Position und Größe (`centeredBounds`) und legt über `begin()` zuerst ein randloses, durchsichtiges Fenster mit `renderer/splash.html` an: das Logo dreht sich (CSS `rotateY`), darunter der Schriftzug.
|
|
2. Das Hauptfenster entsteht danach mit denselben Maßen, verborgen, und lädt.
|
|
3. `play()` wartet auf `did-finish-load` (höchstens 12 s) und mindestens 1,6 s Drehzeit. Dann zeigt es das Hauptfenster unsichtbar (Deckkraft 0, Mausereignisse aus), wartet auf die gezeichnete Oberfläche (Repo-Liste oder höchstens 1,5 s), fotografiert es mit `capturePage()` und lässt `aufbauen()` in `splash.js` das Bild von der Mitte aus aufziehen.
|
|
4. Am Ende übernimmt das echte Fenster an derselben Stelle. Fehler und Zeitüberschreitungen zeigen das Hauptfenster immer trotzdem.
|
|
|
|
**Stolperstein:** `setIgnoreMouseEvents(true)` am Startfenster darf erst nach dem Zeigen und leicht verzögert aufgerufen werden (`IGNORE_MOUSE_DELAY_MS`). Davor aufgerufen wird das durchsichtige Fenster unter Windows weiß. `scripts/ui-smoke-splash.js` prüft das über eine Bildschirmaufnahme (Farbe an einer leeren Stelle muss der des Desktops entsprechen) und darf deshalb die Hardware-Beschleunigung nicht abschalten.
|
|
|
|
Beim Start mit `--hidden` und bei abgeschalteter Einstellung `showSplash` gibt es die Animation nicht. `scripts/ui-smoke-splash.js` prüft sie mit einem Ersatz-Hauptfenster. Im Entwicklungsmodus (`electron .`) startet die App wegen der vielen `node_modules`-Dateien deutlich langsamer als das gepackte Programm; die Animation selbst wird dadurch nicht langsamer.
|
|
|
|
### Oberflächen-Testlauf
|
|
|
|
`npm run test:ui` (`scripts/ui-smoke.js`) startet die App mit leerem eigenen `APPDATA`, steuert sie über den Debug-Port und prüft Toolbar-Layout bei drei Breiten, Fortschrittsbalken, Pause, Verlauf, Sperre, Release-Prüfung und Vorlagen. `scripts/ui-smoke-tray.js` prüft das Tray-Menüfenster in echtem Electron. Der Lauf berührt weder echte Zugangsdaten noch einen Server und dauert gut eine Minute.
|
|
|
|
### Tray-Menü
|
|
|
|
Das Tray-Symbol öffnet kein natives Menü, sondern ein eigenes kleines Fenster, denn das native Electron-Menü zeichnet unter Windows keine Hover-Markierung:
|
|
|
|
- `src/features/trayMenu.js`: Inhalt (`buildTrayTemplate`, `serializeTemplate`, `runAction`, `trayTooltip`), ohne Electron und damit testbar. Neuer Eintrag: dort mit `id` ergänzen, die Aktion in `trayTemplate()` in `main.js` verdrahten.
|
|
- `src/features/trayPopup.js`: das Fenster (frameless, transparent, schließt bei Fokusverlust und Esc). Es wird 2 Sekunden nach dem Start vorgeladen, weil der erste Renderer-Start mehrere Sekunden dauert.
|
|
- `renderer/tray-menu.html`, `renderer/tray-menu.js`, `tray-menu-preload.js`: Darstellung (hell/dunkel nach Windows-Design, Pfeiltasten und Enter) und die vier IPC-Kanäle.
|
|
- Das Fenster ist von der Zoom-Einstellung ausgenommen und wird beim Beenden zerstört, sonst hielte das versteckte Fenster die App am Leben.
|
|
|
|
### Upload-Verlauf und Wiederholen
|
|
|
|
- `src/features/uploadHistory.js` (`buildEntry`, `filterEntries`, `createUploadHistory`): speichert die letzten 100 Uploads in `upload-history.json` im userData-Ordner. `main.js` umhüllt dafür `ipcMain.handle` für die Kanäle in `UPLOAD_HISTORY_CHANNELS`, neue Upload-Kanäle dort eintragen.
|
|
- Teilfehler: `buildPartialUploadError` hängt die fehlgeschlagenen Einträge an den Fehler (`failedItems`). Die Handler geben sie als `retryItems` zurück, der Renderer sendet sie über den Parameter `items` erneut (`retryFailedUploads`).
|
|
- `.gitignore`-Vorlagen: `src/features/gitignoreTemplates.js`.
|
|
|
|
### Version erhöhen
|
|
|
|
1. Version in `package.json` updaten: `"version": "2.2.1"`
|
|
2. Changelog aktualisieren (optional)
|
|
3. Build ausführen
|
|
4. GitHub Release erstellen mit der .exe
|
|
|
|
---
|
|
|
|
## Debugging & Testing
|
|
|
|
### Unit Tests schreiben
|
|
|
|
Jest ist konfiguriert. Test-Datei Vorlage:
|
|
|
|
```javascript
|
|
// __tests__/myFeature.test.js
|
|
const { myFunction } = require('../src/git/gitHandler');
|
|
|
|
describe('Git Handler', () => {
|
|
it('should parse commit log', () => {
|
|
const result = myFunction(testData);
|
|
expect(result.length).toBe(3);
|
|
expect(result[0].sha).toMatch(/^[a-f0-9]{7}/);
|
|
});
|
|
});
|
|
```
|
|
|
|
Tests starten:
|
|
|
|
```bash
|
|
npm test
|
|
|
|
# Mit Coverage:
|
|
npm test -- --coverage
|
|
|
|
# Watch Mode:
|
|
npm test -- --watch
|
|
```
|
|
|
|
### Debugging im DevTools
|
|
|
|
```javascript
|
|
// Im renderer.js oder irgendwo im Renderer:
|
|
console.log('Debug Info:', data);
|
|
|
|
// Öffne DevTools: Strg+Shift+I
|
|
// Console Tab → alle Logs sichtbar
|
|
```
|
|
|
|
### Main Process debuggen
|
|
|
|
```javascript
|
|
// In main.js:
|
|
console.log('Main Process Log:', data);
|
|
|
|
// Logs erscheinen in der Terminal-Console
|
|
// wenn die App mit npm start gestartet wurde
|
|
```
|
|
|
|
---
|
|
|
|
## Code-Konventionen
|
|
|
|
### Variablen & Funktionen
|
|
|
|
```javascript
|
|
// camelCase für Variablen und Funktionen
|
|
const repoName = "mein-projekt";
|
|
function loadRepositories() { }
|
|
|
|
// SCREAMING_SNAKE_CASE für Konstanten
|
|
const MAX_RETRIES = 5;
|
|
const DEFAULT_TIMEOUT = 3000;
|
|
|
|
// Präfixe für Boolean-Variablen
|
|
const isPrivate = true;
|
|
const hasCredentials = false;
|
|
const shouldRetry = true;
|
|
```
|
|
|
|
### Async/Await
|
|
|
|
```javascript
|
|
// Immer try-catch für async Funktionen
|
|
async function loadData() {
|
|
try {
|
|
const data = await fetchFromAPI();
|
|
return { ok: true, data };
|
|
} catch (error) {
|
|
console.error('Error:', error);
|
|
return { ok: false, error: error.message };
|
|
}
|
|
}
|
|
```
|
|
|
|
### Kommentare
|
|
|
|
```javascript
|
|
// Kurze Inline-Kommentare über Code
|
|
const delay = 1000; // Millisekunden
|
|
|
|
/**
|
|
* Längere Beschreibung vor Funktion
|
|
* @param {string} repoName - Name des Repositories
|
|
* @returns {Promise<Object>} Result mit { ok, data, error }
|
|
*/
|
|
async function loadRepository(repoName) {
|
|
// Implementierung
|
|
}
|
|
```
|
|
|
|
### Fehlerbehandlung
|
|
|
|
```javascript
|
|
// Immer aussagekräftige Fehlermeldungen
|
|
if (!token) {
|
|
return { ok: false, error: 'missing-token' };
|
|
}
|
|
|
|
// Oder sprechend für Benutzer:
|
|
if (!token) {
|
|
return { ok: false, error: 'Gitea Token nicht gespeichert. Bitte Settings öffnen.' };
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Häufige Aufgaben
|
|
|
|
### Neue Einstellung hinzufügen
|
|
|
|
1. **In `Settings.jsx` UI-Control hinzufügen**
|
|
```jsx
|
|
<label>Neue Option</label>
|
|
<input type="checkbox" onChange={(e) => setSetting('newOption', e.target.checked)} />
|
|
```
|
|
|
|
2. **In `renderer.js` speichern**
|
|
```javascript
|
|
async function saveSettings(settings) {
|
|
const result = await window.electronAPI.saveSettings(settings);
|
|
// ...
|
|
}
|
|
```
|
|
|
|
3. **In `main.js` Handler**
|
|
```javascript
|
|
ipcMain.handle('saveSettings', async (event, settings) => {
|
|
// Validation und Speicherung
|
|
return { ok: true };
|
|
});
|
|
```
|
|
|
|
### Neuer Button in der Toolbar
|
|
|
|
1. **In `index.html` Button hinzufügen**
|
|
```html
|
|
<button id="btnMyFeature" title="Mein Feature">🎯 Feature</button>
|
|
```
|
|
|
|
2. **In `renderer.js` Event-Handler**
|
|
```javascript
|
|
if ($('btnMyFeature')) {
|
|
$('btnMyFeature').onclick = () => {
|
|
myFeatureHandler();
|
|
};
|
|
}
|
|
```
|
|
|
|
### Neue Kontextmenü-Option
|
|
|
|
1. **In `showRepoContextMenu()` Item hinzufügen**
|
|
```javascript
|
|
items.push({
|
|
label: '🎯 Meine Aktion',
|
|
click: () => myActionHandler(owner, repo)
|
|
});
|
|
```
|
|
|
|
2. **Handler implementieren**
|
|
```javascript
|
|
function myActionHandler(owner, repo) {
|
|
// Logik...
|
|
}
|
|
```
|
|
|
|
### Neue API-Methode aufrufen
|
|
|
|
1. **In `src/git/apiHandler.js` ergänzen**
|
|
2. **In `main.js` IPC-Handler anlegen**
|
|
3. **In `renderer.js` aufrufen:**
|
|
```javascript
|
|
const result = await window.electronAPI.myNewMethod({ param1, param2 });
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting für Entwickler
|
|
|
|
### App startet nicht
|
|
```bash
|
|
# Node/npm Version prüfen
|
|
node --version # sollte >= 16
|
|
npm --version # sollte >= 7
|
|
|
|
# Dependencies neu installieren
|
|
rm -r node_modules
|
|
npm install
|
|
npm start
|
|
```
|
|
|
|
### Fehler: "Cannot find module"
|
|
```bash
|
|
# Dependencies aktualisieren
|
|
npm install
|
|
|
|
# Cache löschen
|
|
npm cache clean --force
|
|
```
|
|
|
|
### Axios/API-Calls schlagen fehl
|
|
- URL/Token in Settings prüfen
|
|
- Gitea-Server online? `curl https://git.example.com/api/v1/user`
|
|
- Token noch gültig? Im Gitea-Interface regenerieren
|
|
- Firewall/VPN blockiert?
|
|
|
|
### Datei-Upload funktioniert nicht
|
|
- Lokale Temp-Pfade prüfen (in `main.js`)
|
|
- Git-Auth konfiguriert?
|
|
- Ausreichend Festplatte?
|
|
|
|
---
|
|
|
|
## Ressourcen
|
|
|
|
- [Electron Dokumentation](https://www.electronjs.org/docs)
|
|
- [Gitea API](https://docs.gitea.io/en-us/api-usage/)
|
|
- [GitHub API v3](https://docs.github.com/en/rest)
|
|
- [Jest Testing](https://jestjs.io/docs/getting-started)
|
|
|
|
---
|
|
|
|
## Lizenz & Beitragen
|
|
|
|
Dieses Projekt ist unter der **MIT-Lizenz** lizenziert.
|
|
Für Beiträge bitte einen **Pull Request** einreichen mit aussagekräftiger Beschreibung.
|
|
|
|
---
|
|
|
|
**Letzte Aktualisierung:** 13. Mai 2026 | **Ersteller:** M_Viper
|