Skip to content

agent: #14 [Agent] Import eines Ordners mit Markdown- oder Textdateien - #26

Draft
leonatwork wants to merge 1 commit into
mainfrom
agent/bearbeite-github-issue-14-vollst-ndig-un-1021-1536
Draft

leonatwork wants to merge 1 commit into
mainfrom
agent/bearbeite-github-issue-14-vollst-ndig-un-1021-1536

Conversation

@leonatwork

Copy link
Copy Markdown
Owner

Zusammenfassung

Autonome Umsetzung von #14: [Agent] Import eines Ordners mit Markdown- oder Textdateien

Verifikation

  • Coder-/Reviewer-Loop: APPROVE nach 1 Runde(n)

  • Tests und Qualitätsprüfungen: siehe Commit und CI-Checks

  • Kein automatischer Merge oder Produktionsdeploy

  • Modell: azure/gpt-6.1-sol; Decision-1 (active): route gpt-5.3-codex, Risiko medium; QS: npm run build && npm test bestanden

  • Art der Änderung (Triage): code; Zweitprüfung: azure/gpt-5.3-codex

  • Kosten (Listenpreis): 4,5 Mio Tokens · 1,64 €

Hinweise der Qualitätsprüfung

  • Review-Hinweis (minor: core/importieren/markdown.ts:42 — Eine Datei, die nur aus einer Titelüberschrift besteht (z. B. # Ebbe\n), gilt als „leer“ und wird übersprungen, ihr Kapiteltitel fehlt danach. Der Word-Import übernimmt leere Kapitel dagegen als „geplant“ (importUebernehmen, leer → speicherePlan). Vorschlag: Solche Dateien als Kapitel mit leerem Text übernehmen und nur einen Hinweis zeigen; komplett leere Dateien weiter überspringen.)
  • Review-Hinweis (minor: core/importieren/markdown.ts:39 — Beginnt eine .md- oder .txt-Datei mit --- als Trennlinie und folgt später eine zweite ----Zeile, wird der Text dazwischen als Frontmatter entfernt. Dabei geht Text verloren, wenn auch selten. Vorschlag: Den Block nur entfernen, wenn er sich als YAML-Zuordnung parsen lässt (wie parseFrontmatter in core/projekt/lesen.ts).)
  • Review-Hinweis (minor: src/features/importexport/ImportDialog.tsx:102 — Die Phase liest wird schon gesetzt, bevor der native Dialog öffnet. Während der Auswahl steht deshalb „„Word“ wird gelesen …“ bzw. „„Ordner mit …“ wird gelesen …“, auch für den bestehenden Word-Weg. Vorschlag: liest erst nach erfolgreicher Auswahl setzen, wie vorher.)
  • Review-Hinweis (minor: src/features/importexport/ImportDialog.tsx:218 — Die Schaltfläche in der Vorschau heißt nur „Quelle“ / „Source“, das ist als Aktion unklar. Vorschlag: z. B. „Andere Quelle …“ / „Change source…“.)
  • Review-Hinweis (minor: src/features/importexport/ImportDialog.tsx:180 — Im Zustand leer mit keineDateien === false, aber ohne Hinweise (das Backend liefert nur Namen, die der Parser verwirft), erscheint „Beachte die Hinweise …“ ohne Hinweise. Vorschlag: keineDateien daran festmachen, dass ergebnis.hinweise leer ist.)
  • Review-Hinweis (minor: core/importieren/markdown.ts:40 — Schließende #-Zeichen einer ATX-Überschrift (# Ankunft #) landen im Titel. Vorschlag: /\s+#+\s*$/ vom Titel entfernen.)
  • Review-Hinweis (minor: docs/handbuch.md:175 — Das Handbuch nennt noch „Word-Datei importieren …“ und beschreibt den Ordnerimport nicht. Vorschlag: Eintrag auf „Importieren …“ mit Quellenwahl Word/Ordner ändern.)
  • Review-Hinweis (minor: docs/issue-14-handover.md:1 — Die Übergabenotiz liegt als Datei im Repo. Vorschlag: Inhalt in die PR-Beschreibung übernehmen und die Datei nicht committen.)
  • Review-Hinweis (minor: src-tauri/src/extern_dateien.rs:50 — Die Rust-Formatierung ist nicht durch rustfmt bestätigt (laut Handover), und cargo test/clippy sind nicht gelaufen. Vor dem Merge auf dem Mac bzw. in der macOS-CI ausführen. Das ist kein Mangel am Code, nur ein noch fehlender Nachweis.)

Closes #14

…bare Lösung.

Lies zuerst den vollständigen Issue-Thread inklusive aller Kommentare, CLAUDE.md und die relevanten Repository-Regeln. Prüfe vorhandene PRs und aktuellen Code, bevor du Änderungen machst. Leite die verbindlichen Akzeptanzkriterien aus dem Issue ab und dokumentiere nicht erfüllbare oder widersprüchliche Kriterien klar.

Arbeite testgetrieben: Erzeuge Regressionstests, verifiziere ihr korrektes Fehlschlagen vor dem Fix und führe danach die relevanten Tests sowie die vorgeschriebenen Qualitätsprüfungen aus. Ändere nur, was für das Issue erforderlich ist. Arbeite ausschließlich auf dem ausgecheckten Stand von origin/main: checke keine Branches fremder offener PRs aus, cherry-picke nichts daraus und baue nicht auf ihnen auf. Hängt die Lösung von einem noch offenen PR ab, liefere nur deinen eigenen Anteil und dokumentiere die Abhängigkeit im Handover. Keine Produktionsdeployments, keine Änderungen an Produktionsdaten oder Produktions-Supabase und kein --prod. Merge den PR nicht.

Issue: #14
Titel: [Agent] Import eines Ordners mit Markdown- oder Textdateien

Beschreibung:
<!-- hermes-agent-form-v1:start -->
## Ziel und Nutzen
Autorinnen aus Obsidian, iA Writer oder Texteditoren übernehmen einen Ordner mit .md/.markdown/.txt-Dateien als Kapitel in Plotwerk, ohne Umweg über Word.

## Ist-Zustand / Problem
Der Import kennt nur .docx (dateiWaehlen(['docx']) und importiereDocx in ImportDialog.tsx:98-102). Das Menü heißt „Word-Datei importieren …“ (menue.rs:102-107). Rust hat nur einen Datei-Dialog (datei_waehlen in extern_dateien.rs), keinen Ordner-Dialog. ImportErgebnis und importUebernehmen sind wiederverwendbar.

## Umfang (In Scope)
- Quellenwahl (Word / Ordner mit Markdown- oder Textdateien) im Import-Dialog; Menüeintrag „Importieren …“ in Ablage (DE/EN)
- Eine Datei pro Kapitel, natürliche Sortierung nach Dateiname
- Titel aus `# `-Überschrift am Dateianfang (nach Frontmatter), sonst Dateiname ohne Endung und führende Nummer; Titelüberschrift nicht doppelt
- Text unverändert (E7), YAML-Frontmatter nicht übernehmen, .txt-Absätze an Leerzeilen
- Ergebnis als ImportErgebnis in der vorhandenen Vorschau mit Hinweisen (leer, ohne Überschrift, nicht lesbar, Kodierung)
- Reiner Parser in core/ (Liste aus Name und Inhalt)
- Rust: Ordner-Dialog und Lesen (eine Ebene, nur genannte Endungen, versteckte Dateien und .DS_Store ignorieren), Backend-Interface, Tauri-Brücke, Demo-Backend
- Tests: Vitest Parser und UI (DE/EN), Rust-Unit-Tests

## Nicht Teil dieses Issues (Out of Scope)
- Scrivener-Import
- Unterordner als Akte oder Teile
- Bilder, Links und Anhänge
- Import eines bestehenden Plotwerk-Projektordners
- Export als Markdown-Ordner
- Aufteilung in mehrere PRs oder Pakete (Leon: alles in einem Lauf)

## Fachliche und UX-Entscheidungen
- Geklärt: E7, keine Typografie-Umwandlung
- Geklärt: E1, IDs über neueId
- Geklärt: Strukturhinweise über ImportErgebnis.hinweise (E10)
- Geklärt (Leon): alles in einem Lauf
- Geklärt (Leon): Menüeintrag „Importieren …“ mit Quellenwahl im Dialog
- Geklärt (Leon): nur Überschrift am Dateianfang (nach Frontmatter) zählt; spätere `# `-Überschrift bleibt im Text
- Annahme: UTF-8; nicht dekodierbare Dateien übersprungen und als Hinweis gemeldet
- Annahme: versteckte Dateien und .DS_Store werden ignoriert
- Annahme: Ziel wie beim Word-Import (aktuelles Projekt anhängen oder neues Projekt)
- Annahme: BOM entfernen, Zeilenenden unverändert lassen

## Prüfbare Akzeptanzkriterien
- AC-1: Wenn ich einen Ordner mit `01-ankunft.md`, `02-ebbe.md` und `10-flut.md` wähle, dann zeigt die Vorschau drei Kapitel in genau dieser Reihenfolge.
- AC-2: Beginnt eine Datei (nach optionalem Frontmatter und Leerzeilen) mit `# Ankunft`, dann heißt das Kapitel „Ankunft“, und die Überschrift steht nicht noch einmal im Text.
- AC-3: Ohne Überschrift am Dateianfang heißt das Kapitel nach dem Dateinamen ohne Endung und führende Nummer, die Vorschau zeigt dazu einen Hinweis, und eine spätere `# `-Überschrift bleibt unverändert im Text.
- AC-4: Der übernommene Text ist zeichengleich zum Dateiinhalt ohne Titelzeile und Frontmatter. `"` und `--` bleiben unverändert.
- AC-5: `.txt`-Dateien werden an Leerzeilen in Absätze geteilt.
- AC-6: Leere oder nicht lesbare Dateien erscheinen als Hinweis, der Rest wird importiert.
- AC-7: Ordner ohne `.md`, `.markdown` oder `.txt` zeigen einen leeren Zustand in DE und EN.
- AC-8: Rust liest nur eine Ebene, nur die genannten Endungen, ignoriert versteckte Dateien und `.DS_Store`, und hat Unit-Tests dafür. Das Menü „Ablage“ enthält „Importieren …“ (DE/EN), und der Dialog bietet die Quellenwahl Word oder Ordner.

## QS und Nachweis
- Vitest-Parser in core/: Sortierung, Titel, Frontmatter, .txt-Absätze, unveränderter Text, Hinweise, BOM/CRLF
- UI-Tests im Stil von importexport.test.tsx und importexport.en.test.tsx mit gemocktem Backend, inkl. Quellenwahl und leerem Zustand
- Rust-Unit-Tests für Ordner-Lesen und Endungsfilter (cargo test in der macOS-CI)
- npm test, npm run typecheck und npm run build grün
- npm run sperrliste ohne Treffer
- Manuell auf dem Mac: Obsidian-Ordner und .txt-Ordner, jeweils neues und bestehendes Projekt

## Offene Fragen
–

_Automatisch nach dem Formular „Agent-Auftrag“ strukturiert (Hermes-Triage). Die ursprüngliche Beschreibung steht unten unverändert._
<!-- hermes-agent-form-v1:end -->

<details><summary>Ursprüngliche Beschreibung</summary>

<!-- hermes-original:start -->
### Ziel und Nutzen

Als Autorin, die bisher in Obsidian, iA Writer oder einem Texteditor geschrieben hat, möchte ich einen Ordner mit Markdown- oder Textdateien als Kapitel importieren, damit ich mein Manuskript ohne Umweg über Word in Plotwerk übernehmen kann.

### Ist-Zustand / Problem

- Der Import kennt nur `.docx`: `dateiWaehlen(['docx'])` und `importiereDocx` in `src/features/importexport/ImportDialog.tsx:98-102`.
- Das Menü heißt „Word-Datei importieren …“ (`src-tauri/src/menue.rs:102-107`, Text in Zeile 105).
- Der Rust-Kern kann nur einzelne Dateien wählen (`datei_waehlen`, `src-tauri/src/extern_dateien.rs:60-96`). Einen Ordner-Dialog gibt es nicht.
- Die Import-Vorschau arbeitet mit `ImportErgebnis` (Kapitel mit Titel und Markdown-Text, Hinweise, Vorspann; `core/docx/importieren.ts:12-56`) und `importUebernehmen` (`src/state/slices/importexport.ts:84`). Das lässt sich für andere Quellen nutzen.

### Umfang (In Scope)

- Neue Import-Quelle „Ordner mit Markdown- oder Textdateien“ (`.md`, `.markdown`, `.txt`) im Import-Dialog und im Menü „Ablage“ (DE/EN).
- Eine Datei pro Kapitel, sortiert nach Dateiname mit natürlicher Zahlensortierung (`2-…` vor `10-…`).
- Kapiteltitel: erste Überschrift `# …` der Datei, sonst der Dateiname ohne Endung und ohne führende Nummer. Die als Titel genutzte Überschrift wird nicht doppelt in den Text übernommen.
- Text unverändert übernehmen (E7). `.txt`: Absätze an Leerzeilen.
- Vorhandenes YAML-Frontmatter in den Dateien wird nicht in den Kapiteltext übernommen.
- Ergebnis als `ImportErgebnis`, angezeigt in der vorhandenen Import-Vorschau mit Hinweisen (leere Datei, Datei ohne Überschrift, nicht lesbare Datei, Kodierung).
- Parser als reine Funktion in `core/` (z. B. `core/importieren/markdown.ts`), Eingabe: Liste von Dateiname und Inhalt.
- Rust: Ordner-Dialog und Lesen der Dateien im gewählten Ordner (nur eine Ebene, nur die genannten Endungen), nach dem Muster von `extern_dateien.rs`.

### Nicht Teil dieses Issues (Out of Scope)

- Scrivener-Import (eigenes Issue, baut hierauf auf).
- Unterordner als Akte oder Teile.
- Bilder, Links und Anhänge aus den Dateien übernehmen.
- Import eines bestehenden Plotwerk-Projektordners.
- Rückweg (Export als Markdown-Ordner).

### Fachliche und UX-Entscheidungen

- Geklärt (Code): E7: Import und Laden ändern keinen Text, also keine Typografie-Umwandlung (`docs/architektur.md:17`). Das gilt auch für Anführungszeichen und Striche.
- Geklärt (Code): E1: Neue Kapitel bekommen IDs über `neueId` wie beim Word-Import (`src/state/slices/importexport.ts:101`).
- Geklärt (Code): Struktur-Hinweise beim Import gibt es schon (E10, `ImportErgebnis.hinweise`).
- Annahme: Erwartete Kodierung ist UTF-8. Nicht dekodierbare Dateien werden übersprungen und als Hinweis gemeldet.
- Annahme: Versteckte Dateien (`.…`) und `.DS_Store` werden ignoriert.
- Annahme: Ziel wie beim Word-Import: aktuelles Projekt (hinten anhängen) oder neues Projekt.
- Leerer Zustand: Ein Ordner ohne passende Dateien zeigt einen Hinweis und keine Vorschau.
- Fehlerfall: Eine nicht lesbare Datei bricht den Import nicht ab. Sie fehlt in der Vorschau und steht als Hinweis drin.

### Prüfbare Akzeptanzkriterien

AC-1: Wenn ich einen Ordner mit `01-ankunft.md`, `02-ebbe.md` und `10-flut.md` wähle, dann zeigt die Vorschau drei Kapitel in genau dieser Reihenfolge.
AC-2: Hat eine Datei die Überschrift `# Ankunft`, dann heißt das Kapitel „Ankunft“, und die Überschrift steht nicht noch einmal im Text.
AC-3: Ohne Überschrift heißt das Kapitel nach dem Dateinamen ohne Endung und Nummer, und die Vorschau zeigt dazu einen Hinweis.
AC-4: Der übernommene Text ist zeichengleich zum Dateiinhalt ohne Titelzeile und Frontmatter. `"` und `--` bleiben unverändert.
AC-5: `.txt`-Dateien werden an Leerzeilen in Absätze geteilt.
AC-6: Leere oder nicht lesbare Dateien erscheinen als Hinweis, der Rest wird importiert.
AC-7: Ordner ohne `.md`, `.markdown` oder `.txt` zeigen einen leeren Zustand in DE und EN.

### QS und Nachweis

- Agent: Vitest für den Parser in `core/` (Sortierung, Titel, Frontmatter, `.txt`-Absätze, unveränderter Text, Hinweise). UI-Test im Stil von `src/features/importexport/importexport.test.tsx` und `importexport.en.test.tsx` mit gemocktem Backend. Rust-Unit-Tests für Ordner-Lesen und Endungsfilter; `cargo test` läuft in der CI auf macOS. `npm test`, `npm run typecheck` und `npm run build` grün.
- Manuell auf dem Mac: einen Obsidian-Ordner und einen Ordner mit `.txt`-Dateien importieren, neues Projekt und bestehendes Projekt.

### Technischer Kontext und Referenzen

- Relevante Dateien: `src/features/importexport/ImportDialog.tsx`, `src/state/slices/importexport.ts`, `core/docx/importieren.ts` (`ImportErgebnis`), `src/backend/types.ts`, `src/backend/demo.ts`, `src-tauri/src/extern_dateien.rs`, `src-tauri/src/menue.rs`.
- Architektur: E1, E7, E10 in `docs/architektur.md`.
- Verwandt: Issue zum Import aus Scrivener 3, das auf diesem Import aufbaut.

### Sicherheits- und Liefergrenzen

- [X] Das Issue enthält keine Secrets, Tokens, Zugangsdaten oder vertraulichen Manuskript- und Kundendaten.
- [X] Der Agent darf Code und Tests ändern sowie einen Draft-PR öffnen, aber nicht selbst mergen, releasen oder deployen.
- [X] Änderungen an produktiver Infrastruktur oder veröffentlichten Releases sind nicht Teil dieses Auftrags.

_Angelegt von Claude Code im Auftrag von @leonatwork auf Basis einer Code-Analyse (Stand 2026-10-20)._
<!-- hermes-original:end -->

</details>

Zusätzliche Repo-Regeln:
Commits tragen ein DCO-Sign-off (das macht dev-loop automatisch). Auf diesem Server gibt es kein Rust/Tauri: nur TypeScript-Teil (core/, src/) mit npm run build und npm test prüfen, src-tauri nicht bauen. Keine Inhalte aus privaten Manuskripten; Beispiele nur aus fixtures/. Farben nur über Tokens in src/theme/tokens.css, UI nach docs/design/screens, core/ bleibt reines TypeScript, core/ki nutzt nur ProjektLeser.

Reviewer verdict: APPROVE after 1 round(s). Generated by dev-loop (not pushed).

Signed-off-by: leonatwork <leon.11@live.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Agent] Import eines Ordners mit Markdown- oder Textdateien

1 participant