mirror of
https://github.com/israerusan/effort-index.git
synced 2026-07-22 08:29:58 +00:00
The suite's single-writer election is now per EVENT KIND (shared core, SIGNALS_API_VERSION 2), synced in here. It has to be: Note Decay emits open/rename/delete and never edit/dwell, and this plugin is the only one that emits edit/dwell. A per-plugin slot meant whoever recorded first owned the log and every event the loser emitted was dropped forever — so with Note Decay installed and winning the coin flip (listener-registration order, re-rolled on every restart), editMs was ZERO for every note in the vault. "Most expensive notes" was permanently empty, the CSV export said "No effort data to export yet", and the product silently did nothing. test/writer-election.test.ts stands a note-decay-shaped store up first, lets it take `open`, and asserts our edit and dwell still land on disk and still come back out of the fold — while `open` is still appended exactly once, by its owner. active-leaf-change fires for every leaf, including this plugin's OWN sidebar panel. The tracker asked getActiveViewOfType(MarkdownView), which returns null for a sidebar leaf, and dispatched `close` — and closeBurst DISCARDS any burst under minSessionMs. Type 4 s, click the Effort panel, type 4 s more, go idle: 8 seconds of real editing recorded as zero. A leaf change into something that is not a note is now treated exactly like a window blur (dwell pauses, the burst stays open, the dead-man tick still closes it on the idle rule); a leaf change into a different note still ends the session, which is what the listener is for. Also: - CSV injection: a note path beginning = + - @ (or tab/CR) exported as a live formula into Excel/Sheets/Numbers. Prefixed with an apostrophe and quoted. - A non-string licenseKey in a corrupt data.json crashed onload() outright (`licenseKey.trim is not a function`) — no view, no settings tab, no way for the user to fix the file. Every field is now coerced back to its declared type at the single boundary where data.json enters (settings.ts coerceSettings). - community-plugins.json said "saiken", the manifest says "Israel Avila". The obsidian-releases entry is now asserted field-by-field against the manifest. test/run.mjs now awaits each async .test.ts (exported as `done`) instead of firing it and moving on: the writer registry is a process-wide global, so two interleaved tests elect into each other's registry — and a test nobody awaited could "pass" without running an assertion. Every one of the five was proved failing against the pre-fix code first. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R3f6GZ2A8FbZerhJEpJQBE |
||
|---|---|---|
| .. | ||
| install-vault.mjs | ||
| sync-shared.mjs | ||