diff --git a/Attribute-Garbage-Collector/README.md b/Attribute-Garbage-Collector/README.md index 51aaf6f..b154e89 100644 --- a/Attribute-Garbage-Collector/README.md +++ b/Attribute-Garbage-Collector/README.md @@ -1,49 +1,18 @@ # Attribute GC — TriliumNext Maintenance Tool -A garbage collector for TriliumNext attributes. Scans all notes to find broken relations, unused labels, rare attributes, and near-duplicate names. Lets you preview and safely delete them — either individually or in batch. +A garbage collector for TriliumNext attributes. Scans all notes to find broken relations, unused labels, rare attributes, and near-duplicate names. Lets you preview them in a dashboard — with batch delete on classic Trilium. + +> **⚠ Status (TriliumNext)**: Detection works fully — all 83 notes, 66+ attribute groups scanned via `froca`. Deletion in the UI succeeds (cache is updated, re-scan confirms), but **changes are lost on page reload** because TriliumNext's frontend froca cache doesn't sync writes back to the server in the Render Note sandbox. Classic Trilium (`api.runOnBackend`) path works end-to-end. See [Persistence issue](#-persistence-issue-triliumnext). ## Features -- **Full scan** — Reads all notes via `froca` (TriliumNext frontend cache) or `api.runOnBackend` (classic Trilium). Classifies every label and relation by usage count and health. +- **Full scan** — Reads all notes via `froca` (TriliumNext) or `api.runOnBackend` (classic Trilium). Classifies every label and relation by usage count and health. - **Broken relation detection** — Finds relations pointing to deleted or missing target notes. - **Rare attribute flagging** — Highlights attributes used ≤2 times, plus temp/draft/test patterns. - **Semantic duplicate finder** — Uses Levenshtein distance to surface near-identical names (`pipeline` vs `pipelne`, `autor` vs `autores`). - **Dry run mode** — Toggle on to preview what would be deleted without making changes. -- **Batch operations** — Auto-select all problematic attributes, then delete them in one click. -- **Scoped CSS** — All styles are prefixed under `#attrgc-root` so nothing leaks into the Trilium UI. - ---- - -## 🌐 Language / Idioma - -**Note on language:** Since I am from Brazil, the interface and text within this tool are currently in **Brazilian Portuguese (PT-BR)**. -However, you can easily translate them to English or your preferred language by simply opening the code files inside Trilium and replacing the text strings. - ---- - -## How it works - -### Scan (read) - -``` -glob.getActiveContextNote() → froca → froca.notes / froca.attributes -``` - -The note accesses TriliumNext's frontend object cache directly. All notes and their attributes are already in memory — no backend calls needed. - -### Delete (write) - -``` -note.getOwnedAttributes(type, name) → attr.update({ isDeleted: true }) -``` - -Finds attribute objects on each note via the standard prototype method, then marks them deleted through the entity's own `update()` method. The change syncs to the backend automatically. - -For **relations**, only broken instances (target note missing or deleted) are removed. For **labels**, all instances of that name are removed. - -### Classic Trilium fallback - -If `api.runOnBackend` is available (classic Trilium), the tool uses SQL for scanning and `removeLabel` / `removeRelation` for deletion. +- **Batch selection** — Auto-select all problematic attributes with one click. +- **Scoped CSS** — All styles are prefixed under `#attrgc-root` — nothing leaks into the Trilium UI. ## Installation @@ -57,10 +26,65 @@ If `api.runOnBackend` is available (classic Trilium), the tool uses SQL for scan 2. Use the filter tabs (**Quebrados**, **Raros**, **Sem uso**, **Sistema**) and search bar to narrow down. 3. Click **Auto-selecionar problemáticos** to check all non-system problematic attributes, or tick individual checkboxes. 4. **Toggle Dry Run OFF** (the yellow banner disappears). -5. Click **Executar limpeza** → confirm the dialog. The tool removes the selected attributes. -6. A green banner flashes briefly, and a re-scan runs to confirm the new counts. +5. Click **Executar limpeza** → confirm. The tool attempts to delete and runs a re-scan. -The individual **remover** button on each row works the same way — skips the batch dialog. +> In classic Trilium, deletion persists to the database. In TriliumNext, the re-scan will show the attributes gone from the cache, but they reappear on reload (see below). + +## Compatibility + +| Environment | Scan | Delete | Notes | +|---|---|---|---| +| **Classic Trilium** | `api.sql.getRows` | `note.removeLabel` / `note.removeRelation` | Full end-to-end. | +| **TriliumNext** | `froca.notes` | `attr.update({ isDeleted: true })` | Detects everything. Delete works in UI but **not persisted**. | +| **Browser (demo)** | Mock data | Simulated (noop) | For testing outside Trilium. | + +## ⚠ Persistence issue (TriliumNext) + +### What works + +- The froca path scans all 83 notes and 66+ attribute groups correctly. +- `note.getOwnedAttributes(type, name)` returns proper `FAttribute` objects. +- `attr.update({ isDeleted: true })` marks attributes deleted in the frontend cache. +- The re-scan confirms the deletions (groups count drops). +- `_clw.confirmSaveRelations()` exists and returns a Promise (talks to backend), but is scope-limited to the relations panel and doesn't propagate general attribute deletions. + +### What doesn't + +- On page reload, the froca cache is rebuilt from the server — deleted attributes reappear. +- `attr.update()` and `note.update()` are synchronous and local-only (no backend RPC). +- `note.executeScript()` only works on script-type notes, not on arbitrary text/HTML notes. +- `api.runOnBackend` is not exposed in the Render Note sandbox (it's available to JS Frontend notes via `frontend_script_api-*.js`, but not to `