- Added a new command to fix findings in the current section of a markdown file, enhancing user experience by automating issue resolution. - Introduced settings for configuring actions related to missing notes and headings, allowing for customizable behavior during the fixing process. - Enhanced the chain inspector to support template matching, providing users with insights into template utilization and potential gaps in their content. - Updated the analysis report to include detailed metadata about edges and role matches, improving the clarity and usefulness of inspection results. - Improved error handling and user notifications for fixing findings and template matching processes, ensuring better feedback during execution.
286 lines
9.8 KiB
Markdown
286 lines
9.8 KiB
Markdown
# Chain Inspector v0.2 - Implementierungsbericht
|
|
|
|
**Status:** ✅ Vollständig implementiert und getestet
|
|
**Datum:** 2025-01-XX
|
|
**Version:** v0.2.0
|
|
**Basiert auf:** Chain Inspector v0.1.0
|
|
|
|
---
|
|
|
|
## Übersicht
|
|
|
|
Chain Inspector v0.2 erweitert v0 um drei wichtige Features für höhere ROI:
|
|
1. **Alias-aware Role Classification** - Interne Mapping von Edge-Aliases zu canonical types für präzisere Rollen-Erkennung
|
|
2. **Dangling Target Detection** - Erkennung von fehlenden Dateien und Headings in Edge-Links
|
|
3. **Analysis Meta** - Zusätzliche Metriken für einfacheres Debugging und Coverage-Analyse
|
|
|
|
## Neue Features
|
|
|
|
### 1. Alias-aware Role Classification
|
|
|
|
**Zweck:** Verbesserte Erkennung von "causal-ish" Rollen auch wenn Vault Aliases verwendet.
|
|
|
|
**Implementierung:**
|
|
- Lädt `edge_vocabulary.md` via `VocabularyLoader` (wenn `edgeVocabularyPath` in Settings konfiguriert)
|
|
- `resolveCanonicalEdgeType(rawEdgeType, edgeVocabulary)` Funktion:
|
|
- Prüft ob `rawEdgeType` bereits canonical ist
|
|
- Prüft ob `rawEdgeType` ein Alias ist (case-insensitive lookup)
|
|
- Gibt `{ canonical?, matchedBy: "canonical" | "alias" | "none" }` zurück
|
|
- `no_causal_roles` Finding verwendet jetzt canonical types:
|
|
- Zuerst Prüfung mit canonical type (falls verfügbar)
|
|
- Fallback auf raw type (permissiv)
|
|
- Funktioniert auch wenn `chain_roles.yaml` nur canonical types listet
|
|
|
|
**Beispiel:**
|
|
- Vault verwendet: `ausgelöst_durch` (Alias)
|
|
- `edge_vocabulary.md` mappt: `ausgelöst_durch` → `caused_by` (canonical)
|
|
- `chain_roles.yaml` listet nur: `caused_by` (canonical)
|
|
- **Ergebnis:** `no_causal_roles` Finding wird NICHT generiert (korrekt erkannt)
|
|
|
|
### 2. Dangling Target Finding
|
|
|
|
**Zweck:** Erkennung von fehlerhaften Links in Edge-Targets.
|
|
|
|
**Implementierung:**
|
|
- Prüft alle outgoing edges von aktueller Section (respektiert `includeNoteLinks`/`includeCandidates` Toggles)
|
|
- **`dangling_target`** (Severity: `error`):
|
|
- Prüft ob Target-Datei existiert via `app.metadataCache.getFirstLinkpathDest()`
|
|
- Wenn Datei nicht gefunden → Finding mit `error` Severity
|
|
- **`dangling_target_heading`** (Severity: `warn`):
|
|
- Wenn Target Heading angegeben (`[[file#Heading]]`):
|
|
- Prüft ob Heading in existierender Datei vorhanden ist
|
|
- Nutzt `app.metadataCache.getFileCache()` für Heading-Liste
|
|
- Wenn Heading fehlt → Finding mit `warn` Severity
|
|
- Evidence enthält:
|
|
- `file`: Source file (aktuelle Datei)
|
|
- `sectionHeading`: Source section heading
|
|
|
|
**Beispiel:**
|
|
```
|
|
> [!edge] causes
|
|
> [[MissingNote]] → dangling_target (error)
|
|
|
|
> [!edge] causes
|
|
> [[ExistingNote#MissingHeading]] → dangling_target_heading (warn)
|
|
```
|
|
|
|
### 3. Analysis Meta
|
|
|
|
**Zweck:** Zusätzliche Metriken für Debugging und Coverage-Analyse.
|
|
|
|
**Implementierung:**
|
|
- Wird zu jedem `ChainInspectorReport` hinzugefügt
|
|
- Enthält:
|
|
- `edgesTotal`: Gesamtanzahl gefilterter Edges (nach `includeNoteLinks`/`includeCandidates`)
|
|
- `edgesWithCanonical`: Anzahl Edges mit erfolgreichem canonical mapping
|
|
- `edgesUnmapped`: Anzahl Edges ohne mapping (weder canonical noch alias)
|
|
- `roleMatches`: Anzahl Matches pro Role (deterministisch sortiert)
|
|
- Deterministische Sortierung:
|
|
- `roleMatches` Keys werden alphabetisch sortiert
|
|
- Konsistente Ausgabe für Golden Tests
|
|
|
|
**Beispiel Output:**
|
|
```json
|
|
"analysisMeta": {
|
|
"edgesTotal": 13,
|
|
"edgesWithCanonical": 13,
|
|
"edgesUnmapped": 0,
|
|
"roleMatches": {
|
|
"causal": 3,
|
|
"influences": 2,
|
|
"structural": 6
|
|
}
|
|
}
|
|
```
|
|
|
|
## Technische Implementierung
|
|
|
|
### Geänderte Dateien
|
|
|
|
#### `src/analysis/chainInspector.ts`
|
|
- **Neue Funktion:** `resolveCanonicalEdgeType()`
|
|
- **Erweiterte Funktion:** `computeFindings()`
|
|
- Parameter: `edgeVocabulary: EdgeVocabulary | null`, `app: App` hinzugefügt
|
|
- Implementierung: `dangling_target` und `dangling_target_heading` Checks
|
|
- Update: `no_causal_roles` verwendet canonical types
|
|
- **Erweiterte Funktion:** `inspectChains()`
|
|
- Parameter: `edgeVocabularyPath?: string` hinzugefügt
|
|
- Lädt Edge Vocabulary wenn Path bereitgestellt
|
|
- Berechnet `analysisMeta` mit deterministischer Sortierung
|
|
- **Erweitertes Interface:** `ChainInspectorReport`
|
|
- Neues Feld: `analysisMeta?: { edgesTotal, edgesWithCanonical, edgesUnmapped, roleMatches }`
|
|
|
|
#### `src/commands/inspectChainsCommand.ts`
|
|
- **Erweiterte Funktion:** `formatReport()`
|
|
- Zeigt `analysisMeta` Sektion im Pretty-Print
|
|
- **Erweiterte Funktion:** `executeInspectChains()`
|
|
- Parameter: `settings: MindnetSettings` hinzugefügt
|
|
- Übergibt `settings.edgeVocabularyPath` an `inspectChains()`
|
|
|
|
#### `src/main.ts`
|
|
- **Update:** Aufruf von `executeInspectChains()` erweitert um `settings` Parameter
|
|
|
|
#### `src/tests/analysis/chainInspector.test.ts`
|
|
- **4 neue Tests:**
|
|
1. `should use canonical types for causal role detection when aliases are used`
|
|
2. `should detect dangling_target for missing file`
|
|
3. `should detect dangling_target_heading for missing heading`
|
|
4. `should produce deterministic analysisMeta ordering`
|
|
- **Mock-Erweiterungen:**
|
|
- `VocabularyLoader` gemockt
|
|
- `metadataCache` Methoden erweitert
|
|
|
|
### Neue Abhängigkeiten
|
|
|
|
- `edge_vocabulary.md`: Wird für canonical mapping verwendet (optional, aber empfohlen)
|
|
- `VocabularyLoader`: Lädt Edge Vocabulary Text
|
|
- `parseEdgeVocabulary`: Parst Edge Vocabulary Markdown
|
|
|
|
## Test-Ergebnisse
|
|
|
|
### Erfolgreiche Tests (11/11)
|
|
|
|
✅ **Alias-aware Role Classification:**
|
|
- Test: Verwendet Alias `ausgelöst_durch`, chain_roles nur canonical `caused_by`
|
|
- Ergebnis: `no_causal_roles` Finding wird NICHT generiert (korrekt)
|
|
- `analysisMeta.edgesWithCanonical` > 0
|
|
|
|
✅ **Dangling Target Detection:**
|
|
- Test: Link auf `[[MissingNote]]` (Datei existiert nicht)
|
|
- Ergebnis: `dangling_target` Finding mit `error` Severity korrekt erkannt
|
|
|
|
✅ **Dangling Target Heading Detection:**
|
|
- Test: Link auf `[[ExistingNote#MissingHeading]]` (Datei existiert, Heading fehlt)
|
|
- Ergebnis: `dangling_target_heading` Finding mit `warn` Severity korrekt erkannt
|
|
|
|
✅ **Deterministic Analysis Meta:**
|
|
- Test: Zwei identische Aufrufe mit gemischten Aliases
|
|
- Ergebnis: `analysisMeta` identisch, `roleMatches` Keys sortiert
|
|
|
|
### Beispiel-Output (aus realem Vault)
|
|
|
|
```
|
|
=== Chain Inspector Report ===
|
|
|
|
Context: 03_Experiences/Clusters/Wendepunkte/Ereignisse die mein Leben verändert haben.md
|
|
Section: 28.11.2007 und 30.01.2011 Geburt unserer beiden Söhne
|
|
Zone: content
|
|
|
|
Settings:
|
|
- Include Note Links: true
|
|
- Include Candidates: false
|
|
- Max Depth: 3
|
|
- Direction: both
|
|
|
|
Neighbors:
|
|
Incoming: 1
|
|
- part_of -> 03_Experiences/persönliche Erfahrungen.md#Zentrale Prägungen [section]
|
|
Outgoing: 2
|
|
- basiert_auf -> Geburt unserer Kinder Rouven und Rohan [section]
|
|
- wirkt_auf -> Rolle Vater von zwei Söhnen [section]
|
|
|
|
Paths:
|
|
Forward: 2
|
|
- ... -> Geburt unserer Kinder Rouven und Rohan (1 edges)
|
|
- ... -> Rolle Vater von zwei Söhnen (1 edges)
|
|
Backward: 1
|
|
- 03_Experiences/persönliche Erfahrungen.md#Zentrale Prägungen -> ... (1 edges)
|
|
|
|
Gap Heuristics (Findings): 1
|
|
❌ [ERROR] dangling_target: Target file does not exist: Geburt unserer Kinder Rouven und Rohan
|
|
|
|
Analysis Meta:
|
|
- Edges Total: 13
|
|
- Edges With Canonical: 13
|
|
- Edges Unmapped: 0
|
|
- Role Matches:
|
|
- causal: 3
|
|
- influences: 2
|
|
- structural: 6
|
|
```
|
|
|
|
## Bekannte Einschränkungen
|
|
|
|
1. **Trash Detection:** Dateien im `.trash` Ordner werden als "nicht existierend" erkannt (korrektes Verhalten)
|
|
2. **Heading Cache:** Wenn `metadataCache.getFileCache()` nicht verfügbar ist, wird Heading-Check übersprungen (akzeptabel, da Cache später aktualisiert wird)
|
|
3. **Case Sensitivity:** Alias-Matching ist case-insensitive, aber File-Matching kann case-sensitive sein (abhängig von Obsidian-Konfiguration)
|
|
|
|
## Verwendung
|
|
|
|
### In Obsidian
|
|
|
|
1. Öffnen Sie eine Markdown-Datei mit Edges
|
|
2. Positionieren Sie den Cursor in einer Section
|
|
3. Öffnen Sie die Command Palette (Strg+P / Cmd+P)
|
|
4. Wählen Sie: **"Mindnet: Inspect Chains (Current Section)"**
|
|
5. Prüfen Sie die Console (Strg+Shift+I / Cmd+Option+I) für den Report
|
|
|
|
**Erwartete Ausgabe:**
|
|
- `analysisMeta` Sektion zeigt Mapping-Coverage
|
|
- `dangling_target` Findings für fehlende Dateien/Headings
|
|
- `no_causal_roles` sollte nicht triggern wenn Aliases zu canonical causal types gemappt werden
|
|
|
|
### Programmatisch
|
|
|
|
```typescript
|
|
import { executeInspectChains } from "./commands/inspectChainsCommand";
|
|
|
|
await executeInspectChains(
|
|
app,
|
|
editor,
|
|
filePath,
|
|
chainRoles, // ChainRolesConfig | null
|
|
settings, // MindnetSettings (für edgeVocabularyPath)
|
|
{
|
|
includeNoteLinks: true,
|
|
includeCandidates: false,
|
|
maxDepth: 3,
|
|
direction: "both"
|
|
}
|
|
);
|
|
```
|
|
|
|
## Konfiguration
|
|
|
|
### Erforderliche Settings
|
|
|
|
- `edgeVocabularyPath`: Pfad zu `edge_vocabulary.md` (Standard: `"_system/dictionary/edge_vocabulary.md"`)
|
|
- `chainRolesPath`: Pfad zu `chain_roles.yaml` (Standard: `"_system/dictionary/chain_roles.yaml"`)
|
|
|
|
### Optional
|
|
|
|
- `chainTemplatesPath`: Wird noch nicht verwendet (für zukünftige Features)
|
|
|
|
## Vergleich v0.1 vs v0.2
|
|
|
|
| Feature | v0.1 | v0.2 |
|
|
|---------|------|------|
|
|
| Neighbors (incoming/outgoing) | ✅ | ✅ |
|
|
| Forward/Backward Paths | ✅ | ✅ |
|
|
| Gap Heuristics (basic) | ✅ | ✅ |
|
|
| Alias-aware Role Classification | ❌ | ✅ |
|
|
| Dangling Target Detection | ❌ | ✅ |
|
|
| Analysis Meta | ❌ | ✅ |
|
|
| Edge Vocabulary Integration | ❌ | ✅ |
|
|
|
|
## Zusammenfassung
|
|
|
|
Chain Inspector v0.2 erweitert v0 erfolgreich um:
|
|
|
|
✅ **Alias-aware Role Classification** - Präzisere Rollen-Erkennung auch bei Alias-Verwendung
|
|
✅ **Dangling Target Detection** - Automatische Erkennung fehlerhafter Links
|
|
✅ **Analysis Meta** - Zusätzliche Metriken für Debugging und Coverage-Analyse
|
|
|
|
**Alle Tests bestehen** (11/11)
|
|
**TypeScript kompiliert ohne Fehler**
|
|
**Keine Linter-Fehler**
|
|
**Production Ready** ✅
|
|
|
|
Die Implementierung bildet eine solide Grundlage für weitere Chain Intelligence Features in Phase 2.
|
|
|
|
---
|
|
|
|
**Erstellt:** 2025-01-XX
|
|
**Autor:** Cursor AI Agent
|
|
**Status:** ✅ Production Ready
|