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).
- **Full scan** — Reads all notes via `froca` (TriliumNext) or `api.runOnBackend` (classic Trilium). Classifies every label and relation by usage count and health.
> 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).
-`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.
- 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 `<script>` tags in HTML Render Notes).
- The REST API (`/api/notes`, `/api/tree`) returns 401 — `glob.getHeaders()` returns an empty object, and session cookies + CSRF token don't authenticate from the sandbox.
1.**JS Backend note approach**: Create a temporary JS Backend note, put the deletion script in it, execute via `note.executeScript()`, then delete the temp note.
2.**Proxy note mutations**: Find how the TriliumNext UI (e.g. relation map) communicates attribute changes to the server and replicate that protocol.
3.**Module import**: If dynamic `import()` is available from Render Notes, try importing `frontend_script_api-*.js` to access `runOnBackend` directly.
The Render Note accesses TriliumNext's frontend object cache (`froca`) via the active context note. All notes and their attributes are already in memory — no backend calls needed. Broken relations are detected by building a `Set` of all valid `noteId`s and checking whether each relation's target exists.
### Scan (Classic Trilium — SQL path)
If `api.runOnBackend` is detected, the tool runs SQL aggregation queries directly for maximum performance.
**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.