Write stable block-id links and always start the interview wizard.
New notes and workbench edges now emit [[Note#Heading ^block]] or [[#^id]] so vaults stay ingestible without mass relinks. Create-from-profile always opens the wizard; a command can restart it on the current note. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
c40a89096f
commit
56ae6a2407
|
|
@ -1,187 +1,110 @@
|
||||||
# Mindnet Causal Assistant - Dokumentations-Index
|
# Mindnet Causal Assistant – Dokumentations-Index
|
||||||
|
|
||||||
> **Version:** 1.0.0
|
> **Version:** 1.0.0
|
||||||
> **Stand:** 2025-01-XX
|
> **Stand:** Januar 2026
|
||||||
> **Vollständige Übersicht:** Alle Dokumentations-Dateien und deren Inhalte
|
> **Plugin:** Mindnet Causal Assistant (Obsidian)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Dokumentations-Struktur
|
## Übersicht
|
||||||
|
|
||||||
### Hauptdokumentation (nach Zielgruppe)
|
Die Dokumentation ist in **zwei Perspektiven** organisiert:
|
||||||
|
|
||||||
1. **[01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md)** - Endnutzer
|
1. **Nach Modul** – technische Inhalte nach Komponenten (Analysis, Interview, Mapping, usw.)
|
||||||
2. **[02_Administratorhandbuch.md](./02_Administratorhandbuch.md)** - Administratoren
|
2. **Nach Rolle** – gezielte Einstiege für Nutzer, Administratoren, Entwickler, Architekten, Projektleitung
|
||||||
3. **[03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md)** - Entwickler
|
|
||||||
4. **[04_Architektur.md](./04_Architektur.md)** - Architekten
|
|
||||||
5. **[05_Installation_Deployment.md](./05_Installation_Deployment.md)** - Installation
|
|
||||||
|
|
||||||
### Spezialisierte Referenzen
|
|
||||||
|
|
||||||
6. **[06_Konfigurationsdateien_Referenz.md](./06_Konfigurationsdateien_Referenz.md)** - Config-Dateien Format & Aufbau
|
|
||||||
7. **[Interview_Config_Guide.md](./Interview_Config_Guide.md)** - Vollständige Anleitung für `interview_config.yaml` (inkl. WP-26 Features, GenAI-freundlich)
|
|
||||||
8. **[07_Event_Handler_Commands.md](./07_Event_Handler_Commands.md)** - Event Handler & Commands
|
|
||||||
|
|
||||||
### WP-26 Integration (Section Types & Intra-Note-Edges)
|
|
||||||
|
|
||||||
9. **[06_LH_WP26_Plugin_Integration.md](./06_LH_WP26_Plugin_Integration.md)** - Lastenheft für WP-26 Plugin-Integration (vollständige Anforderungen)
|
|
||||||
10. **[WP26_Plugin_Interface_Specification.md](./WP26_Plugin_Interface_Specification.md)** - Vollständige Schnittstellenspezifikation für Plugin-Entwicklung
|
|
||||||
11. **[WP26_Implementation_Checklist.md](./WP26_Implementation_Checklist.md)** - Implementierungs-Checkliste mit Tasks und Phasen
|
|
||||||
|
|
||||||
### Chain Inspector Reports
|
|
||||||
|
|
||||||
- [CHAIN_INSPECTOR_V0_REPORT.md](./CHAIN_INSPECTOR_V0_REPORT.md) - v0.0 Implementierung
|
|
||||||
- [CHAIN_INSPECTOR_V02_REPORT.md](./CHAIN_INSPECTOR_V02_REPORT.md) - v0.2 Features
|
|
||||||
- [CHAIN_INSPECTOR_V03_REPORT.md](./CHAIN_INSPECTOR_V03_REPORT.md) - v0.3 Features
|
|
||||||
- [CHAIN_INSPECTOR_V04_REPORT.md](./CHAIN_INSPECTOR_V04_REPORT.md) - v0.4 Template Matching
|
|
||||||
- [CHAIN_INSPECTOR_V042_REPORT.md](./CHAIN_INSPECTOR_V042_REPORT.md) - v0.4.2 Updates
|
|
||||||
|
|
||||||
### Konzepte & Details
|
|
||||||
|
|
||||||
- [02_causal_chain_retrieving.md](./02_causal_chain_retrieving.md) - Kausale Ketten-Retrieval
|
|
||||||
- [DANGLING_TARGET_CASES.md](./DANGLING_TARGET_CASES.md) - Dangling Target Findings
|
|
||||||
|
|
||||||
### Legacy-Dokumentation
|
|
||||||
|
|
||||||
- [readme.md](./readme.md) - MVP 1.0 Quickstart
|
|
||||||
- [Handbuch.md](./Handbuch.md) - MVP 1.0 Handbuch
|
|
||||||
- [TESTING_WITH_REAL_VAULT.md](./TESTING_WITH_REAL_VAULT.md) - Testing mit echtem Vault
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Vollständigkeits-Checkliste
|
## Einstieg nach Rolle
|
||||||
|
|
||||||
### ✅ Module & Komponenten
|
| Rolle | Primäre Dokumente | Kurzbeschreibung |
|
||||||
|
|-------|-------------------|------------------|
|
||||||
- [x] **Analysis** (`src/analysis/`) - Chain Inspector, Template Matching, Graph Index, Section Context, Severity Policy
|
| **Nutzer** | [13_Erfassung_Causal_Ketten](13_Erfassung_Causal_Ketten.md), [01_Benutzerhandbuch](01_Benutzerhandbuch.md), [07_Event_Handler_Commands](07_Event_Handler_Commands.md) | Erfassung & Ketten, Installation, Commands, Troubleshooting |
|
||||||
- [x] **Commands** (`src/commands/`) - Inspect Chains, Fix Findings
|
| **Administrator** | [02_Administratorhandbuch](02_Administratorhandbuch.md), [06_Konfigurationsdateien_Referenz](06_Konfigurationsdateien_Referenz.md), [Interview_Config_Guide](Interview_Config_Guide.md) | Konfiguration, Pfade, Live-Reload, Wartung |
|
||||||
- [x] **Dictionary** (`src/dictionary/`) - Chain Roles Loader, Chain Templates Loader, Config Path Manager, Dictionary Loader, Parsers, Types
|
| **Entwickler** | [03_Entwicklerhandbuch](03_Entwicklerhandbuch.md), [04_Architektur](04_Architektur.md), [Module](modules/README.md) | Code-Struktur, Testing, Build, Erweiterungen |
|
||||||
- [x] **Entity Picker** (`src/entityPicker/`) - Note Index, Folder Tree, Filters, Wikilink
|
| **Architekt** | [04_Architektur](04_Architektur.md), [02_concepts/03_chain_identification_and_matching](02_concepts/03_chain_identification_and_matching.md) | System-Design, Datenfluss, Konzepte |
|
||||||
- [x] **Export** (`src/export/`) - Graph Export
|
| **Projektleitung** | [04_Architektur](04_Architektur.md), [README](../README.md), [STATUS_DOD](../STATUS_DOD.md) | Überblick, Scope, Definition of Done |
|
||||||
- [x] **Graph** (`src/graph/`) - Graph Builder, Graph Index, Render Chain Report, Resolve Target, Traverse
|
| **Systemadmin** | [05_Installation_Deployment](05_Installation_Deployment.md), [02_Administratorhandbuch](02_Administratorhandbuch.md) | Installation, Deployment, Umgebung |
|
||||||
- [x] **Interview** (`src/interview/`) - Config Loader, Parser, Wizard State, Loop State, Renderer, Write Frontmatter, Section Key Resolver, Extract Target, Slugify
|
|
||||||
- [x] **Lint** (`src/lint/`) - Lint Engine, Rules (Hub Has Causality, Missing Target, Unknown Edge)
|
|
||||||
- [x] **Mapping** (`src/mapping/`) - Semantic Mapping Builder, Mapping Extractor, Mapping Builder, Edge Type Selector, Update Mapping Blocks, Section Parser, Worklist Builder, Graph Schema, Schema Helper, Folder Helpers
|
|
||||||
- [x] **Parser** (`src/parser/`) - Parse Edges From Callouts, Parse Frontmatter, Parse Rel Links
|
|
||||||
- [x] **Schema** (`src/schema/`) - Graph Schema Loader
|
|
||||||
- [x] **UI** (`src/ui/`) - Alle Modals (Interview Wizard, Profile Selection, Edge Type Chooser, Entity Picker, Adopt Note, Folder Tree, Link Prompt, Inline Edge Type, Confirm Overwrite), Settings Tab, Markdown Toolbar, Mindnet View
|
|
||||||
- [x] **Unresolved Link** (`src/unresolvedLink/`) - Handler, Link Helpers, Adopt Helpers
|
|
||||||
- [x] **Vocabulary** (`src/vocab/`) - Vocabulary, Vocabulary Loader, Parse Edge Vocabulary
|
|
||||||
|
|
||||||
### ✅ Funktionen & Features
|
|
||||||
|
|
||||||
- [x] **Note-Erstellung** - Mit Profilen, Frontmatter-Generierung
|
|
||||||
- [x] **Interview-Wizard** - Steps, Loops, Nested Loops, Section-basierte Ausgabe
|
|
||||||
- [x] **Semantic Mapping** - Builder, Extractor, Edge Type Assignment
|
|
||||||
- [x] **Chain Inspector** - Template Matching, Findings Generation
|
|
||||||
- [x] **Fix Findings** - Automatische Behebung von Findings
|
|
||||||
- [x] **Unresolved Link Handling** - Reading View, Editor, Note Adoption
|
|
||||||
- [x] **Edge-Type-Änderung** - Kontext-Erkennung, Edge Type Selector
|
|
||||||
- [x] **Graph Export** - JSON-Export
|
|
||||||
- [x] **Linting** - Lint Engine mit Regeln
|
|
||||||
- [x] **Live-Reload** - Automatisches Neuladen von Config-Dateien
|
|
||||||
|
|
||||||
### ✅ Commands
|
|
||||||
|
|
||||||
- [x] `mindnet-reload-edge-vocabulary` - Edge Vocabulary neu laden
|
|
||||||
- [x] `mindnet-validate-current-note` - Note validieren (Lint)
|
|
||||||
- [x] `mindnet-export-graph` - Graph exportieren
|
|
||||||
- [x] `mindnet-show-chains-from-current-note` - Ketten von aktueller Note zeigen
|
|
||||||
- [x] `mindnet-create-note-from-profile` - Note mit Profil erstellen
|
|
||||||
- [x] `mindnet-change-edge-type` - Edge-Type ändern
|
|
||||||
- [x] `mindnet-debug-chain-roles` - Chain Roles Debug-Info
|
|
||||||
- [x] `mindnet-debug-chain-templates` - Chain Templates Debug-Info
|
|
||||||
- [x] `mindnet-fix-findings` - Findings beheben
|
|
||||||
- [x] `mindnet-inspect-chains` - Chains analysieren
|
|
||||||
- [x] `mindnet-build-semantic-mappings` - Semantic Mapping Blöcke bauen
|
|
||||||
|
|
||||||
### ✅ Event Handler
|
|
||||||
|
|
||||||
- [x] **Vault Modify Event** - Live-Reload von Config-Dateien
|
|
||||||
- [x] **Vault Create Event** - Note Adoption
|
|
||||||
- [x] **Markdown Post Processor** - Unresolved Link Handling (Reading View)
|
|
||||||
- [x] **DOM Click Event** - Unresolved Link Handling (Editor)
|
|
||||||
|
|
||||||
### ✅ Settings
|
|
||||||
|
|
||||||
- [x] **Pfad-Settings** (6) - Alle Config-Datei-Pfade
|
|
||||||
- [x] **Graph & Chain Settings** (4) - maxHops, strictMode, showCanonicalHints, chainDirection
|
|
||||||
- [x] **Interview Settings** (1) - autoStartInterviewOnCreate
|
|
||||||
- [x] **Unresolved Link Settings** (6) - interceptUnresolvedLinkClicks, autoStartOnUnresolvedClick, bypassModifier, editorFollowModifier, waitForFirstModifyAfterCreate, waitForModifyTimeoutMs, debugLogging
|
|
||||||
- [x] **Note Adoption Settings** (4) - adoptNewNotesInEditor, adoptMaxChars, adoptConfirmMode, highConfidenceWindowMs
|
|
||||||
- [x] **Semantic Mapping Settings** (6) - mappingWrapperCalloutType, mappingWrapperTitle, mappingWrapperFolded, defaultEdgeType, unassignedHandling, allowOverwriteExistingMappings, defaultNotesFolder
|
|
||||||
- [x] **Inline Micro Edge Suggester Settings** (3) - inlineMicroEnabled, inlineMaxAlternatives, inlineCancelBehavior
|
|
||||||
- [x] **Export Settings** (1) - exportPath
|
|
||||||
- [x] **Chain Inspector Settings** (3) - chainInspectorIncludeCandidates, chainInspectorMaxTemplateMatches, templateMatchingProfile
|
|
||||||
- [x] **Fix Actions Settings** (5) - createMissingNote (mode, defaultTypeStrategy, includeZones), createMissingHeading (level), promoteCandidate (keepOriginal)
|
|
||||||
|
|
||||||
### ✅ Konfigurationsdateien
|
|
||||||
|
|
||||||
- [x] **edge_vocabulary.md** - Format, Parsing-Regeln, Beispiel
|
|
||||||
- [x] **graph_schema.md** - Format, Parsing-Regeln, Beispiel
|
|
||||||
- [x] **interview_config.yaml** - Format, Felder, Beispiel (Profile, Steps, Loops) - **Siehe auch:** [Interview_Config_Guide.md](./Interview_Config_Guide.md) für vollständige Anleitung
|
|
||||||
- [x] **chain_roles.yaml** - Format, Felder, Beispiel (Roles, Edge Types)
|
|
||||||
- [x] **chain_templates.yaml** - Format, Felder, Beispiel (Templates, Slots, Links, Defaults, Profiles)
|
|
||||||
- [x] **analysis_policies.yaml** - Geplante Struktur (noch nicht vollständig implementiert)
|
|
||||||
|
|
||||||
### ✅ Wirkungsweise
|
|
||||||
|
|
||||||
- [x] **Live-Reload** - Debounced (200ms), Last-Known-Good Fallback
|
|
||||||
- [x] **Config-Loading** - YAML/Markdown Parsing, Error Handling
|
|
||||||
- [x] **Template Matching** - Slot-basiertes Matching, Link Constraints
|
|
||||||
- [x] **Findings Generation** - Gap-Heuristiken, Severity-Policy
|
|
||||||
- [x] **Note Adoption** - Confidence-Evaluation, Adoption-Flow
|
|
||||||
- [x] **Unresolved Link Handling** - Reading View vs Editor, Modifier-Keys
|
|
||||||
- [x] **Semantic Mapping** - Section-Parsing, Link-Extraktion, Edge-Type-Assignment
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Dokumentations-Abdeckung
|
## Einstieg nach Modul
|
||||||
|
|
||||||
### Vollständig dokumentiert
|
| Modul | Pfad | Beschreibung |
|
||||||
|
|-------|------|--------------|
|
||||||
✅ **Alle Module** - Alle 14 Hauptmodule sind dokumentiert
|
| **Analysis** | [modules/analysis](modules/analysis.md) | Chain Inspector, Template Matching, Scoring, Findings |
|
||||||
✅ **Alle Commands** - Alle 11 Commands sind dokumentiert
|
| **Dictionary** | [modules/dictionary](modules/dictionary.md) | Config-Loader, Chain Roles, Chain Templates, Dictionary |
|
||||||
✅ **Alle Event Handler** - Alle 4 Event Handler sind dokumentiert
|
| **Interview** | [modules/interview](modules/interview.md) | Wizard, Loop State, Renderer, Section Key Resolver |
|
||||||
✅ **Alle Settings** - Alle 40+ Settings sind dokumentiert
|
| **Mapping** | [modules/mapping](modules/mapping.md) | Semantic Mapping, Edge Type Selector, Update Mapping Blocks |
|
||||||
✅ **Alle Config-Dateien** - Alle 6 Config-Dateien sind dokumentiert
|
| **Parser** | [modules/parser](modules/parser.md) | Edges aus Callouts, Frontmatter, Links |
|
||||||
✅ **Wirkungsweise** - Alle Hauptfunktionen sind beschrieben
|
| **Graph** | [modules/graph](modules/graph.md) | Graph Builder, Traversal, Resolution, Export |
|
||||||
✅ **Konfiguration** - Format und Aufbau aller Config-Dateien sind dokumentiert
|
| **Vocabulary** | [modules/vocabulary](modules/vocabulary.md) | Edge Vocabulary, Normalisierung, Aliases |
|
||||||
|
| **Unresolved Link** | [modules/unresolvedLink](modules/unresolvedLink.md) | Link-Handler, Adoption, Heading-Normalisierung |
|
||||||
### Teilweise dokumentiert
|
| **Workbench** | [modules/workbench](modules/workbench.md) | Chain Workbench, Todo-Generator, Status, Actions |
|
||||||
|
| **Lint** | [modules/lint](modules/lint.md) | Lint Engine, Rules, Findings |
|
||||||
⚠️ **Analysis Policies** - Erwähnt, aber noch nicht vollständig implementiert
|
| **UI** | [modules/ui](modules/ui.md) | Modals, Settings Tab, Entity Picker |
|
||||||
⚠️ **Einige UI-Komponenten** - Basis-Funktionalität dokumentiert, Details könnten erweitert werden
|
|
||||||
|
|
||||||
### Nicht dokumentiert (nicht vorhanden oder nicht relevant)
|
|
||||||
|
|
||||||
- **Tests** - Test-Dateien sind nicht Teil der Benutzer-Dokumentation
|
|
||||||
- **Mocks** - Mock-Dateien sind nicht Teil der Benutzer-Dokumentation
|
|
||||||
- **Build-Scripts** - Build-Scripts sind in Entwicklerhandbuch dokumentiert
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Schnellzugriff nach Thema
|
## Kern-Dokumente
|
||||||
|
|
||||||
### Installation & Setup
|
### Nutzung & Konfiguration
|
||||||
→ [05_Installation_Deployment.md](./05_Installation_Deployment.md)
|
|
||||||
|
|
||||||
### Konfiguration
|
- [13_Erfassung_Causal_Ketten](13_Erfassung_Causal_Ketten.md) – **Praxis-Handbuch:** Elemente erfassen und Causal-Ketten schließen
|
||||||
→ [02_Administratorhandbuch.md](./02_Administratorhandbuch.md)
|
- [01_Benutzerhandbuch](01_Benutzerhandbuch.md) – Endnutzer-Workflows, Commands, Einstellungen
|
||||||
→ [06_Konfigurationsdateien_Referenz.md](./06_Konfigurationsdateien_Referenz.md)
|
- [07_Event_Handler_Commands](07_Event_Handler_Commands.md) – alle Commands und Event-Handler
|
||||||
→ [Interview_Config_Guide.md](./Interview_Config_Guide.md) - Interview-Profile erstellen (GenAI-freundlich)
|
- [02_Administratorhandbuch](02_Administratorhandbuch.md) – Plugin-Konfiguration, Pfade, Wartung
|
||||||
|
- [06_Konfigurationsdateien_Referenz](06_Konfigurationsdateien_Referenz.md) – Format aller Config-Dateien, Gewichtung, Analysis Policies
|
||||||
|
- [Interview_Config_Guide](Interview_Config_Guide.md) – interview_config.yaml (Profile, Steps, Loops, WP-26)
|
||||||
|
|
||||||
### Nutzung
|
### Technik & Konzepte
|
||||||
→ [01_Benutzerhandbuch.md](./01_Benutzerhandbuch.md)
|
|
||||||
→ [07_Event_Handler_Commands.md](./07_Event_Handler_Commands.md)
|
|
||||||
|
|
||||||
### Entwicklung
|
- [04_Architektur](04_Architektur.md) – System-Design, Komponenten, Datenfluss
|
||||||
→ [03_Entwicklerhandbuch.md](./03_Entwicklerhandbuch.md)
|
- [03_Entwicklerhandbuch](03_Entwicklerhandbuch.md) – Projekt-Struktur, Build, Testing
|
||||||
→ [04_Architektur.md](./04_Architektur.md)
|
- [02_concepts/03_chain_identification_and_matching](02_concepts/03_chain_identification_and_matching.md) – Template Matching, Scoring, Confidence
|
||||||
|
- [02_causal_chain_retrieving](02_causal_chain_retrieving.md) – Kausale Ketten-Retrieval
|
||||||
|
|
||||||
### WP-26 Integration
|
### Operation & Deployment
|
||||||
→ [WP26_Plugin_Interface_Specification.md](./WP26_Plugin_Interface_Specification.md)
|
|
||||||
→ [WP26_Implementation_Checklist.md](./WP26_Implementation_Checklist.md)
|
- [05_Installation_Deployment](05_Installation_Deployment.md) – Installation, Deployment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spezialthemen
|
||||||
|
|
||||||
|
- [12_Heading_Block_Link_Recommendation](12_Heading_Block_Link_Recommendation.md) – Überschrift vs. Block-Link, Normalisierung, Obsidian-Verhalten
|
||||||
|
- [09_Workbench_Analysis_Basis](09_Workbench_Analysis_Basis.md) – Workbench-Analyse
|
||||||
|
- [10_Workbench_Findings_Integration](10_Workbench_Findings_Integration.md) – Findings-Integration
|
||||||
|
- [DANGLING_TARGET_CASES](DANGLING_TARGET_CASES.md) – Dangling-Target-Fälle
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WP-26 Integration
|
||||||
|
|
||||||
|
- [06_LH_WP26_Plugin_Integration](06_LH_WP26_Plugin_Integration.md) – Lastenheft für WP-26 Plugin-Integration
|
||||||
|
- [WP26_Plugin_Interface_Specification](WP26_Plugin_Interface_Specification.md) – Schnittstellenspezifikation
|
||||||
|
- [WP26_Implementation_Checklist](WP26_Implementation_Checklist.md) – Implementierungs-Checkliste
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Reports & Archive
|
||||||
|
|
||||||
|
- [CHAIN_INSPECTOR_V042_REPORT](CHAIN_INSPECTOR_V042_REPORT.md) – aktuellster Chain Inspector Report
|
||||||
|
- Weitere Reports: [CHAIN_INSPECTOR_V0_REPORT](CHAIN_INSPECTOR_V0_REPORT.md) … [CHAIN_INSPECTOR_V04_REPORT](CHAIN_INSPECTOR_V04_REPORT.md)
|
||||||
|
- Legacy: [readme](readme.md), [Handbuch](Handbuch.md), [TESTING_WITH_REAL_VAULT](TESTING_WITH_REAL_VAULT.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vollständigkeits-Checkliste (Stand)
|
||||||
|
|
||||||
|
| Bereich | Status |
|
||||||
|
|---------|--------|
|
||||||
|
| Module | 14 Module dokumentiert |
|
||||||
|
| Commands | 11+ Commands |
|
||||||
|
| Settings | 40+ Settings |
|
||||||
|
| Config-Dateien | 6 Dateien (edge_vocabulary, graph_schema, interview_config, chain_roles, chain_templates, analysis_policies) |
|
||||||
|
| Scoring & Gewichtung | Template Matching + Profile + Analysis Policies |
|
||||||
|
| Heading-Normalisierung | normalizeHeadingForMatch (^Block-ID entfernen, Idempotenz ohne ^) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
# Chain-Identifikation und Template Matching
|
# Chain-Identifikation und Template Matching
|
||||||
|
|
||||||
|
> **Stand:** Januar 2026
|
||||||
|
> **Siehe auch:** [modules/analysis](../modules/analysis.md), [06_Konfigurationsdateien_Referenz](../06_Konfigurationsdateien_Referenz.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Übersicht
|
## Übersicht
|
||||||
|
|
||||||
Das System identifiziert und füllt Chains durch einen mehrstufigen Prozess:
|
Das System identifiziert und füllt Chains durch einen mehrstufigen Prozess:
|
||||||
|
|
@ -176,13 +181,17 @@ roleEvidence.push({
|
||||||
|
|
||||||
### Scoring (`scoreAssignment`)
|
### Scoring (`scoreAssignment`)
|
||||||
|
|
||||||
**Slot-Scoring**:
|
**Implementierung:** `src/analysis/templateMatching.ts`
|
||||||
- Jeder zugewiesene Slot: **+2 Punkte**
|
|
||||||
|
|
||||||
**Link-Scoring**:
|
| Komponente | Punkte |
|
||||||
- Erfüllter Link (mit erlaubter Role): **+10 Punkte**
|
|------------|--------|
|
||||||
- Fehlender Link (wenn `required_links: true`): **-5 Punkte**
|
| Jeder zugewiesene Slot | +2 |
|
||||||
- Falsche Role (wenn `required_links: true`): **-5 Punkte**
|
| Intra-Note-Bonus (alle Slots in derselben Note) | +5 |
|
||||||
|
| Erfüllter Link (mit erlaubter Edge-Role) | +10 |
|
||||||
|
| Fehlender Link (wenn `required_links: true`) | -5 |
|
||||||
|
| Falsche Role (wenn `required_links: true`) | -5 |
|
||||||
|
|
||||||
|
**Heading-Matching:** Vergleiche via `headingsMatch` (normalisiert `^BlockID`; siehe [12_Heading_Block_Link_Recommendation](../../12_Heading_Block_Link_Recommendation.md)).
|
||||||
|
|
||||||
### Confidence-Berechnung
|
### Confidence-Berechnung
|
||||||
|
|
||||||
|
|
@ -221,6 +230,8 @@ min_slots_filled_for_gap_findings: 3
|
||||||
min_score_for_gap_findings: 18
|
min_score_for_gap_findings: 18
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Profil-Auswahl:** Plugin-Setting `templateMatchingProfile` (`discovery` | `decisioning`). Profil-Definitionen in `chain_templates.yaml` unter `defaults.profiles`.
|
||||||
|
|
||||||
### Profile-Auflösung
|
### Profile-Auflösung
|
||||||
|
|
||||||
1. **Settings**: Plugin-Einstellung `templateMatchingProfile`
|
1. **Settings**: Plugin-Einstellung `templateMatchingProfile`
|
||||||
|
|
@ -372,6 +383,23 @@ Definiert Note-Type-Kompatibilität:
|
||||||
- Welche Edge-Typen sind typisch für `insight → decision`?
|
- Welche Edge-Typen sind typisch für `insight → decision`?
|
||||||
- Welche Edge-Typen sind verboten?
|
- Welche Edge-Typen sind verboten?
|
||||||
|
|
||||||
|
### `analysis_policies.yaml`
|
||||||
|
|
||||||
|
Definiert Severity-Policies pro Profil (discovery, decisioning) für Findings:
|
||||||
|
- `missing_link_constraints`, `weak_chain_roles`, `unmapped_edge_types`, `missing_slot_*`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Matching-Parameter (defaults.matching)
|
||||||
|
|
||||||
|
| Parameter | Standard | Beschreibung |
|
||||||
|
|-----------|----------|--------------|
|
||||||
|
| `distinct_nodes` | true | Jeder Knoten nur einmal pro Template |
|
||||||
|
| `required_links` | true | Links erforderlich (profil-überschreibbar) |
|
||||||
|
| `max_candidate_nodes` | 30 | Max. Candidate Nodes pro Template |
|
||||||
|
| `max_matches_per_template` | 2 | Max. unterschiedliche Zuordnungen (z. B. intra-note + cross-note) |
|
||||||
|
| `max_assignments_collected` | 1000 | Schleifenschutz beim Backtracking |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Zusammenfassung
|
## Zusammenfassung
|
||||||
|
|
|
||||||
|
|
@ -531,58 +531,75 @@ templates:
|
||||||
|
|
||||||
### Zweck
|
### Zweck
|
||||||
|
|
||||||
Definiert Policies für Findings (Severity, Unterdrückung, etc.).
|
Definiert Severity-Policies für Findings pro Profil (discovery, decisioning).
|
||||||
|
|
||||||
### Format
|
### Format
|
||||||
|
|
||||||
**YAML-Datei** (geplant, noch nicht vollständig implementiert).
|
**YAML-Datei** mit `profiles` und `severities` je Finding-Typ.
|
||||||
|
|
||||||
### Geplante Struktur
|
### Aktuelle Struktur
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
version: "1.0"
|
version: 1
|
||||||
|
|
||||||
findings:
|
|
||||||
missing_slot_*:
|
|
||||||
default_severity: warn
|
|
||||||
profiles:
|
profiles:
|
||||||
discovery:
|
discovery:
|
||||||
severity: info
|
severities:
|
||||||
suppress_if:
|
missing_link_constraints: info
|
||||||
- slots_filled < 2
|
weak_chain_roles: info
|
||||||
|
unmapped_edge_types: info
|
||||||
|
missing_slot_*: info
|
||||||
decisioning:
|
decisioning:
|
||||||
severity: warn
|
severities:
|
||||||
suppress_if: []
|
missing_link_constraints: warn
|
||||||
dangling_target:
|
weak_chain_roles: info
|
||||||
default_severity: error
|
unmapped_edge_types: warn
|
||||||
suppress_if: []
|
missing_slot_*: warn
|
||||||
missing_link_constraints:
|
|
||||||
default_severity: warn
|
|
||||||
suppress_if:
|
|
||||||
- required_links == false
|
|
||||||
no_causal_roles:
|
|
||||||
default_severity: info
|
|
||||||
suppress_if: []
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Felder (geplant)
|
### Felder
|
||||||
|
|
||||||
#### Root-Level
|
- **`version`** (number, optional): Config-Version
|
||||||
|
- **`profiles`** (object, required): Profil-Name → Severity-Overrides
|
||||||
|
- **`severities`** (object): Finding-Code → Severity (`info`, `warn`, `error`)
|
||||||
|
|
||||||
- **`version`** (string, optional): Config-Version
|
### Verwendung
|
||||||
- **`findings`** (object, required): Mapping von Finding-Codes zu Policies
|
|
||||||
|
|
||||||
#### Finding Policy
|
- **Severity Policy:** `severityPolicy.ts` nutzt diese Datei für Profil-spezifische Severities
|
||||||
|
- **Profil-Auswahl:** Plugin-Setting `templateMatchingProfile` (`discovery` | `decisioning`)
|
||||||
|
|
||||||
- **`default_severity`** (string, required): Standard-Severity (`error`, `warn`, `info`)
|
---
|
||||||
- **`profiles`** (object, optional): Profil-spezifische Overrides
|
|
||||||
- **`discovery`** (object, optional): Discovery-Profil-Parameter
|
|
||||||
- **`decisioning`** (object, optional): Decisioning-Profil-Parameter
|
|
||||||
- **`suppress_if`** (array, optional): Bedingungen für Unterdrückung
|
|
||||||
|
|
||||||
### Status
|
## Template-Matching-Gewichtung (chain_templates.yaml)
|
||||||
|
|
||||||
**Noch nicht vollständig implementiert.** Aktuell wird Severity-Policy teilweise in `severityPolicy.ts` gehandhabt.
|
### Scoring-Logik (Implementierung)
|
||||||
|
|
||||||
|
Die Scoring-Logik ist in `src/analysis/templateMatching.ts` implementiert:
|
||||||
|
|
||||||
|
| Komponente | Punkte |
|
||||||
|
|------------|--------|
|
||||||
|
| Jeder zugewiesene Slot | +2 |
|
||||||
|
| Intra-Note-Bonus (alle Slots in derselben Note) | +5 |
|
||||||
|
| Erfüllter Link (mit erlaubter Edge-Role) | +10 |
|
||||||
|
| Fehlender Link (wenn `required_links: true`) | -5 |
|
||||||
|
| Falsche Role (wenn `required_links: true`) | -5 |
|
||||||
|
|
||||||
|
### Profil-Parameter (defaults.profiles)
|
||||||
|
|
||||||
|
| Parameter | discovery | decisioning | Beschreibung |
|
||||||
|
|-----------|-----------|-------------|--------------|
|
||||||
|
| `required_links` | false | true | Links sind Pflicht |
|
||||||
|
| `min_slots_filled_for_gap_findings` | 2 | 3 | Min. Slots für Gap-Findings |
|
||||||
|
| `min_score_for_gap_findings` | 8 | 18 | Min. Score für Gap-Findings |
|
||||||
|
|
||||||
|
### Matching-Parameter (defaults.matching)
|
||||||
|
|
||||||
|
| Parameter | Standard | Beschreibung |
|
||||||
|
|-----------|----------|--------------|
|
||||||
|
| `distinct_nodes` | true | Jeder Knoten nur einmal pro Template |
|
||||||
|
| `required_links` | true | Links erforderlich (profil-überschreibbar) |
|
||||||
|
| `max_candidate_nodes` | 30 | Max. Candidate Nodes pro Template |
|
||||||
|
| `max_matches_per_template` | 2 | Max. unterschiedliche Zuordnungen pro Template |
|
||||||
|
| `max_assignments_collected` | 1000 | Schleifenschutz beim Backtracking |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,16 +42,13 @@ Bei einer Zeile `## Überschrift ^Block` in der Zieldatei:
|
||||||
|
|
||||||
**Fazit:** Der Interview-Assistent erzeugt `[[Note#Überschrift]]`. In Obsidian springt dieser Link **in die Note, aber nicht auf die Überschrift** (siehe Abschnitt 1). Obsidian-typisches Springen auf die Überschrift (inkl. Highlight des Abschnitts) liefert nur `[[Titel#Überschrift Block]]` (UI-erzeugt, ohne `^`).
|
**Fazit:** Der Interview-Assistent erzeugt `[[Note#Überschrift]]`. In Obsidian springt dieser Link **in die Note, aber nicht auf die Überschrift** (siehe Abschnitt 1). Obsidian-typisches Springen auf die Überschrift (inkl. Highlight des Abschnitts) liefert nur `[[Titel#Überschrift Block]]` (UI-erzeugt, ohne `^`).
|
||||||
|
|
||||||
### 2.3 Inspect Chains & Chain Workbench
|
### 2.3 Inspect Chains & Chain Workbench (Stand: Jan 2026)
|
||||||
|
|
||||||
- **chainInspector** vergleicht überall **strikt:**
|
- **headingsMatch / normalizeHeadingForMatch** (`src/unresolvedLink/linkHelpers.ts`):
|
||||||
`edge.target.heading === context.heading` und
|
- **Mit ^Block-ID:** `"Überschrift ^Block"` → `"Überschrift"` (Block-Suffix entfernt)
|
||||||
`edge.source.sectionHeading === context.heading`.
|
- **Ohne ^:** Rückgabe unverändert (Idempotenz für bereits normalisierte Formen)
|
||||||
- **dangling_target_heading:** Prüfung gegen `metadataCache.getFileCache(...).headings` mit
|
- **Matchen:** `"Überschrift ^Block"` und `"Überschrift"` gelten als dieselbe Sektion.
|
||||||
`h.heading === targetHeading` (ebenfalls exakt).
|
- **Nicht unterstützt:** `"Überschrift Block"` (Obsidian-UI, ohne ^) wird **nicht** zu `"Überschrift"` normalisiert – für zuverlässiges Matching Links mit `^` verwenden.
|
||||||
- **Chain Workbench** nutzt dieselben Konzepte (context/assignment mit `heading`); keine Normalisierung.
|
|
||||||
|
|
||||||
**Folge:** Sobald eine Seite `"Überschrift ^block"` und ein Link `[[Titel#Überschrift]]` vorkommt (oder umgekehrt), stimmen die Strings nicht überein → kein Match, ggf. falscher `dangling_target_heading`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -75,30 +72,24 @@ Um nicht zu viele Änderungen gleichzeitig zu öffnen:
|
||||||
- **Nur eine Baustelle:** **Normalisierung in Inspect Chains & Chain Workbench** (zentrale Normalisierungsfunktion + alle Heading-Vergleiche und `dangling_target_heading` auf normalisierte Form umstellen).
|
- **Nur eine Baustelle:** **Normalisierung in Inspect Chains & Chain Workbench** (zentrale Normalisierungsfunktion + alle Heading-Vergleiche und `dangling_target_heading` auf normalisierte Form umstellen).
|
||||||
- **Interview-Assistent vorerst unverändert:** Weiter `[[Note#Überschrift]]` ausgeben. Eine spätere, **optionale** Anpassung (z. B. Ausgabe `[[Note#Überschrift Block]]` im Obsidian-Stil, damit der Klick auf die Überschrift springt) kann separat erfolgen.
|
- **Interview-Assistent vorerst unverändert:** Weiter `[[Note#Überschrift]]` ausgeben. Eine spätere, **optionale** Anpassung (z. B. Ausgabe `[[Note#Überschrift Block]]` im Obsidian-Stil, damit der Klick auf die Überschrift springt) kann separat erfolgen.
|
||||||
|
|
||||||
### 4.2 Normalisierungsregel (für Vergleiche)
|
### 4.2 Umsetzte Normalisierungsregel (Stand: Jan 2026)
|
||||||
|
|
||||||
Drei Schreibweisen sollen als **dieselbe Sektion** gelten:
|
**Implementiert in `normalizeHeadingForMatch` (linkHelpers.ts):**
|
||||||
|
|
||||||
- `Überschrift` (Interview, reiner Text)
|
1. **Mit ^Block-ID:** Block-Suffix entfernen: `\s*\^[a-zA-Z0-9_-]+\s*$` → z. B. `"Überschrift ^Block"` → `"Überschrift"`, `"Lars ist gut ^PersLars"` → `"Lars ist gut"`.
|
||||||
- `Überschrift ^Block` (Quelldokument / sectionParser)
|
2. **Ohne ^:** Rückgabe unverändert (Idempotenz). Multi-Wort-Überschriften wie `"Lars ist gut"` werden nicht gekürzt.
|
||||||
- `Überschrift Block` (Obsidian-UI-Link, ohne `^`)
|
|
||||||
|
|
||||||
**Kanonische Form für Vergleiche:**
|
**Matchen:** `"Überschrift ^Block"` und `"Überschrift"` gelten als dieselbe Sektion. `"Lars ist gut ^PersLars"` und `"Lars ist gut"` matchen.
|
||||||
|
|
||||||
1. Am Ende **Block-Suffix mit Caret** entfernen: `\s+\^[a-zA-Z0-9_-]+$` → z. B. `"Überschrift ^Block"` → `"Überschrift"`.
|
**Nicht unterstützt:** `"Überschrift Block"` (Obsidian-UI, ohne ^) wird **nicht** automatisch zu `"Überschrift"` normalisiert – zur Vermeidung von Fehlmatches bei kanonischen Multi-Wort-Überschriften. **Empfehlung:** Für zuverlässiges Matching Links mit `^` verwenden: `[[Note#Überschrift ^Block]]`.
|
||||||
2. Danach **ein einzelnes Wort am Ende** (nur Buchstaben, Zahlen, Bindestrich, Unterstrich) optional entfernen: `\s+[a-zA-Z0-9_-]+$` → z. B. `"Überschrift Block"` → `"Überschrift"`.
|
|
||||||
|
|
||||||
So werden alle drei Varianten auf `"Überschrift"` abgebildet. **Randfall:** Eine Überschrift, die wirklich „X Y“ heißt (ohne Block-ID), würde ebenfalls zu „X“ normalisiert und könnte mit „X“ matchen; in der Praxis selten. Die Funktion **nur** für Vergleiche/Prüfungen nutzen, nicht für Anzeige oder gespeicherte Links.
|
### 4.3 Umsetzte Maßnahmen
|
||||||
|
|
||||||
### 4.3 Konkrete Maßnahmen (nur diese eine Baustelle)
|
1. **Zentrale Normalisierung:** `normalizeHeadingForMatch` und `headingsMatch` in `src/unresolvedLink/linkHelpers.ts` – nur ^Block-Suffix entfernen, sonst Idempotenz.
|
||||||
|
|
||||||
1. **Eine zentrale Normalisierungsfunktion** (z. B. in `linkHelpers` oder eigenem Modul): Eingabe = Überschrift-String, Ausgabe = kanonische Form wie oben.
|
2. **Inspect Chains & Chain Workbench:** Nutzen `headingsMatch` für alle Heading-Vergleiche.
|
||||||
|
|
||||||
2. **Inspect Chains (chainInspector):** Alle Vergleiche mit `heading` / `sectionHeading` auf die **normalisierte** Form umstellen; bei **dangling_target_heading** `targetHeading` und Cache-Headings vor dem Vergleich normalisieren.
|
3. **Interview-Assistent:** Unverändert – erzeugt weiterhin `[[Note#Überschrift]]`.
|
||||||
|
|
||||||
3. **Chain Workbench:** Dieselbe Normalisierung überall, wo Headings verglichen werden.
|
|
||||||
|
|
||||||
4. **graphIndex / Interview:** Keine Änderung in dieser Baustelle.
|
|
||||||
|
|
||||||
### 4.4 Optional später (separate Baustelle)
|
### 4.4 Optional später (separate Baustelle)
|
||||||
|
|
||||||
|
|
@ -106,8 +97,8 @@ So werden alle drei Varianten auf `"Überschrift"` abgebildet. **Randfall:** Ein
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Kurzfassung
|
## 5. Kurzfassung (Stand: Jan 2026)
|
||||||
|
|
||||||
- **Obsidian (beobachtet):** Manueller Link auf Überschrift mit Block-ID → `[[Titel#Überschrift Block]]` (ohne `^`). Klick springt auf Überschrift und highlighted den Abschnitt. `[[Titel#Überschrift]]` springt nur in die Note, nicht auf die Überschrift. `[[Titel#^Block]]` highlighted nur die Überschrift.
|
- **Plugin-Normalisierung:** `normalizeHeadingForMatch` entfernt nur `^BlockID`; bei Überschriften ohne `^` wird unverändert zurückgegeben (Idempotenz). Dadurch matchen `"Lars ist gut ^PersLars"` und `"Lars ist gut"` korrekt.
|
||||||
- **Eine Baustelle:** Nur **Normalisierung in Inspect Chains & Chain Workbench** umsetzen (zentrale Funktion: Block-Suffix mit `^` und ggf. ein trailinges Wort entfernen; alle Heading-Vergleiche und `dangling_target_heading` auf diese Form umstellen). Interview-Assistent und graphIndex in dieser Runde **nicht** anfassen.
|
- **Empfehlung:** Für zuverlässiges Matching Links mit `^` verwenden: `[[Note#Überschrift ^Block]]`. Obsidian-Form `[[Titel#Überschrift Block]]` (ohne `^`) wird nicht automatisch normalisiert.
|
||||||
- **Optional später:** Interview-Assistent so anpassen, dass er z. B. `[[Note#Überschrift Block]]` erzeugt (Obsidian-Stil), damit der Klick auf den Link auf die Überschrift springt.
|
- **Obsidian (beobachtet):** Manueller Link → `[[Titel#Überschrift Block]]` (ohne `^`). Klick springt auf Überschrift. `[[Titel#^Block]]` highlighted nur die Überschrift.
|
||||||
|
|
|
||||||
309
docs/13_Erfassung_Causal_Ketten.md
Normal file
309
docs/13_Erfassung_Causal_Ketten.md
Normal file
|
|
@ -0,0 +1,309 @@
|
||||||
|
# Handbuch: Erfassung & Causal-Ketten in Obsidian
|
||||||
|
|
||||||
|
> **Zielgruppe:** Du beim täglichen Erfassen (auch unterwegs)
|
||||||
|
> **Plugin:** Mindnet Causal Assistant
|
||||||
|
> **Stand:** August 2026
|
||||||
|
> **Zweck:** Elemente so anlegen und vernetzen, dass kausale Ketten erkennbar, prüfbar und schließbar sind.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Was du erzeugst
|
||||||
|
|
||||||
|
Mindnet speichert Wissen als **Markdown im Vault**. Das Plugin hilft, daraus einen **kausalen Graphen** zu machen.
|
||||||
|
|
||||||
|
| Baustein | Bedeutung | Beispiel |
|
||||||
|
|----------|-----------|----------|
|
||||||
|
| **Note** | Eine Entität (Datei) mit Typ und `id` | Experience „Geburt der Kinder“ |
|
||||||
|
| **Section** | Abschnitt unter einer Überschrift; optional mit Typ | `## Learning ^learning` + `[!section] insight` |
|
||||||
|
| **Block-ID** | Anker hinter der Überschrift (`^…`) | `^learning`, `^next` |
|
||||||
|
| **Edge** | Gerichtete Beziehung mit Typ | `caused_by`, `guides`, `resulted_in` |
|
||||||
|
| **Kette** | Mehrere Notes/Sections + Edges in einem Muster | Experience → Insight → Decision |
|
||||||
|
|
||||||
|
**Merksatz:** Text allein reicht nicht. Ketten entstehen, wenn du **Rollen** (Typen) und **Kanten** (Edges) setzt.
|
||||||
|
|
||||||
|
### Urlaub / Weiterarbeit ohne Massen-Relink
|
||||||
|
|
||||||
|
Neue Notes so anlegen, dass sie später **nicht** umgeschrieben werden müssen. Alte Notes nicht anfassen, nur neue sauber schreiben.
|
||||||
|
|
||||||
|
| Immer so | Nie so (später teuer) |
|
||||||
|
|----------|------------------------|
|
||||||
|
| Überschrift mit Block-ID: `## Learning ^learning` | Überschrift ohne `^…` |
|
||||||
|
| Section-Typ: `> [!section] insight` | Nur Fließtext ohne Typ |
|
||||||
|
| Intra-Note: `[[#^learning]]` | `[[#Learning]]` ohne `^` |
|
||||||
|
| Cross-Note: `[[Note#Überschrift ^block]]` | `[[Note#Überschrift]]` ohne Block-ID |
|
||||||
|
| Kanten als `[!edge]` mit kanonischem Typ (`guides`, `caused_by`, `derived_from`) | Nur lose Wikilinks oder Alias-Typen wie `derives` |
|
||||||
|
|
||||||
|
**Create note from profile** und **Chain Workbench** schreiben diese Form jetzt selbst. Manuelle Obsidian-UI-Links (`[[Note#Überschrift Block]]` ohne `^`) vermeiden.
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
E[Experience / Situation] -->|causal / influences| I[Insight / Learning]
|
||||||
|
I -->|guides / foundation_for| D[Decision / nächster Schritt]
|
||||||
|
D -->|causal| E2[neue Experience / Feedback]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Die wichtigsten Commands
|
||||||
|
|
||||||
|
Command Palette: `Ctrl+P` (macOS: `Cmd+P`).
|
||||||
|
|
||||||
|
| Wann | Command |
|
||||||
|
|------|---------|
|
||||||
|
| Neu anfangen | **Mindnet: Create note from profile** |
|
||||||
|
| Links zu Edges machen | **Mindnet: Build semantic mapping blocks (by section)** |
|
||||||
|
| Edge-Typ wählen/ändern | **Mindnet: Edge-Type ändern** |
|
||||||
|
| Note prüfen | **Mindnet: Validate current note** |
|
||||||
|
| Ketten verstehen | **Mindnet: Inspect Chains (Current Section)** |
|
||||||
|
| Lücken schließen | **Mindnet: Chain Workbench (Current Section)** |
|
||||||
|
| Vault-weit Lücken finden | **Mindnet: Scan Vault for Chain Gaps** |
|
||||||
|
| Findings beheben | **Mindnet: Fix Findings (Current Section)** |
|
||||||
|
|
||||||
|
Einstellungen: **Mindnet: Einstellungen öffnen** (oder Plugin-Name in der linken Settings-Leiste).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Alltags-Workflow: von der Idee zur Kette
|
||||||
|
|
||||||
|
### Schritt A — Element anlegen
|
||||||
|
|
||||||
|
1. **Mindnet: Create note from profile**
|
||||||
|
2. Profil wählen, z. B.:
|
||||||
|
- **Experience – Basis** → Erlebnis / Situation
|
||||||
|
- **Insight – Basis** → Erkenntnis / Learning
|
||||||
|
- weitere Profile je nach Vault-Config
|
||||||
|
3. Titel und Ordner setzen → Note öffnet sich
|
||||||
|
4. Interview-Wizard ausfüllen → **Review → Apply & Finish**
|
||||||
|
|
||||||
|
Ergebnis typischerweise:
|
||||||
|
|
||||||
|
- Frontmatter mit `id`, `title`, `type`, …
|
||||||
|
- Sections mit Überschriften
|
||||||
|
- oft schon `[!section] …` und `^block-id` (WP-26)
|
||||||
|
|
||||||
|
> **Tipp:** **Mindnet: Create note from profile** startet den Wizard immer. Für eine schon offene Note: **Mindnet: Interview für aktuelle Note starten**.
|
||||||
|
|
||||||
|
### Schritt B — Verbindungen setzen (während oder nach dem Schreiben)
|
||||||
|
|
||||||
|
**Variante 1 – im Text verlinken, dann mappen**
|
||||||
|
|
||||||
|
1. Im Fließtext oder am Section-Ende Wikilinks setzen, z. B. `[[Meine Einsicht]]`
|
||||||
|
2. Cursor in die Section
|
||||||
|
3. **Mindnet: Edge-Type ändern** → passenden Typ wählen
|
||||||
|
oder zuerst Links setzen und danach **Build semantic mapping blocks**
|
||||||
|
4. Mapping-Block prüfen:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
> [!abstract] 🕸️ Semantic Mapping
|
||||||
|
>
|
||||||
|
> > [!edge] caused_by
|
||||||
|
> > [[Früheres Erlebnis]]
|
||||||
|
>
|
||||||
|
> > [!edge] guides
|
||||||
|
> > [[Nächster Schritt ^next]]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Variante 2 – fehlende Note aus einem Link erzeugen**
|
||||||
|
|
||||||
|
1. `[[Noch nicht existierende Note]]` schreiben
|
||||||
|
2. Link anklicken (Reading View: Klick; Editor oft `Ctrl`+Klick)
|
||||||
|
3. Profil wählen → Note (+ optional Wizard)
|
||||||
|
|
||||||
|
**Variante 3 – Intra-Note (innerhalb einer Datei)**
|
||||||
|
|
||||||
|
Sections derselben Note verbinden, bevorzugt mit Block-ID:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Situation ^sit
|
||||||
|
> [!section] experience
|
||||||
|
|
||||||
|
…
|
||||||
|
|
||||||
|
## Learning ^learning
|
||||||
|
> [!section] insight
|
||||||
|
|
||||||
|
> [!edge] derived_from
|
||||||
|
> [[#^sit]]
|
||||||
|
|
||||||
|
## Nächster Schritt ^next
|
||||||
|
> [!section] decision
|
||||||
|
|
||||||
|
> [!edge] guides
|
||||||
|
> [[#^learning]]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Link-Empfehlung für zuverlässiges Matching:**
|
||||||
|
|
||||||
|
| Form | Nutzen |
|
||||||
|
|------|--------|
|
||||||
|
| `[[Note#Überschrift ^block]]` oder `[[#^block]]` | zuverlässig für Chain Inspector / Workbench |
|
||||||
|
| `[[Note#Überschrift]]` | oft vom Interview erzeugt; springt in Obsidian nicht immer zur Überschrift |
|
||||||
|
| Obsidian-UI ohne `^` (`…#Überschrift Block`) | gut zum Navigieren, Matching kann schwächer sein |
|
||||||
|
|
||||||
|
### Schritt C — Kette prüfen
|
||||||
|
|
||||||
|
1. Cursor in die relevante Section stellen
|
||||||
|
2. **Mindnet: Chain Workbench (Current Section)** öffnen
|
||||||
|
3. Matches und Status lesen (siehe Abschnitt 5)
|
||||||
|
4. Todos abarbeiten: fehlende Edges, fehlende Notes, falsche Typen
|
||||||
|
5. Optional: **Inspect Chains** für den textuellen Report (Console / Report)
|
||||||
|
|
||||||
|
### Schritt D — Qualität sichern
|
||||||
|
|
||||||
|
1. **Validate current note** → keine Errors
|
||||||
|
2. Bei Bedarf **Fix Findings**
|
||||||
|
3. Speichern — Obsidian Sync übernimmt den Vault
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Welche Kette willst du erzählen?
|
||||||
|
|
||||||
|
Das Plugin matcht gegen **Chain Templates** (Datei `chain_templates.yaml`). Du musst sie nicht auswendig kennen — aber die Kernmuster helfen beim Erfassen:
|
||||||
|
|
||||||
|
### 4.1 Trigger → Transformation → Outcome
|
||||||
|
|
||||||
|
**Frage:** Was hat mich verändert, und was folgte daraus?
|
||||||
|
|
||||||
|
| Slot | Typische Typen | Deine Rolle beim Erfassen |
|
||||||
|
|------|----------------|---------------------------|
|
||||||
|
| trigger | experience, event, obstacle, risk, state | Auslöser / Situation |
|
||||||
|
| transformation | insight, belief, value, principle, … | innere Veränderung |
|
||||||
|
| outcome | decision, project, habit, goal | Folge / Handlung |
|
||||||
|
|
||||||
|
Edges zwischen den Slots: eher **causal**, **influences**, **provenance** (`foundation_for` u. ä.).
|
||||||
|
|
||||||
|
### 4.2 Learning Loop
|
||||||
|
|
||||||
|
**Frage:** Erlebnis → Lernen → Verhalten → neues Erlebnis?
|
||||||
|
|
||||||
|
| Slot | Typische Typen |
|
||||||
|
|------|----------------|
|
||||||
|
| experience | experience, event, situation |
|
||||||
|
| learning | insight, principle, value, … |
|
||||||
|
| behavior | habit, decision, task |
|
||||||
|
| feedback | experience, journal, event, state |
|
||||||
|
|
||||||
|
Viele Experience-Interviews legen genau diese Abschnitte nahe (Situation → Learning → Nächster Schritt).
|
||||||
|
|
||||||
|
### 4.3 Decision Logic
|
||||||
|
|
||||||
|
**Frage:** Was treibt die Entscheidung, was begrenzt sie, was entsteht?
|
||||||
|
|
||||||
|
driver + constraint → decision → outcome
|
||||||
|
|
||||||
|
### 4.4 Weitere Muster (kurz)
|
||||||
|
|
||||||
|
- **constraint_to_adaptation** — Problem → Anpassung → Stabilisierung
|
||||||
|
- **person_influence** — Person → inneres Modell → Entscheidung/Outcome
|
||||||
|
- **state_trigger_response** — Zustand → Auslöser → Reaktion → neuer Zustand
|
||||||
|
|
||||||
|
**Praxisregel:** Beim Schreiben eine dieser Geschichten im Kopf behalten und die fehlenden Glieder als Notes/Sections + Edges nachziehen — nicht „irgendwelche Links“.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Workbench lesen: Status & Todos
|
||||||
|
|
||||||
|
| Status | Bedeutung | Typische Aktion |
|
||||||
|
|--------|-----------|-----------------|
|
||||||
|
| **complete** | Slots und geforderte Links passen | fertig / nur noch Feinschliff |
|
||||||
|
| **near_complete** | fast vollständig | 1–2 Todos (Edge oder Slot) |
|
||||||
|
| **partial** | mehrere Lücken | gezielt fehlende Glieder anlegen |
|
||||||
|
| **weak** | schwache/unsichere Zuordnung | Typen und Edges prüfen, Template evtl. falsch |
|
||||||
|
|
||||||
|
Häufige Todos:
|
||||||
|
|
||||||
|
- **missing_slot** — fehlendes Glied der Kette (Note oder Section anlegen)
|
||||||
|
- **missing_link** — Verbindung zwischen vorhandenen Gliedern fehlt → Edge einfügen
|
||||||
|
- **dangling_target** — Link zeigt ins Leere → Note/Heading erzeugen oder Link retargeten
|
||||||
|
|
||||||
|
**Arbeitsweise:** Immer zuerst **near_complete** schließen — dort ist der Erkenntnisgewinn pro Klick am höchsten. Vault-weit: **Scan Vault for Chain Gaps**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Section Types & Effective Type
|
||||||
|
|
||||||
|
Innerhalb einer Note können Abschnitte **eigene Typen** haben:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
---
|
||||||
|
type: experience
|
||||||
|
---
|
||||||
|
|
||||||
|
## Learning ^learning
|
||||||
|
> [!section] insight
|
||||||
|
|
||||||
|
Was ich daraus lerne …
|
||||||
|
```
|
||||||
|
|
||||||
|
- Ohne `[!section]` gilt der **Note-Type** (`experience`).
|
||||||
|
- Mit `[!section] insight` zählt die Section als **insight** fürs Template-Matching (**effective type**).
|
||||||
|
- So kann eine Experience-Note intern schon die Learning-Loop abbilden, ohne sofort drei Dateien anzulegen.
|
||||||
|
|
||||||
|
**Wann eigene Datei, wann Section?**
|
||||||
|
|
||||||
|
| Situation | Empfehlung |
|
||||||
|
|-----------|------------|
|
||||||
|
| Ein Erlebnis mit Situation / Reaktion / Learning / nächstem Schritt | eine Note, Sections + Intra-Note-Edges |
|
||||||
|
| Learning soll später vielen Experiences gehören | eigene Insight-Note + Cross-Note-Edge |
|
||||||
|
| Entscheidung betrifft mehrere Projekte | eigene Decision-Note |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Mini-Checkliste pro Erfassungs-Session
|
||||||
|
|
||||||
|
Vor dem Schließen der Note:
|
||||||
|
|
||||||
|
- [ ] Frontmatter hat `id` und sinnvollen `type`
|
||||||
|
- [ ] Wichtige Abschnitte haben Überschrift (+ idealerweise `^block-id`)
|
||||||
|
- [ ] Wo nötig: `[!section] …` gesetzt
|
||||||
|
- [ ] Beziehungen liegen als `[!edge]` (Mapping-Block) vor — nicht nur lose Wikilinks
|
||||||
|
- [ ] Mindestens eine erkennbare Ketten-Idee (z. B. Learning Loop oder Trigger→Outcome)
|
||||||
|
- [ ] **Validate** ohne Errors
|
||||||
|
- [ ] Bei Ambition: Workbench zeigt **near_complete** oder **complete** für das Haupt-Template
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Typischer Tagesablauf (Urlaub / unterwegs)
|
||||||
|
|
||||||
|
1. **Erfassen** — 1–3 Experiences oder Insights über Profile + Interview
|
||||||
|
2. **Verknüpfen** — Edges zu bestehenden Notes/Sections (Mapping / Edge-Type)
|
||||||
|
3. **Ketten schließen** — Workbench auf der wichtigsten Section, 5–15 Minuten Todos
|
||||||
|
4. **Optional Scan** — einmal am Tag/Woche Vault Gap Scan, nahe Lücken priorisieren
|
||||||
|
|
||||||
|
Obsidian Sync speichert den Vault zentral. Plugin-Updates (`main.js`) synct nur, wenn Community-Plugins in Sync aktiviert sind — sonst nach Build manuell in `.obsidian/plugins/mindnet-causal-assistant/` legen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Häufige Stolpersteine
|
||||||
|
|
||||||
|
| Problem | Was tun |
|
||||||
|
|---------|---------|
|
||||||
|
| Keine Profile beim Create | Config-Pfad `_system/dictionary/interview_config.yaml` / Sync prüfen |
|
||||||
|
| Workbench „Chain Roles/Templates nicht geladen“ | Pfade in Plugin-Settings prüfen |
|
||||||
|
| Kette wird nicht erkannt | Edge-Typ zu generisch/falsch; Section-Type fehlt; Link ohne treffendes Heading/`^block` |
|
||||||
|
| Link springt nicht zur Section | Form mit Block-ID nutzen (`[[#^id]]` oder Heading+`^block`) |
|
||||||
|
| Mapping an falscher Stelle | Cursor in die richtige Section; Mapping erneut bauen |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Kurz-Rezept: „Ich will eine Learning-Loop sauber machen“
|
||||||
|
|
||||||
|
1. Experience-Note aus Profil **Experience – Basis**
|
||||||
|
2. Interview: Situation, Reaktion, Learning, Nächster Schritt ausfüllen
|
||||||
|
3. Prüfen: Sections haben Block-IDs; Learning = `[!section] insight` (falls vorgesehen)
|
||||||
|
4. Edges setzen, z. B. Learning ← Situation, Nächster Schritt ← Learning (`guides` / passende Rolle)
|
||||||
|
5. Cursor auf Learning-Section → **Chain Workbench** → Template `loop_learning` / verwandte Matches
|
||||||
|
6. Todos bis **near_complete** oder **complete**
|
||||||
|
7. Validate → speichern
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [01_Benutzerhandbuch](01_Benutzerhandbuch.md) — Commands & Settings im Detail
|
||||||
|
- [07_Event_Handler_Commands](07_Event_Handler_Commands.md) — vollständige Command-Referenz
|
||||||
|
- [12_Heading_Block_Link_Recommendation](12_Heading_Block_Link_Recommendation.md) — Link-Formen & Matching
|
||||||
|
- [Interview_Config_Guide](Interview_Config_Guide.md) — Profile anpassen (Admin)
|
||||||
|
- [02_concepts/03_chain_identification_and_matching](02_concepts/03_chain_identification_and_matching.md) — Matching-Technik
|
||||||
|
|
||||||
|
**Tipp:** Diese Datei nach `_system/docs/` (oder ähnlich) im Vault kopieren, dann liegt sie über Obsidian Sync auf allen Geräten.
|
||||||
81
docs/by_role/README.md
Normal file
81
docs/by_role/README.md
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
# Dokumentation nach Rolle
|
||||||
|
|
||||||
|
> **Zielgruppe:** Alle
|
||||||
|
> **Einstieg:** Wählen Sie Ihre Rolle und folgen Sie den verlinkten Dokumenten
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Nutzer
|
||||||
|
|
||||||
|
**Primäre Dokumente:**
|
||||||
|
|
||||||
|
- [13_Erfassung_Causal_Ketten](../13_Erfassung_Causal_Ketten.md) – **Alltag:** Erfassen, verlinken, Causal-Ketten prüfen/schließen
|
||||||
|
- [01_Benutzerhandbuch](../01_Benutzerhandbuch.md) – Installation, Commands, Workflows, Troubleshooting
|
||||||
|
- [07_Event_Handler_Commands](../07_Event_Handler_Commands.md) – alle Commands und Event-Handler
|
||||||
|
|
||||||
|
**Zusätzlich:**
|
||||||
|
|
||||||
|
- [05_Installation_Deployment](../05_Installation_Deployment.md) – Installation
|
||||||
|
- [12_Heading_Block_Link_Recommendation](../12_Heading_Block_Link_Recommendation.md) – Überschriften-Links (Obsidian)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Administrator
|
||||||
|
|
||||||
|
**Primäre Dokumente:**
|
||||||
|
|
||||||
|
- [02_Administratorhandbuch](../02_Administratorhandbuch.md) – Plugin-Konfiguration, Pfade, Wartung
|
||||||
|
- [06_Konfigurationsdateien_Referenz](../06_Konfigurationsdateien_Referenz.md) – alle Config-Dateien, Gewichtung, Analysis Policies
|
||||||
|
- [Interview_Config_Guide](../Interview_Config_Guide.md) – interview_config.yaml
|
||||||
|
|
||||||
|
**Zusätzlich:**
|
||||||
|
|
||||||
|
- [05_Installation_Deployment](../05_Installation_Deployment.md) – Deployment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Entwickler
|
||||||
|
|
||||||
|
**Primäre Dokumente:**
|
||||||
|
|
||||||
|
- [03_Entwicklerhandbuch](../03_Entwicklerhandbuch.md) – Projekt-Struktur, Build, Testing
|
||||||
|
- [04_Architektur](../04_Architektur.md) – System-Design
|
||||||
|
- [modules/README](../modules/README.md) – Modul-Übersicht
|
||||||
|
|
||||||
|
**Zusätzlich:**
|
||||||
|
|
||||||
|
- [02_concepts/03_chain_identification_and_matching](../02_concepts/03_chain_identification_and_matching.md) – Template Matching, Scoring
|
||||||
|
- [06_Konfigurationsdateien_Referenz](../06_Konfigurationsdateien_Referenz.md) – Config-Formate
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architekt
|
||||||
|
|
||||||
|
**Primäre Dokumente:**
|
||||||
|
|
||||||
|
- [04_Architektur](../04_Architektur.md) – Komponenten, Datenfluss
|
||||||
|
- [02_concepts/03_chain_identification_and_matching](../02_concepts/03_chain_identification_and_matching.md) – Chain-Identifikation, Scoring
|
||||||
|
- [02_causal_chain_retrieving](../02_causal_chain_retrieving.md) – Kausale Ketten
|
||||||
|
|
||||||
|
**Zusätzlich:**
|
||||||
|
|
||||||
|
- [modules/](../modules/) – Modul-Details
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Projektleitung
|
||||||
|
|
||||||
|
**Primäre Dokumente:**
|
||||||
|
|
||||||
|
- [04_Architektur](../04_Architektur.md) – Überblick
|
||||||
|
- [README](../../README.md) – Projekt-README
|
||||||
|
- [STATUS_DOD](../../STATUS_DOD.md) – Definition of Done
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Systemadmin
|
||||||
|
|
||||||
|
**Primäre Dokumente:**
|
||||||
|
|
||||||
|
- [05_Installation_Deployment](../05_Installation_Deployment.md) – Installation, Deployment
|
||||||
|
- [02_Administratorhandbuch](../02_Administratorhandbuch.md) – Konfiguration
|
||||||
58
docs/modules/README.md
Normal file
58
docs/modules/README.md
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
# Module – technische Dokumentation
|
||||||
|
|
||||||
|
> **Zielgruppe:** Entwickler, Architekten
|
||||||
|
> **Übersicht:** Modul-basierte Dokumentation des Mindnet Causal Assistant Plugins
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Modul-Übersicht
|
||||||
|
|
||||||
|
| Modul | Pfad in `src/` | Kurzbeschreibung |
|
||||||
|
|-------|----------------|------------------|
|
||||||
|
| [Analysis](analysis.md) | `analysis/` | Chain Inspector, Template Matching, Scoring, Findings |
|
||||||
|
| [Dictionary](dictionary.md) | `dictionary/` | Config-Loader, Chain Roles, Chain Templates |
|
||||||
|
| [Interview](interview.md) | `interview/` | Wizard, Loop State, Renderer, Section Key Resolver |
|
||||||
|
| [Mapping](mapping.md) | `mapping/` | Semantic Mapping, Edge Type Selector |
|
||||||
|
| [Parser](parser.md) | `parser/` | Edges aus Callouts, Frontmatter, Links |
|
||||||
|
| [Graph](graph.md) | `graph/` | Graph Builder, Traversal, Resolution |
|
||||||
|
| [Vocabulary](vocabulary.md) | `vocab/` | Edge Vocabulary, Normalisierung |
|
||||||
|
| [Unresolved Link](unresolvedLink.md) | `unresolvedLink/` | Link-Handler, Adoption, Heading-Normalisierung |
|
||||||
|
| [Workbench](workbench.md) | `workbench/` | Chain Workbench, Todo-Generator, Status |
|
||||||
|
| [Lint](lint.md) | `lint/` | Lint Engine, Rules |
|
||||||
|
| [UI](ui.md) | `ui/` | Modals, Settings Tab, Entity Picker |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Abhängigkeiten (vereinfacht)
|
||||||
|
|
||||||
|
```
|
||||||
|
main.ts
|
||||||
|
├── analysis ← dictionary, graph, parser
|
||||||
|
├── commands ← analysis, graph, mapping, ui, ...
|
||||||
|
├── dictionary ← vault
|
||||||
|
├── graph ← parser
|
||||||
|
├── interview ← dictionary, parser
|
||||||
|
├── mapping ← parser, schema
|
||||||
|
├── parser
|
||||||
|
├── vocab ← vault
|
||||||
|
├── lint ← vocab, parser
|
||||||
|
├── unresolvedLink ← interview, entityPicker
|
||||||
|
├── workbench ← analysis, interview, mapping
|
||||||
|
└── ui
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Weitere Module
|
||||||
|
|
||||||
|
- **schema/** – Graph Schema Loader
|
||||||
|
- **entityPicker/** – Note Index, Folder Tree, Filters
|
||||||
|
- **export/** – Graph Export
|
||||||
|
- **utils/** – Logger
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [04_Architektur](../04_Architektur.md) – System-Design
|
||||||
|
- [02_concepts/03_chain_identification_and_matching](../02_concepts/03_chain_identification_and_matching.md) – Template Matching, Scoring
|
||||||
112
docs/modules/analysis.md
Normal file
112
docs/modules/analysis.md
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
# Modul: Analysis
|
||||||
|
|
||||||
|
> **Pfad:** `src/analysis/`
|
||||||
|
> **Zielgruppe:** Entwickler, Architekten
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Das Analysis-Modul enthält die Chain Inspector-Logik, Template Matching, Scoring und Findings-Erzeugung.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `chainInspector.ts` | Haupt-Analyse-Engine |
|
||||||
|
| `templateMatching.ts` | Template Matching, Scoring, Backtracking |
|
||||||
|
| `graphIndex.ts` | Graph-Indexierung, Edge-Erfassung |
|
||||||
|
| `sectionContext.ts` | Section-Context-Handling |
|
||||||
|
| `severityPolicy.ts` | Severity-Policy für Findings |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scoring-Logik (Template Matching)
|
||||||
|
|
||||||
|
### scoreAssignment
|
||||||
|
|
||||||
|
Die Funktion `scoreAssignment` bewertet jede Slot-Zuordnung:
|
||||||
|
|
||||||
|
| Komponente | Punkte |
|
||||||
|
|------------|--------|
|
||||||
|
| Jeder zugewiesene Slot | +2 |
|
||||||
|
| Intra-Note-Bonus (alle Slots in derselben Note) | +5 |
|
||||||
|
| Erfüllter Link (mit erlaubter Edge-Role) | +10 |
|
||||||
|
| Fehlender Link (wenn `required_links: true`) | -5 |
|
||||||
|
| Falsche Role (wenn `required_links: true`) | -5 |
|
||||||
|
|
||||||
|
### Link-Validierung
|
||||||
|
|
||||||
|
- **findEdgeBetween:** Sucht Edge zwischen zwei Nodes (file:heading)
|
||||||
|
- **headingsMatch:** Vergleicht Überschriften (normalisiert über `normalizeHeadingForMatch`)
|
||||||
|
- **Role-Mapping:** Edge-Typ → Role via `chain_roles.yaml`
|
||||||
|
|
||||||
|
### Profile-Auflösung
|
||||||
|
|
||||||
|
1. **Settings:** `templateMatchingProfile` (`discovery` | `decisioning`)
|
||||||
|
2. **Template:** `template.matching.required_links`
|
||||||
|
3. **Defaults:** `defaults.matching.required_links`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Template-Matching-Profile
|
||||||
|
|
||||||
|
| Profil | required_links | min_slots_filled_for_gap_findings | min_score_for_gap_findings |
|
||||||
|
|--------|----------------|-----------------------------------|----------------------------|
|
||||||
|
| `discovery` | false | 2 | 8 |
|
||||||
|
| `decisioning` | true | 3 | 18 |
|
||||||
|
|
||||||
|
Profile werden in `chain_templates.yaml` unter `defaults.profiles` definiert.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Confidence-Berechnung
|
||||||
|
|
||||||
|
| Confidence | Bedingung |
|
||||||
|
|------------|-----------|
|
||||||
|
| `confirmed` | slotsComplete AND linksComplete AND mind. eine causal-ish Role |
|
||||||
|
| `plausible` | slotsComplete, aber (nicht linksComplete ODER keine causal-ish Role) |
|
||||||
|
| `weak` | nicht slotsComplete |
|
||||||
|
|
||||||
|
**causal-ish Roles:** `["causal", "influences", "enables_constraints"]` (konfigurierbar in `chain_templates.yaml`)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Analysis Policies
|
||||||
|
|
||||||
|
Datei: `analysis_policies.yaml` (Pfad via Settings `analysisPoliciesPath`)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: 1
|
||||||
|
profiles:
|
||||||
|
discovery:
|
||||||
|
severities:
|
||||||
|
missing_link_constraints: info
|
||||||
|
weak_chain_roles: info
|
||||||
|
unmapped_edge_types: info
|
||||||
|
missing_slot_*: info
|
||||||
|
decisioning:
|
||||||
|
severities:
|
||||||
|
missing_link_constraints: warn
|
||||||
|
weak_chain_roles: info
|
||||||
|
unmapped_edge_types: warn
|
||||||
|
missing_slot_*: warn
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Abhängigkeiten
|
||||||
|
|
||||||
|
- **Dictionary:** Chain Roles, Chain Templates
|
||||||
|
- **Graph:** Graph Index, Traversal
|
||||||
|
- **Parser:** Edge-Extraktion
|
||||||
|
- **Unresolved Link:** `headingsMatch`, `normalizeHeadingForMatch`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [02_concepts/03_chain_identification_and_matching](../02_concepts/03_chain_identification_and_matching.md)
|
||||||
|
- [06_Konfigurationsdateien_Referenz](../06_Konfigurationsdateien_Referenz.md) – chain_templates, chain_roles, analysis_policies
|
||||||
67
docs/modules/dictionary.md
Normal file
67
docs/modules/dictionary.md
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
# Modul: Dictionary
|
||||||
|
|
||||||
|
> **Pfad:** `src/dictionary/`
|
||||||
|
> **Zielgruppe:** Entwickler, Administratoren
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Das Dictionary-Modul lädt und parst alle Konfigurationsdateien (YAML, Markdown) und stellt sie den anderen Modulen zur Verfügung.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `DictionaryLoader.ts` | Generischer Loader mit Last-Known-Good |
|
||||||
|
| `ChainRolesLoader.ts` | Lädt chain_roles.yaml |
|
||||||
|
| `ChainTemplatesLoader.ts` | Lädt chain_templates.yaml |
|
||||||
|
| `ConfigPathManager.ts` | Pfad-Auflösung für Config-Dateien |
|
||||||
|
| `parseChainRoles.ts` | Parser für chain_roles |
|
||||||
|
| `parseChainTemplates.ts` | Parser für chain_templates |
|
||||||
|
| `types.ts` | TypeScript-Typen |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Geladene Config-Dateien
|
||||||
|
|
||||||
|
| Datei | Pfad-Setting | Inhalt |
|
||||||
|
|-------|-------------|--------|
|
||||||
|
| edge_vocabulary | edgeVocabularyPath | Kanonische Edge-Typen, Aliases |
|
||||||
|
| graph_schema | graphSchemaPath | Empfehlungen für Edge-Typen |
|
||||||
|
| interview_config | interviewConfigPath | Profile, Steps, Loops |
|
||||||
|
| chain_roles | chainRolesPath | Edge-Typ → Role Mapping |
|
||||||
|
| chain_templates | chainTemplatesPath | Templates, Slots, Links, Profile |
|
||||||
|
| analysis_policies | analysisPoliciesPath | Severity-Policies pro Profil |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Live-Reload
|
||||||
|
|
||||||
|
- **Debounced:** 200ms bei Dateiänderung
|
||||||
|
- **Last-Known-Good:** Bei Parse-Fehlern wird letzte gültige Config verwendet
|
||||||
|
- **Vault Modify Event:** Automatisches Neuladen bei Änderung im Vault
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Chain Templates – Struktur
|
||||||
|
|
||||||
|
- **defaults.matching:** required_links, distinct_nodes, max_candidate_nodes, max_matches_per_template, max_assignments_collected
|
||||||
|
- **defaults.profiles:** discovery, decisioning (min_slots_filled_for_gap_findings, min_score_for_gap_findings)
|
||||||
|
- **templates:** name, slots, links, matching (optional)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Chain Roles – Struktur
|
||||||
|
|
||||||
|
- **roles:** Mapping Role-Name → edge_types[]
|
||||||
|
- **Standard-Rollen:** causal, influences, enables_constraints, provenance, epistemic, normative, structural, temporal
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [06_Konfigurationsdateien_Referenz](../06_Konfigurationsdateien_Referenz.md)
|
||||||
|
- [02_Administratorhandbuch](../02_Administratorhandbuch.md)
|
||||||
28
docs/modules/graph.md
Normal file
28
docs/modules/graph.md
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Modul: Graph
|
||||||
|
|
||||||
|
> **Pfad:** `src/graph/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Graph Building, Traversal, Target Resolution, Report Rendering.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `GraphBuilder.ts` | Baut Graph aus Vault |
|
||||||
|
| `GraphIndex.ts` | Indexierung für Traversal |
|
||||||
|
| `traverse.ts` | BFS/DFS Traversal |
|
||||||
|
| `resolveTarget.ts` | Link → File Auflösung |
|
||||||
|
| `renderChainReport.ts` | Report-Rendering |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [analysis/graphIndex](../analysis.md) – Graph Index für Chain Inspector
|
||||||
47
docs/modules/interview.md
Normal file
47
docs/modules/interview.md
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Modul: Interview
|
||||||
|
|
||||||
|
> **Pfad:** `src/interview/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Interview-Wizard zur strukturierten Erfassung von Inhalten, Section-basierte Ausgabe, Frontmatter-Generierung.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `InterviewConfigLoader.ts` | Lädt interview_config.yaml |
|
||||||
|
| `parseInterviewConfig.ts` | YAML → InterviewConfig Parser |
|
||||||
|
| `wizardState.ts` | Wizard State (Steps, Loops) |
|
||||||
|
| `loopState.ts` | Nested Loops |
|
||||||
|
| `renderer.ts` | Output-Rendering (Section-basiert) |
|
||||||
|
| `writeFrontmatter.ts` | Frontmatter-Generierung |
|
||||||
|
| `sectionKeyResolver.ts` | Section-Key-Auflösung |
|
||||||
|
| `extractTargetFromAnchor.ts` | Target-Extraktion aus Anchors |
|
||||||
|
| `targetTypeResolver.ts` | Note-Type- und Section-Type-Auflösung |
|
||||||
|
| `slugify.ts` | Slug-Generierung für Dateinamen |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Step-Typen
|
||||||
|
|
||||||
|
- `capture_frontmatter`, `capture_text`, `capture_text_line`
|
||||||
|
- `loop`, `review`, `instruction`
|
||||||
|
- `llm_dialog`, `entity_picker` (experimentell)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WP-26 Features
|
||||||
|
|
||||||
|
- `section_type`, `block_id`, `generate_block_id`, `references`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [Interview_Config_Guide](../Interview_Config_Guide.md)
|
||||||
28
docs/modules/lint.md
Normal file
28
docs/modules/lint.md
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
# Modul: Lint
|
||||||
|
|
||||||
|
> **Pfad:** `src/lint/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Linting Engine für Note-Validierung, regelbasierte Prüfungen, Findings.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `LintEngine.ts` | Haupt-Engine |
|
||||||
|
| `rules/` | Einzelne Regeln |
|
||||||
|
| `rule_hub_has_causality.ts` | Kausale Edges prüfen |
|
||||||
|
| `rule_missing_target.ts` | Fehlende Targets |
|
||||||
|
| `rule_unknown_edge.ts` | Unbekannte Edge-Types |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Command
|
||||||
|
|
||||||
|
`mindnet-validate-current-note` – validiert aktuelle Note
|
||||||
32
docs/modules/mapping.md
Normal file
32
docs/modules/mapping.md
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Modul: Mapping
|
||||||
|
|
||||||
|
> **Pfad:** `src/mapping/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Semantic Mapping – Section-basierte Gruppierung von Links nach Edge-Typen, Edge-Type-Assignment.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `semanticMappingBuilder.ts` | Baut Mapping-Blöcke |
|
||||||
|
| `mappingExtractor.ts` | Extrahiert existierende Mappings |
|
||||||
|
| `mappingBuilder.ts` | Erstellt Mapping-Struktur |
|
||||||
|
| `edgeTypeSelector.ts` | Edge-Type-Auswahl (empfohlen via graph_schema) |
|
||||||
|
| `updateMappingBlocks.ts` | Aktualisiert Note |
|
||||||
|
| `sectionParser.ts` | Section-Parsing |
|
||||||
|
| `graphSchema.ts` | Schema-Lookup für Empfehlungen |
|
||||||
|
| `folderHelpers.ts` | Ordner-Hilfsfunktionen |
|
||||||
|
| `worklistBuilder.ts` | Worklist für Pending Assignments |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [06_Konfigurationsdateien_Referenz](../06_Konfigurationsdateien_Referenz.md) – graph_schema
|
||||||
37
docs/modules/parser.md
Normal file
37
docs/modules/parser.md
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Modul: Parser
|
||||||
|
|
||||||
|
> **Pfad:** `src/parser/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Markdown-Parsing: Edges aus Callouts, Frontmatter, Links.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `parseEdgesFromCallouts.ts` | Parst `>> [!edge] type` Callouts, Targets |
|
||||||
|
| `parseFrontmatter.ts` | Frontmatter-Referenz |
|
||||||
|
| `parseRelLinks.ts` | Relative Links in Sections |
|
||||||
|
| `types.ts` | Parser-Typen |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Edge-Callout-Format
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
>> [!edge] resulted_in
|
||||||
|
>> [[#^impact]]
|
||||||
|
>> [[#^learning]]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [mapping/sectionParser](../mapping.md) – Section-Parsing
|
||||||
38
docs/modules/ui.md
Normal file
38
docs/modules/ui.md
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Modul: UI
|
||||||
|
|
||||||
|
> **Pfad:** `src/ui/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
UI-Komponenten: Modals, Settings Tab, Entity Picker, Markdown Toolbar.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `MindnetSettingTab.ts` | Plugin-Einstellungen |
|
||||||
|
| `InterviewWizardModal.ts` | Interview-Wizard |
|
||||||
|
| `ProfileSelectionModal.ts` | Profil-Auswahl |
|
||||||
|
| `EntityPickerModal.ts` | Note/Ordner-Auswahl |
|
||||||
|
| `ChainWorkbenchModal.ts` | Chain Workbench |
|
||||||
|
| `VaultTriageScanModal.ts` | Vault-Triage-Scan |
|
||||||
|
| `EdgeTypeChooserModal.ts` | Edge-Type-Auswahl |
|
||||||
|
| `AdoptNoteModal.ts` | Note-Adoption |
|
||||||
|
| `LinkPromptModal.ts` | Link-Prompt |
|
||||||
|
| `LinkTargetPickerModal.ts` | Link-Ziel-Auswahl |
|
||||||
|
| `ConfirmOverwriteModal.ts` | Überschreibbestätigung |
|
||||||
|
| `InlineEdgeTypeModal.ts` | Inline Edge-Type-Suggester |
|
||||||
|
| `FolderTreeModal.ts` | Ordnerbaum |
|
||||||
|
| `markdownToolbar.ts` | Markdown-Toolbar |
|
||||||
|
| `MindnetView.ts` | Mindnet-View |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [01_Benutzerhandbuch](../01_Benutzerhandbuch.md)
|
||||||
62
docs/modules/unresolvedLink.md
Normal file
62
docs/modules/unresolvedLink.md
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
# Modul: Unresolved Link
|
||||||
|
|
||||||
|
> **Pfad:** `src/unresolvedLink/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Das Unresolved-Link-Modul behandelt das Abfangen von Klicks auf unaufgelöste Links, Note-Adoption und die Normalisierung von Überschriften für Matching.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `unresolvedLinkHandler.ts` | Haupt-Handler für Link-Clicks |
|
||||||
|
| `linkHelpers.ts` | Link-Parsing, Heading-Normalisierung, Matching |
|
||||||
|
| `adoptHelpers.ts` | Note-Adoption-Logik |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Heading-Normalisierung (normalizeHeadingForMatch)
|
||||||
|
|
||||||
|
**Zweck:** Überschriften für Vergleich (Inspect Chains, Chain Workbench) auf kanonische Form bringen.
|
||||||
|
|
||||||
|
### Regeln
|
||||||
|
|
||||||
|
1. **Mit ^Block-ID:** `"Überschrift ^Block"` → `"Überschrift"` (Block-Suffix entfernen)
|
||||||
|
2. **Ohne ^:** Rückgabe unverändert (Idempotenz für bereits normalisierte Formen)
|
||||||
|
|
||||||
|
### Wichtige Eigenschaft: Idempotenz
|
||||||
|
|
||||||
|
`norm(norm(x)) === norm(x)` – mehrfache Normalisierung ändert nichts.
|
||||||
|
|
||||||
|
### Beispiele
|
||||||
|
|
||||||
|
| Input | Output |
|
||||||
|
|-------|--------|
|
||||||
|
| `"Lars ist gut ^PersLars"` | `"Lars ist gut"` |
|
||||||
|
| `"Lars ist gut"` | `"Lars ist gut"` |
|
||||||
|
| `"Nächster Schritt ^next"` | `"Nächster Schritt"` |
|
||||||
|
| `"Überschrift ^Block"` | `"Überschrift"` |
|
||||||
|
|
||||||
|
### headingsMatch
|
||||||
|
|
||||||
|
Vergleicht zwei Überschriften über `normalizeHeadingForMatch` – beide müssen nach Normalisierung identisch sein.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Obsidian-Verhalten
|
||||||
|
|
||||||
|
- **Manuell verlinkt:** Obsidian erzeugt `[[Titel#Überschrift Block]]` (ohne `^`)
|
||||||
|
- **Empfehlung:** Für zuverlässiges Matching Links mit `^` verwenden: `[[Note#Überschrift ^Block]]`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [12_Heading_Block_Link_Recommendation](../12_Heading_Block_Link_Recommendation.md)
|
||||||
|
- [Analysis-Modul](analysis.md) – Nutzung von headingsMatch
|
||||||
32
docs/modules/vocabulary.md
Normal file
32
docs/modules/vocabulary.md
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Modul: Vocabulary
|
||||||
|
|
||||||
|
> **Pfad:** `src/vocab/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Edge Vocabulary Loading, Normalisierung (Alias → Canonical), Inverse Edge Resolution.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `Vocabulary.ts` | Lookup-Methoden |
|
||||||
|
| `VocabularyLoader.ts` | Lädt edge_vocabulary.md |
|
||||||
|
| `parseEdgeVocabulary.ts` | Parst Markdown zu EdgeVocabulary |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Format
|
||||||
|
|
||||||
|
Markdown mit Tabellen oder Callouts. Kanonische Typen, Inverse, Aliases.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [06_Konfigurationsdateien_Referenz](../06_Konfigurationsdateien_Referenz.md) – edge_vocabulary
|
||||||
61
docs/modules/workbench.md
Normal file
61
docs/modules/workbench.md
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
# Modul: Workbench
|
||||||
|
|
||||||
|
> **Pfad:** `src/workbench/`
|
||||||
|
> **Zielgruppe:** Entwickler
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Übersicht
|
||||||
|
|
||||||
|
Das Workbench-Modul implementiert die **Chain Workbench** – eine UI zur Analyse von Ketten und zur Bearbeitung von Lücken (Todos, Actions).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Komponenten
|
||||||
|
|
||||||
|
| Datei | Beschreibung |
|
||||||
|
|-------|--------------|
|
||||||
|
| `ChainWorkbenchModal.ts` | Haupt-Modal (in ui/) |
|
||||||
|
| `workbenchBuilder.ts` | Baut Workbench-Daten aus Template Matches |
|
||||||
|
| `todoGenerator.ts` | Erzeugt Todos (missing_slot, missing_link, weak_roles) |
|
||||||
|
| `statusCalculator.ts` | Berechnet Status (complete, near_complete, partial, weak) |
|
||||||
|
| `zoneDetector.ts` | Erkennt Zonen (note_links, candidates_only) |
|
||||||
|
| `createSectionAction.ts` | Aktion: Sektion erstellen |
|
||||||
|
| `linkExistingAction.ts` | Aktion: Bestehenden Knoten verlinken |
|
||||||
|
| `insertEdgeIntoSectionContent.ts` | Edge in Section-Content einfügen |
|
||||||
|
| `interviewOrchestration.ts` | Orchestriert Interview bei Create-Actions |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vault Triage Scan
|
||||||
|
|
||||||
|
- **Command:** `mindnet-vault-triage-scan`
|
||||||
|
- **Modal:** VaultTriageScanModal
|
||||||
|
- **Sortierung:** near_complete zuerst, dann nach Score absteigend
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Status-Werte
|
||||||
|
|
||||||
|
| Status | Bedingung |
|
||||||
|
|--------|-----------|
|
||||||
|
| `complete` | Slots + Links vollständig |
|
||||||
|
| `near_complete` | 1–2 Links fehlen oder 1 Slot fehlt |
|
||||||
|
| `partial` | Mehrere Lücken |
|
||||||
|
| `weak` | Nur structural/temporal Roles, keine causal Roles |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fix Actions
|
||||||
|
|
||||||
|
- **createMissingNote:** Skeleton, Create+Open, Create+Wizard
|
||||||
|
- **createMissingHeading:** Neues Heading mit konfigurierbarem Level
|
||||||
|
- **promoteCandidate:** Candidate als echten Slot übernehmen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Siehe auch
|
||||||
|
|
||||||
|
- [09_Workbench_Analysis_Basis](../09_Workbench_Analysis_Basis.md)
|
||||||
|
- [10_Workbench_Findings_Integration](../10_Workbench_Findings_Integration.md)
|
||||||
|
- [Analysis-Modul](analysis.md) – Template Matching, Scoring
|
||||||
|
|
@ -102,6 +102,8 @@ export interface HeadingWithType {
|
||||||
heading: string;
|
heading: string;
|
||||||
sectionType: string | null;
|
sectionType: string | null;
|
||||||
level: number;
|
level: number;
|
||||||
|
/** Block-ID from `## Title ^id`; null if the heading has none. */
|
||||||
|
blockId: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getHeadingsWithSectionTypes(
|
export async function getHeadingsWithSectionTypes(
|
||||||
|
|
@ -115,10 +117,11 @@ export async function getHeadingsWithSectionTypes(
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines[i];
|
const line = lines[i];
|
||||||
if (line === undefined) continue;
|
if (line === undefined) continue;
|
||||||
const match = line.match(/^(#{1,6})\s+(.+?)(?:\s*\^[\w-]+)?\s*$/);
|
const match = line.match(/^(#{1,6})\s+(.+?)(?:\s*\^([a-zA-Z0-9_-]+))?\s*$/);
|
||||||
if (match && match[1] && match[2]) {
|
if (match && match[1] && match[2]) {
|
||||||
const level = match[1].length;
|
const level = match[1].length;
|
||||||
const heading = match[2].trim();
|
const heading = match[2].trim();
|
||||||
|
const blockId = match[3] ?? null;
|
||||||
let sectionType: string | null = null;
|
let sectionType: string | null = null;
|
||||||
for (let j = i + 1; j < Math.min(i + 5, lines.length); j++) {
|
for (let j = i + 1; j < Math.min(i + 5, lines.length); j++) {
|
||||||
const nextLine = lines[j];
|
const nextLine = lines[j];
|
||||||
|
|
@ -129,7 +132,7 @@ export async function getHeadingsWithSectionTypes(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.push({ heading, sectionType, level });
|
result.push({ heading, sectionType, level, blockId });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
72
src/main.ts
72
src/main.ts
|
|
@ -383,6 +383,14 @@ export default class MindnetCausalAssistantPlugin extends Plugin {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.addCommand({
|
||||||
|
id: "mindnet-start-interview-current-note",
|
||||||
|
name: "Mindnet: Interview für aktuelle Note starten",
|
||||||
|
callback: async () => {
|
||||||
|
await this.startInterviewForActiveFile();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
this.addCommand({
|
this.addCommand({
|
||||||
id: "mindnet-create-note-from-profile",
|
id: "mindnet-create-note-from-profile",
|
||||||
name: "Mindnet: Create note from profile",
|
name: "Mindnet: Create note from profile",
|
||||||
|
|
@ -852,7 +860,9 @@ export default class MindnetCausalAssistantPlugin extends Plugin {
|
||||||
async (wizardResult: WizardResult) => {
|
async (wizardResult: WizardResult) => {
|
||||||
new Notice("Interview saved and changes applied");
|
new Notice("Interview saved and changes applied");
|
||||||
},
|
},
|
||||||
this // Pass plugin instance for graph schema loading
|
this, // Pass plugin instance for graph schema loading
|
||||||
|
undefined,
|
||||||
|
!isUnresolvedClick
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const msg = e instanceof Error ? e.message : String(e);
|
const msg = e instanceof Error ? e.message : String(e);
|
||||||
|
|
@ -869,6 +879,66 @@ export default class MindnetCausalAssistantPlugin extends Plugin {
|
||||||
return this.createNoteFromProfileAndOpen(result, result.title);
|
return this.createNoteFromProfileAndOpen(result, result.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Start interview wizard on the open note (profile from frontmatter or picker). */
|
||||||
|
private async startInterviewForActiveFile(): Promise<void> {
|
||||||
|
const file = this.app.workspace.getActiveFile();
|
||||||
|
if (!file || file.extension !== "md") {
|
||||||
|
new Notice("Bitte eine Markdown-Notiz öffnen");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = await this.ensureInterviewConfigLoaded();
|
||||||
|
if (!config) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const content = await this.app.vault.read(file);
|
||||||
|
const profileKeyMatch = content.match(/^interview_profile\s*:\s*(.+)$/m);
|
||||||
|
let profileKey = profileKeyMatch?.[1]?.trim() ?? "";
|
||||||
|
if (
|
||||||
|
(profileKey.startsWith('"') && profileKey.endsWith('"')) ||
|
||||||
|
(profileKey.startsWith("'") && profileKey.endsWith("'"))
|
||||||
|
) {
|
||||||
|
profileKey = profileKey.slice(1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const profile = profileKey
|
||||||
|
? config.profiles.find((p) => p.key === profileKey)
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
const openWizard = (chosen: import("./interview/types").InterviewProfile) => {
|
||||||
|
new InterviewWizardModal(
|
||||||
|
this.app,
|
||||||
|
chosen,
|
||||||
|
file,
|
||||||
|
content,
|
||||||
|
async () => {
|
||||||
|
new Notice("Interview completed and changes applied");
|
||||||
|
},
|
||||||
|
async () => {
|
||||||
|
new Notice("Interview saved and changes applied");
|
||||||
|
},
|
||||||
|
this.settings,
|
||||||
|
this
|
||||||
|
).open();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (profile) {
|
||||||
|
openWizard(profile);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new ProfileSelectionModal(
|
||||||
|
this.app,
|
||||||
|
config,
|
||||||
|
async (result) => {
|
||||||
|
openWizard(result.profile);
|
||||||
|
},
|
||||||
|
file.basename,
|
||||||
|
file.parent?.path ?? ""
|
||||||
|
).open();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register unresolved link handlers for Reading View and Live Preview.
|
* Register unresolved link handlers for Reading View and Live Preview.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||||
import { normalizeLinkTarget, normalizeHeadingForMatch, headingsMatch, isUnresolvedLink, waitForFileModify, parseWikilinkAtPosition } from "../../unresolvedLink/linkHelpers";
|
import { normalizeLinkTarget, normalizeHeadingForMatch, headingsMatch, isUnresolvedLink, waitForFileModify, parseWikilinkAtPosition, parseHeadingWithBlockId, formatStableWikilinkTarget, formatStableWikilink } from "../../unresolvedLink/linkHelpers";
|
||||||
import { App, TFile } from "obsidian";
|
import { App, TFile } from "obsidian";
|
||||||
|
|
||||||
describe("normalizeLinkTarget", () => {
|
describe("normalizeLinkTarget", () => {
|
||||||
|
|
@ -59,6 +59,64 @@ describe("normalizeHeadingForMatch", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("parseHeadingWithBlockId", () => {
|
||||||
|
it("splits heading and block-id", () => {
|
||||||
|
expect(parseHeadingWithBlockId("Nächster Schritt ^next")).toEqual({
|
||||||
|
heading: "Nächster Schritt",
|
||||||
|
blockId: "next",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("returns heading only when no block-id", () => {
|
||||||
|
expect(parseHeadingWithBlockId("Nächster Schritt")).toEqual({
|
||||||
|
heading: "Nächster Schritt",
|
||||||
|
blockId: null,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("formatStableWikilinkTarget", () => {
|
||||||
|
it("writes intra-note block ref", () => {
|
||||||
|
expect(formatStableWikilinkTarget({ blockId: "sit" })).toBe("#^sit");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("writes cross-note heading + block (vacation-stable form)", () => {
|
||||||
|
expect(
|
||||||
|
formatStableWikilinkTarget({
|
||||||
|
basename: "Geburt",
|
||||||
|
heading: "Nächster Schritt",
|
||||||
|
blockId: "next",
|
||||||
|
})
|
||||||
|
).toBe("Geburt#Nächster Schritt ^next");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("parses block-id out of heading if passed combined", () => {
|
||||||
|
expect(
|
||||||
|
formatStableWikilinkTarget({
|
||||||
|
basename: "Geburt",
|
||||||
|
heading: "Nächster Schritt ^next",
|
||||||
|
})
|
||||||
|
).toBe("Geburt#Nächster Schritt ^next");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("falls back to heading-only when no block-id", () => {
|
||||||
|
expect(
|
||||||
|
formatStableWikilinkTarget({
|
||||||
|
basename: "Geburt",
|
||||||
|
heading: "Nächster Schritt",
|
||||||
|
})
|
||||||
|
).toBe("Geburt#Nächster Schritt");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("writes note-only link", () => {
|
||||||
|
expect(formatStableWikilinkTarget({ basename: "Geburt" })).toBe("Geburt");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("wraps in brackets", () => {
|
||||||
|
expect(formatStableWikilink({ basename: "Geburt", blockId: "sit" })).toBe("[[Geburt#^sit]]");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("headingsMatch", () => {
|
describe("headingsMatch", () => {
|
||||||
it("matches same heading", () => {
|
it("matches same heading", () => {
|
||||||
expect(headingsMatch("Überschrift", "Überschrift")).toBe(true);
|
expect(headingsMatch("Überschrift", "Überschrift")).toBe(true);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/**
|
/**
|
||||||
* Modal zur Auswahl des Link-Ziels: Ganze Note oder ein Abschnitt (Überschrift inkl. Sektionstyp).
|
* Modal zur Auswahl des Link-Ziels: Ganze Note oder ein Abschnitt (Überschrift inkl. Sektionstyp).
|
||||||
* Wird in der Interview-Toolbar nach der Note-Auswahl angezeigt.
|
* Wird in der Interview-Toolbar nach der Note-Auswahl angezeigt.
|
||||||
* Speichert Link als [[Note]] oder [[Note#Abschnitt]].
|
* Speichert Link als [[Note]], [[Note#Abschnitt ^block]] oder [[Note#Abschnitt]].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { App, Modal, TFile } from "obsidian";
|
import { App, Modal, TFile } from "obsidian";
|
||||||
|
|
@ -10,9 +10,10 @@ import {
|
||||||
resolveTargetTypeForNoteLink,
|
resolveTargetTypeForNoteLink,
|
||||||
type HeadingWithType,
|
type HeadingWithType,
|
||||||
} from "../interview/targetTypeResolver";
|
} from "../interview/targetTypeResolver";
|
||||||
|
import { formatStableWikilinkTarget } from "../unresolvedLink/linkHelpers";
|
||||||
|
|
||||||
export interface LinkTargetPick {
|
export interface LinkTargetPick {
|
||||||
linkTarget: string; // "Note" oder "Note#Abschnitt"
|
linkTarget: string; // "Note", "Note#Abschnitt ^block" oder "Note#Abschnitt"
|
||||||
targetType: string | null;
|
targetType: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -102,7 +103,11 @@ export class LinkTargetPickerModal extends Modal {
|
||||||
.createEl("span", { text: ` (Sektion: ${h.sectionType})`, cls: "target-type" })
|
.createEl("span", { text: ` (Sektion: ${h.sectionType})`, cls: "target-type" })
|
||||||
.style.color = "var(--text-muted)";
|
.style.color = "var(--text-muted)";
|
||||||
}
|
}
|
||||||
const linkTarget = `${this.basename}#${h.heading}`;
|
const linkTarget = formatStableWikilinkTarget({
|
||||||
|
basename: this.basename,
|
||||||
|
heading: h.heading,
|
||||||
|
blockId: h.blockId,
|
||||||
|
});
|
||||||
headingBtn.onclick = () => {
|
headingBtn.onclick = () => {
|
||||||
if (this.resolve) {
|
if (this.resolve) {
|
||||||
this.resolve({ linkTarget, targetType: h.sectionType });
|
this.resolve({ linkTarget, targetType: h.sectionType });
|
||||||
|
|
|
||||||
|
|
@ -465,7 +465,7 @@ export class MindnetSettingTab extends PluginSettingTab {
|
||||||
new Setting(containerEl)
|
new Setting(containerEl)
|
||||||
.setName("Auto-start interview on create")
|
.setName("Auto-start interview on create")
|
||||||
.setDesc(
|
.setDesc(
|
||||||
"Startet automatisch den Interview-Wizard, wenn eine neue Notiz über ein Profil erstellt wird."
|
"Zusätzlich zum Command „Create note from profile“ (der den Wizard immer startet): Wizard auch bei anderen Create-Wegen automatisch öffnen."
|
||||||
)
|
)
|
||||||
.addToggle((toggle) =>
|
.addToggle((toggle) =>
|
||||||
toggle
|
toggle
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,71 @@ export function normalizeHeadingForMatch(heading: string | null): string | null
|
||||||
return s || null;
|
return s || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Split heading text into title and optional trailing block-id.
|
||||||
|
* "Nächster Schritt ^next" → { heading: "Nächster Schritt", blockId: "next" }
|
||||||
|
* "Nächster Schritt" → { heading: "Nächster Schritt", blockId: null }
|
||||||
|
* "^sit" / "#^sit" are not headings; use formatStableWikilinkTarget for those.
|
||||||
|
*/
|
||||||
|
export function parseHeadingWithBlockId(raw: string | null | undefined): {
|
||||||
|
heading: string | null;
|
||||||
|
blockId: string | null;
|
||||||
|
} {
|
||||||
|
if (raw == null) return { heading: null, blockId: null };
|
||||||
|
const s = raw.trim();
|
||||||
|
if (!s) return { heading: null, blockId: null };
|
||||||
|
const match = s.match(/^(.*?)(?:\s*\^([a-zA-Z0-9_-]+))\s*$/);
|
||||||
|
if (match && match[2]) {
|
||||||
|
const heading = (match[1] ?? "").trim();
|
||||||
|
return { heading: heading || null, blockId: match[2] };
|
||||||
|
}
|
||||||
|
return { heading: s, blockId: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StableLinkParts {
|
||||||
|
/** Note basename. Empty/null = intra-note link. */
|
||||||
|
basename?: string | null;
|
||||||
|
heading?: string | null;
|
||||||
|
blockId?: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stable wikilink *target* (without [[ ]]). Prefer this for every write path.
|
||||||
|
* Intra-note + blockId → #^block
|
||||||
|
* Cross-note + heading + blockId → Note#Heading ^block
|
||||||
|
* Cross-note + blockId only → Note#^block
|
||||||
|
* Cross-note + heading only → Note#Heading
|
||||||
|
* Note only → Note
|
||||||
|
*/
|
||||||
|
export function formatStableWikilinkTarget(parts: StableLinkParts): string {
|
||||||
|
const basename = (parts.basename ?? "").trim();
|
||||||
|
let heading = parts.heading?.trim() || null;
|
||||||
|
let blockId = parts.blockId?.trim() || null;
|
||||||
|
if (heading && !blockId) {
|
||||||
|
const parsed = parseHeadingWithBlockId(heading);
|
||||||
|
heading = parsed.heading;
|
||||||
|
blockId = parsed.blockId;
|
||||||
|
} else if (heading && blockId) {
|
||||||
|
heading = parseHeadingWithBlockId(heading).heading ?? heading.replace(/\s*\^[a-zA-Z0-9_-]+\s*$/, "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!basename) {
|
||||||
|
if (blockId) return `#^${blockId}`;
|
||||||
|
if (heading) return `#${heading}`;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (heading && blockId) return `${basename}#${heading} ^${blockId}`;
|
||||||
|
if (blockId) return `${basename}#^${blockId}`;
|
||||||
|
if (heading) return `${basename}#${heading}`;
|
||||||
|
return basename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Same as formatStableWikilinkTarget, wrapped in [[ ]]. */
|
||||||
|
export function formatStableWikilink(parts: StableLinkParts): string {
|
||||||
|
const target = formatStableWikilinkTarget(parts);
|
||||||
|
return target ? `[[${target}]]` : "";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two headings for equality using normalized form (block-id suffix and trailing word stripped).
|
* Compare two headings for equality using normalized form (block-id suffix and trailing word stripped).
|
||||||
* Use for Inspect Chains / Chain Workbench matching only.
|
* Use for Inspect Chains / Chain Workbench matching only.
|
||||||
|
|
|
||||||
|
|
@ -49,12 +49,13 @@ export async function startWizardAfterCreate(
|
||||||
onWizardComplete: (result: any) => void,
|
onWizardComplete: (result: any) => void,
|
||||||
onWizardSave: (result: any) => void,
|
onWizardSave: (result: any) => void,
|
||||||
pluginInstance?: { ensureGraphSchemaLoaded?: () => Promise<import("../mapping/graphSchema").GraphSchema | null> },
|
pluginInstance?: { ensureGraphSchemaLoaded?: () => Promise<import("../mapping/graphSchema").GraphSchema | null> },
|
||||||
initialPendingEdgeAssignments?: import("../interview/wizardState").PendingEdgeAssignment[]
|
initialPendingEdgeAssignments?: import("../interview/wizardState").PendingEdgeAssignment[],
|
||||||
|
forceStart = false
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
// Determine if wizard should start
|
// Determine if wizard should start
|
||||||
const shouldStartInterview = isUnresolvedClick
|
const shouldStartInterview = forceStart || (isUnresolvedClick
|
||||||
? (settings.autoStartOnUnresolvedClick || settings.autoStartInterviewOnCreate)
|
? (settings.autoStartOnUnresolvedClick || settings.autoStartInterviewOnCreate)
|
||||||
: settings.autoStartInterviewOnCreate;
|
: settings.autoStartInterviewOnCreate);
|
||||||
|
|
||||||
if (!shouldStartInterview) {
|
if (!shouldStartInterview) {
|
||||||
if (settings.debugLogging) {
|
if (settings.debugLogging) {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import { EntityPickerModal } from "../ui/EntityPickerModal";
|
||||||
import { NoteIndex } from "../entityPicker/noteIndex";
|
import { NoteIndex } from "../entityPicker/noteIndex";
|
||||||
import { detectZoneFromContent } from "./zoneDetector";
|
import { detectZoneFromContent } from "./zoneDetector";
|
||||||
import { removeBlanksAndInsert } from "./edgeInsertHelper";
|
import { removeBlanksAndInsert } from "./edgeInsertHelper";
|
||||||
|
import { formatStableWikilinkTarget } from "../unresolvedLink/linkHelpers";
|
||||||
|
import { slugify } from "../interview/slugify";
|
||||||
|
|
||||||
/** Common section/node types for dropdown when slot has no allowed_node_types. */
|
/** Common section/node types for dropdown when slot has no allowed_node_types. */
|
||||||
const FALLBACK_SECTION_TYPES = [
|
const FALLBACK_SECTION_TYPES = [
|
||||||
|
|
@ -130,9 +132,10 @@ export async function createSectionInNote(
|
||||||
sectionContent += `> [!${wrapperType}]${foldMarker}${wrapperTitle ? ` ${wrapperTitle}` : ""}\n`;
|
sectionContent += `> [!${wrapperType}]${foldMarker}${wrapperTitle ? ` ${wrapperTitle}` : ""}\n`;
|
||||||
|
|
||||||
for (const edge of result.initialEdges) {
|
for (const edge of result.initialEdges) {
|
||||||
const targetLink = edge.targetHeading
|
const targetLink = formatStableWikilinkTarget({
|
||||||
? `${edge.targetNote}#${edge.targetHeading}`
|
basename: edge.targetNote,
|
||||||
: edge.targetNote;
|
heading: edge.targetHeading,
|
||||||
|
});
|
||||||
sectionContent += `>> [!edge] ${edge.edgeType}\n>> [[${targetLink}]]\n`;
|
sectionContent += `>> [!edge] ${edge.edgeType}\n>> [[${targetLink}]]\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,13 +162,11 @@ export async function createSectionInNote(
|
||||||
|
|
||||||
// Gegenkanten in den anderen Notes einfügen (Vorwärts- bzw. Rückwärtskante)
|
// Gegenkanten in den anderen Notes einfügen (Vorwärts- bzw. Rückwärtskante)
|
||||||
const sourcePath = result.targetFilePath.replace(/\.md$/, "");
|
const sourcePath = result.targetFilePath.replace(/\.md$/, "");
|
||||||
const sourceFragment =
|
const sourceLink = formatStableWikilinkTarget({
|
||||||
result.blockId && result.heading
|
basename: sourcePath,
|
||||||
? `${result.heading} ^${result.blockId}`
|
heading: result.heading,
|
||||||
: result.blockId
|
blockId: result.blockId,
|
||||||
? `^${result.blockId}`
|
});
|
||||||
: result.heading ?? "";
|
|
||||||
const sourceLink = sourceFragment ? `${sourcePath}#${sourceFragment}` : sourcePath;
|
|
||||||
|
|
||||||
for (const edge of result.initialEdges) {
|
for (const edge of result.initialEdges) {
|
||||||
const otherPathRaw = edge.targetNote.replace(/\.md$/, "");
|
const otherPathRaw = edge.targetNote.replace(/\.md$/, "");
|
||||||
|
|
@ -553,10 +554,10 @@ async function showCreateSectionModal(
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Block ID (optional)
|
// Block ID — auto from heading if left empty (stable links for later ingest)
|
||||||
new Setting(contentEl)
|
new Setting(contentEl)
|
||||||
.setName("Block-ID (optional)")
|
.setName("Block-ID")
|
||||||
.setDesc("z. B. learning, insight-1")
|
.setDesc("Pflicht für stabile Links. Leer = aus der Überschrift erzeugt.")
|
||||||
.addText((text) => {
|
.addText((text) => {
|
||||||
text.setValue("").onChange((value) => {
|
text.setValue("").onChange((value) => {
|
||||||
this.blockId = value.trim();
|
this.blockId = value.trim();
|
||||||
|
|
@ -616,6 +617,12 @@ async function showCreateSectionModal(
|
||||||
new Notice("Bitte eine Ziel-Note wählen");
|
new Notice("Bitte eine Ziel-Note wählen");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const heading = this.heading.trim();
|
||||||
|
const blockId = this.blockId || slugify(heading);
|
||||||
|
if (!blockId) {
|
||||||
|
new Notice("Block-ID fehlt und konnte nicht aus der Überschrift erzeugt werden");
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.initialEdges = requiredEdges.map((e, i) => ({
|
this.initialEdges = requiredEdges.map((e, i) => ({
|
||||||
edgeType: this.chosenEdgeTypes[i] ?? e.suggestedAlias ?? e.edgeType,
|
edgeType: this.chosenEdgeTypes[i] ?? e.suggestedAlias ?? e.edgeType,
|
||||||
targetNote: e.targetNote,
|
targetNote: e.targetNote,
|
||||||
|
|
@ -625,8 +632,8 @@ async function showCreateSectionModal(
|
||||||
}));
|
}));
|
||||||
this.result = {
|
this.result = {
|
||||||
targetFilePath: this.targetFilePath,
|
targetFilePath: this.targetFilePath,
|
||||||
heading: this.heading.trim(),
|
heading,
|
||||||
blockId: this.blockId || null,
|
blockId,
|
||||||
sectionType: this.sectionType || null,
|
sectionType: this.sectionType || null,
|
||||||
sectionBody: this.sectionBody,
|
sectionBody: this.sectionBody,
|
||||||
initialEdges: this.initialEdges,
|
initialEdges: this.initialEdges,
|
||||||
|
|
|
||||||
|
|
@ -184,7 +184,8 @@ export async function createNoteViaInterview(
|
||||||
new Notice("Wizard saved");
|
new Notice("Wizard saved");
|
||||||
},
|
},
|
||||||
pluginInstance,
|
pluginInstance,
|
||||||
pendingEdgeAssignments // Pass initial edge assignments to wizard
|
pendingEdgeAssignments,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,14 @@
|
||||||
* Link existing action for missing_slot todos.
|
* Link existing action for missing_slot todos.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Notice } from "obsidian";
|
import { Notice, TFile } from "obsidian";
|
||||||
import type { App, Editor, TFile } from "obsidian";
|
import type { App, Editor } from "obsidian";
|
||||||
import type { MissingSlotTodo } from "./types";
|
import type { MissingSlotTodo } from "./types";
|
||||||
import { EntityPickerModal } from "../ui/EntityPickerModal";
|
import { EntityPickerModal } from "../ui/EntityPickerModal";
|
||||||
|
import { LinkTargetPickerModal } from "../ui/LinkTargetPickerModal";
|
||||||
import { NoteIndex } from "../entityPicker/noteIndex";
|
import { NoteIndex } from "../entityPicker/noteIndex";
|
||||||
import { findSection } from "./zoneDetector";
|
import { findSection } from "./zoneDetector";
|
||||||
|
import { formatStableWikilink } from "../unresolvedLink/linkHelpers";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link existing note/section to fill missing slot.
|
* Link existing note/section to fill missing slot.
|
||||||
|
|
@ -56,7 +58,15 @@ export async function linkExisting(
|
||||||
// This is a placeholder - the real implementation would need to update the match
|
// This is a placeholder - the real implementation would need to update the match
|
||||||
|
|
||||||
const targetNote = selectedNote.basename.replace(/\.md$/, "");
|
const targetNote = selectedNote.basename.replace(/\.md$/, "");
|
||||||
const linkText = `[[${targetNote}]]`;
|
let linkText = formatStableWikilink({ basename: targetNote });
|
||||||
|
const pickedFile = app.vault.getAbstractFileByPath(selectedNote.path);
|
||||||
|
if (pickedFile instanceof TFile) {
|
||||||
|
const picker = new LinkTargetPickerModal(app, pickedFile, targetNote, file.path);
|
||||||
|
const pick = await picker.show();
|
||||||
|
if (pick?.linkTarget) {
|
||||||
|
linkText = `[[${pick.linkTarget}]]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Insert link at cursor position
|
// Insert link at cursor position
|
||||||
const cursor = editor.getCursor();
|
const cursor = editor.getCursor();
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import type { Vocabulary } from "../vocab/Vocabulary";
|
||||||
import type { EdgeVocabulary } from "../vocab/types";
|
import type { EdgeVocabulary } from "../vocab/types";
|
||||||
import type { MindnetSettings } from "../settings";
|
import type { MindnetSettings } from "../settings";
|
||||||
import { computeSectionContentAfterInsertEdge } from "./insertEdgeIntoSectionContent";
|
import { computeSectionContentAfterInsertEdge } from "./insertEdgeIntoSectionContent";
|
||||||
import { headingsMatch } from "../unresolvedLink/linkHelpers";
|
import { formatStableWikilinkTarget, headingsMatch } from "../unresolvedLink/linkHelpers";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert edge forward (from source to target).
|
* Insert edge forward (from source to target).
|
||||||
|
|
@ -68,9 +68,10 @@ export async function insertEdgeForward(
|
||||||
|
|
||||||
// Build target link (extract basename from file path)
|
// Build target link (extract basename from file path)
|
||||||
const targetBasename = todo.toNodeRef.file.replace(/\.md$/, "").split("/").pop() || todo.toNodeRef.file;
|
const targetBasename = todo.toNodeRef.file.replace(/\.md$/, "").split("/").pop() || todo.toNodeRef.file;
|
||||||
const targetLink = todo.toNodeRef.heading
|
const targetLink = formatStableWikilinkTarget({
|
||||||
? `${targetBasename}#${todo.toNodeRef.heading}`
|
basename: targetBasename,
|
||||||
: targetBasename;
|
heading: todo.toNodeRef.heading,
|
||||||
|
});
|
||||||
|
|
||||||
if (debugLogging) {
|
if (debugLogging) {
|
||||||
console.log("[insertEdgeForward] Target link:", targetLink);
|
console.log("[insertEdgeForward] Target link:", targetLink);
|
||||||
|
|
@ -486,9 +487,10 @@ async function createInverseEdge(
|
||||||
|
|
||||||
// Build source link (for inverse edge, source is the original target)
|
// Build source link (for inverse edge, source is the original target)
|
||||||
const sourceBasename = todo.fromNodeRef.file.replace(/\.md$/, "").split("/").pop() || todo.fromNodeRef.file;
|
const sourceBasename = todo.fromNodeRef.file.replace(/\.md$/, "").split("/").pop() || todo.fromNodeRef.file;
|
||||||
const sourceLink = todo.fromNodeRef.heading
|
const sourceLink = formatStableWikilinkTarget({
|
||||||
? `${sourceBasename}#${todo.fromNodeRef.heading}`
|
basename: sourceBasename,
|
||||||
: sourceBasename;
|
heading: todo.fromNodeRef.heading,
|
||||||
|
});
|
||||||
|
|
||||||
// Always ask user to select target section (or whole note)
|
// Always ask user to select target section (or whole note)
|
||||||
// Open target file in editor first
|
// Open target file in editor first
|
||||||
|
|
@ -973,9 +975,10 @@ export async function promoteCandidate(
|
||||||
// Find candidate edge in zone
|
// Find candidate edge in zone
|
||||||
const candidateEdge = todo.candidateEdge;
|
const candidateEdge = todo.candidateEdge;
|
||||||
const edgeType = candidateEdge.rawEdgeType;
|
const edgeType = candidateEdge.rawEdgeType;
|
||||||
const targetLink = candidateEdge.to.heading
|
const targetLink = formatStableWikilinkTarget({
|
||||||
? `[[${candidateEdge.to.file}#${candidateEdge.to.heading}]]`
|
basename: candidateEdge.to.file,
|
||||||
: `[[${candidateEdge.to.file}]]`;
|
heading: candidateEdge.to.heading,
|
||||||
|
});
|
||||||
|
|
||||||
// Determine source section (from evidence or current context)
|
// Determine source section (from evidence or current context)
|
||||||
const sourceSectionHeading = candidateEdge.evidence.sectionHeading;
|
const sourceSectionHeading = candidateEdge.evidence.sectionHeading;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user