Skip to content

agent: #10 [Agent] Suchen und Ersetzen im Kapitel und im ganzen Projekt - #24

Closed
leonatwork wants to merge 1 commit into
mainfrom
agent/bearbeite-github-issue-10-vollst-ndig-un-1020-1348
Closed

leonatwork wants to merge 1 commit into
mainfrom
agent/bearbeite-github-issue-10-vollst-ndig-un-1020-1348

Conversation

@leonatwork

Copy link
Copy Markdown
Owner

Zusammenfassung

Autonome Umsetzung von #10: [Agent] Suchen und Ersetzen im Kapitel und im ganzen Projekt

Verifikation

  • Coder-/Reviewer-Loop: APPROVE nach 2 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): 10,4 Mio Tokens · 3,58 €

Hinweise der Qualitätsprüfung

  • Review-Hinweis (minor: src/state/slices/suche.ts:136-140: Undo of a title group rewrites manuskript/<id>.md without taking a snapshot first. Undo only puts the title back, but for consistency with AC-4 you could optionally take a snapshot here (schnappschuss(kapitelPfad(id),'ersetzen')).)

Closes #10

…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: #10
Titel: [Agent] Suchen und Ersetzen im Kapitel und im ganzen Projekt

Beschreibung:
<!-- hermes-agent-form-v1:start -->
## Ziel und Nutzen
Autorin kann im aktuellen Kapitel und im ganzen Projekt (Manuskript, alle Plan-Textfelder, alle Notizen inkl. privater) Text suchen und gezielt ersetzen, mit Schnappschuss-Sicherheitsnetz für Kapitel und App-Undo für Plan und Notizen.

## Ist-Zustand / Problem
Nur Schnellsuche (⌘K) für Kapitel, Figuren, Orte, Bereiche und Befehle. Kein Volltext im Manuskript, keine Such-Erweiterung im Editor, keine Such- und Ersetzlogik in core, kein Menüeintrag. ⌘⇧F ist Fokus-Modus, ⌘F in der Recherche belegt. Schnappschüsse gibt es nur für Manuskriptkapitel, kein Undo für Projektdaten.

## Umfang (In Scope)
- Suchleiste im Schreiben-Bereich (⌘F): Markierung, vor/zurück, Trefferzahl
- Projektsuche (⌥⌘F) mit Ergebnisliste nach Bereich getrennt, Manuskript in Buchreihenfolge
- Ersetzen einzeln und Alle ersetzen, im Kapitel und im Projekt, auch in Plan-Textfeldern und Notizen inkl. privater
- Optionen Ganzes Wort und Groß-/Kleinschreibung
- Schnappschuss je betroffenem Kapitel vor dem Ersetzen
- Rückfrage vor Alle ersetzen im Projekt plus App-Undo der ganzen Aktion für Plan und Notizen
- Statistik: nur stand nachführen, Zählregel in docs/architektur.md ergänzen
- Menüeinträge DE/EN, i18n, Handbuch-Kürzeltabelle
- Reine Logik in core/suche/

## Nicht Teil dieses Issues (Out of Scope)
- Reguläre Ausdrücke
- Änderungen an der Schnellsuche (⌘K)
- Suche in Schnappschüssen und Fassungen
- KI-Vorschläge zum Ersetzen
- Recherche-Suche (bleibt ⌘F in der Recherche)

## Fachliche und UX-Entscheidungen
- Geklärt: Alles in einem Lauf (Leon)
- Geklärt: Projektsuche ⌥⌘F, Fokus-Modus bleibt ⌘⇧F (Leon)
- Geklärt: Ersetzen auch in Planfeldern und Notizen, alle Textfelder inkl. private (Leon)
- Geklärt: Private Notizen erscheinen in Trefferlisten und beim Ersetzen, bleiben lokal (Leon)
- Geklärt: Sicherheitsnetz für Plan und Notizen = Rückfrage plus App-Undo der ganzen Aktion (Leon)
- Geklärt: Ersetzungstext wörtlich, keine Typografie-Regel (E7)
- Geklärt: Ersetzen zählt nicht als geschrieben, nur stand
- Geklärt: SchnappschussAnlass additiv erweitern
- Geklärt: Textanker werden neu gesucht, sonst verwaist
- Geklärt: keine regulären Ausdrücke (vorläufig)
- Annahme: Unicode-Wortgrenzen, Groß-/Kleinschreibung ignorieren als Standard, Suche je Absatz
- Annahme: App-Undo nur In-Memory für die letzte Aktion

## Prüfbare Akzeptanzkriterien
- AC-1: Wenn ich im Bereich „Schreiben“ ⌘F drücke und einen Begriff eingebe, dann sind alle Treffer im aktuellen Kapitel markiert, die Leiste zeigt die Trefferzahl, und Enter springt zum nächsten Treffer.
- AC-2: Wenn ich in der Projektsuche (⌥⌘F) einen Begriff suche, dann zeigt die Liste jeden Manuskript-Treffer mit Kapitelnummer, Kapiteltitel und Kontext in Buchreihenfolge. Ein Klick öffnet das Kapitel an dieser Stelle.
- AC-3: Mit „Ganzes Wort“ trifft „Ole“ nicht „Oleander“. Mit „Groß- und Kleinschreibung beachten“ trifft „hafen“ nicht „Hafen“.
- AC-4: Wenn ich „Alle ersetzen“ im Projekt bestätige, dann liegt vorher für jedes betroffene Kapitel ein neuer Schnappschuss in `.versionen/`. Kapitel ohne Treffer werden nicht neu geschrieben.
- AC-5: Nach einem Ersetzen ändert sich der Wert `geschrieben` des Tages in `statistik.json` nicht; nur `stand` folgt.
- AC-6: Der Ersetzungstext wird wörtlich eingefügt. Ein `"` darin wird nicht zu „ oder “.
- AC-7: Bei leerer Suche oder ohne Treffer sind „Ersetzen“ und „Alle ersetzen“ deaktiviert, und ein leerer Zustand erscheint in DE und EN.
- AC-8: Fehlerfall: Schlägt der Schnappschuss eines Kapitels fehl, bleibt dieses Kapitel unverändert, und eine Meldung nennt es.
- AC-9: Die Projektsuche findet und ersetzt auch in allen Plan-Textfeldern und allen Notizen (inkl. privater, z. B. `notizen` bei Figur und Ort). Die Treffer sind nach Bereich getrennt aufgeführt. „Alle ersetzen“ in Plan und Notizen fragt vorher nach und lässt sich als ganze Aktion per App-Undo zurücknehmen; beides ist getestet.

## QS und Nachweis
- Vitest in core/suche: Wortgrenzen, Case, Kontext, Markdown, mehrere Treffer je Absatz, Plan/Notizen
- UI-Tests im Stil von Editor.test.tsx und schreiben.en.test.tsx gegen das Demo-Projekt
- Test in src/app/app.test.tsx für ⌥⌘F ohne Kollision
- Test, dass core/suche und die Projektsuche keinen Pfad zu core/ki schaffen
- Test für App-Undo der ganzen Ersetzen-Aktion in Plan und Notizen
- npm test, npm run typecheck, npm run build, npm run sperrliste grün
- Rust-Menü: cargo test in der macOS-CI
- Manuell auf dem Mac: Menü DE/EN, Kürzel, Alle ersetzen im Demo-Projekt Hafenlichter, Rückkehr über Versionsverlauf

## 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 möchte ich im aktuellen Kapitel und im ganzen Manuskript nach Text suchen und ihn gezielt ersetzen, damit ich etwa einen Figurennamen oder eine Schreibweise sicher im ganzen Buch ändern kann.

### Ist-Zustand / Problem

- Es gibt nur die Schnellsuche (⌘K). Sie findet Kapitel, Figuren, Orte, Bereiche und Befehle, aber keinen Text im Manuskript: Trefferarten in `src/app/suche.ts:10`, Funktion `suche` in `src/app/suche.ts:91`.
- Das Menü „Bearbeiten“ hat keinen Eintrag „Suchen“ oder „Ersetzen“, nur „Schnellsuche …“ (`src-tauri/src/menue.rs:166-181`).
- Der Editor hat keine Such-Erweiterung (`src/features/schreiben/Editor.tsx:307-324`, `useEditor`). Im Repo gibt es keine Such- oder Ersetzen-Logik für Manuskripttext.
- Kürzel-Kollision: ⌘⇧F ist schon der Fokus-Modus (`src-tauri/src/menue.rs:207-212`, `src/app/befehle.ts:165`, `src/app/app.test.tsx:13`, `docs/handbuch.md:188`). ⌘F ist in der Recherche schon die Suche (`docs/handbuch.md:146,195`, `src/i18n/de/recherche.ts:28`).

### Umfang (In Scope)

- Suchleiste im Bereich „Schreiben“ (⌘F): Treffer im aktuellen Kapitel hervorheben, vor und zurück springen, Trefferzahl anzeigen.
- Projektsuche (Kürzel siehe Offen): Ergebnisliste über alle Kapitel in Buchreihenfolge. Je Treffer Kapitelnummer, Kapiteltitel und Kontext. Ein Klick öffnet das Kapitel an der Stelle.
- Ersetzen: einzeln und „Alle ersetzen“, im Kapitel und im Projekt.
- Optionen „Ganzes Wort“ und „Groß- und Kleinschreibung beachten“.
- Vor dem Ersetzen einen Schnappschuss jedes betroffenen Kapitels anlegen (`schnappschuss` aus `core/projekt`, Ablage `.versionen/`, E8).
- Ersetzen zählt nicht als geschriebene Wörter. Die Statistik führt nur den `stand` nach.
- Menüeinträge in „Bearbeiten“ (DE/EN), Texte in `src/i18n/{de,en}`, Tastenkürzel-Tabelle in `docs/handbuch.md`.
- Such- und Ersetzlogik als reine Funktionen in `core/` (z. B. neues Modul `core/suche/`), ohne DOM.

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

- Reguläre Ausdrücke (siehe Offen).
- Suchen und Ersetzen in Planfeldern, Notizen, Figuren, Orten und Recherche (siehe Offen).
- Änderungen an der Schnellsuche (⌘K).
- Suche in Schnappschüssen und Fassungen.
- Jede Form von KI-Vorschlag zum Ersetzen („Die KI liest mit, schreibt aber nie.“).

### Fachliche und UX-Entscheidungen

- Geklärt (Code): Typografie gibt es nur beim Tippen (E7, `docs/architektur.md:17`). Der Ersetzungstext wird wörtlich eingefügt, ohne Typografie-Regel.
- Geklärt (Code): Zählregel `docs/architektur.md:85-90`: Import, Wiederherstellen, Änderungen von außen und Rückimport führen nur den `stand` nach. Der Mechanismus existiert: `nurStand` in `bucheAenderung` (`core/statistik/index.ts:123-130`), im Store über `NICHT_ZAEHLEN` und `aussetzen` (`src/state/slices/statistik.ts:74,158-160`). Ersetzen kommt in diese Liste. Die Zählregel in `docs/architektur.md` wird ergänzt.
- Geklärt (Code): Schnappschüsse für Manuskriptdateien gibt es (`core/projekt`, `core/versionen`). `SchnappschussAnlass` (`core/versionen/index.ts:7`) darf additiv erweitert werden.
- Geklärt (Code): Textanker (E4) werden nach dem Ersetzen neu gesucht. Ist eine Stelle nicht mehr eindeutig, wird sie „verwaist“, nie still falsch.
- Annahme: „Ganzes Wort“ nutzt Unicode-Wortgrenzen wie die Namenserkennung (E5). „Ole“ trifft also nicht „Oleander“.
- Annahme: Standard ist „Groß- und Kleinschreibung ignorieren“, „Ganzes Wort“ aus.
- Annahme: Gesucht wird innerhalb eines Absatzes, nicht über Absatzgrenzen. Markdown-Auszeichnung (`*`, `_`) bleibt beim Ersetzen erhalten.
- Annahme: „Alle ersetzen“ im Projekt fragt vorher nach und nennt die Zahl der Treffer und Kapitel. Rückgängig geht über den Versionsverlauf; im offenen Kapitel zusätzlich mit ⌘Z.
- Fehlerfall: Lässt sich ein Schnappschuss nicht anlegen, wird dieses Kapitel nicht geändert. Die Meldung nennt das Kapitel.
- Leerer Zustand: Keine Eingabe oder keine Treffer zeigt einen Hinweis; Ersetzen ist deaktiviert.
- Offen (Leon): Sollen auch Planfelder (Kurzbeschreibung, Szenen) und Notizen ersetzt werden, oder nur der Manuskripttext?
- Offen (Leon): Soll es reguläre Ausdrücke geben?
- Offen (Leon): Welches Kürzel bekommt die Projektsuche? ⌘⇧F ist der Fokus-Modus. Vorschlag: ⌥⌘F für die Projektsuche, der Fokus-Modus bleibt auf ⌘⇧F. Oder soll der Fokus-Modus umziehen?

### Prüfbare Akzeptanzkriterien

AC-1: Wenn ich im Bereich „Schreiben“ ⌘F drücke und einen Begriff eingebe, dann sind alle Treffer im aktuellen Kapitel markiert, die Leiste zeigt die Trefferzahl, und Enter springt zum nächsten Treffer.
AC-2: Wenn ich in der Projektsuche einen Begriff suche, dann zeigt die Liste jeden Treffer mit Kapitelnummer, Kapiteltitel und Kontext in Buchreihenfolge. Ein Klick öffnet das Kapitel an dieser Stelle.
AC-3: Mit „Ganzes Wort“ trifft „Ole“ nicht „Oleander“. Mit „Groß- und Kleinschreibung beachten“ trifft „hafen“ nicht „Hafen“.
AC-4: Wenn ich „Alle ersetzen“ im Projekt bestätige, dann liegt vorher für jedes betroffene Kapitel ein neuer Schnappschuss in `.versionen/`. Kapitel ohne Treffer werden nicht neu geschrieben.
AC-5: Nach einem Ersetzen ändert sich der Wert `geschrieben` des Tages in `statistik.json` nicht; nur `stand` folgt.
AC-6: Der Ersetzungstext wird wörtlich eingefügt. Ein `"` darin wird nicht zu „ oder “.
AC-7: Bei leerer Suche oder ohne Treffer sind „Ersetzen“ und „Alle ersetzen“ deaktiviert, und ein leerer Zustand erscheint in DE und EN.
AC-8: Fehlerfall: Schlägt der Schnappschuss eines Kapitels fehl, bleibt dieses Kapitel unverändert, und eine Meldung nennt es.

### QS und Nachweis

- Agent: Vitest-Tests für die Such- und Ersetzlogik in `core/` (Wortgrenzen, Groß- und Kleinschreibung, Kontext, Markdown-Auszeichnung, mehrere Treffer je Absatz). UI-Tests im Stil von `src/features/schreiben/Editor.test.tsx` und `schreiben.en.test.tsx` gegen das Demo-Projekt (Markieren, Ersetzen, Schnappschuss, Statistik, Typografie). Test in `src/app/app.test.tsx` für das neue Kürzel ohne Kollision. `npm test`, `npm run typecheck` und `npm run build` grün. Die Menüänderung in Rust prüft `cargo test` in der CI auf macOS; der Agent-Server ist Linux und kann die Mac-App nicht bauen.
- Manuell auf dem Mac: Menü „Bearbeiten“ in DE und EN, Kürzel kollidieren nicht mit Fokus-Modus und Recherche-Suche, „Alle ersetzen“ im Demo-Projekt „Hafenlichter“ und Rückkehr über den Versionsverlauf.

### Technischer Kontext und Referenzen

- Relevante Dateien: `src/app/suche.ts`, `src/app/befehle.ts`, `src-tauri/src/menue.rs`, `src/features/schreiben/Editor.tsx`, `core/versionen/index.ts`, `core/statistik/index.ts`, `src/state/slices/statistik.ts`, `core/text/` (Klartext, Anker), `docs/handbuch.md`.
- Architektur: E4, E5, E7, E8 und Zählregel in `docs/architektur.md`.
- Verwandt: Issue zu „Kapitel teilen, zusammenführen und archivieren“ nutzt dieselbe Schnappschuss-Logik.

### 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 2 round(s). Generated by dev-loop (not pushed).

Signed-off-by: leonatwork <leon.11@live.de>
@leonatwork

Copy link
Copy Markdown
Owner Author

Duplikat zu PR #21 (gleiches Issue #10, ein späterer Neuversuch hat einen zweiten PR erzeugt). Geschlossen auf Anweisung des Inhabers; #21 bleibt der Kandidat.

@leonatwork leonatwork closed this Oct 21, 2026
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] Suchen und Ersetzen im Kapitel und im ganzen Projekt

1 participant