Previously, many guard conditions in the sync pipeline returned silently
with zero feedback, making it impossible to diagnose why operations were
dropped (root cause of issues #109, #111).
Changes:
- syncLock: log timeout failures in waitForRelease/waitForSaveRelease and
acquire/acquireExclusive (console.warn + debugLog + logOperation)
- toTodoist: log isTaskSyncEnabled skips on user actions (edit/close/reopen),
isPrimaryDevice guard in lastLineNewTaskCheck, and parser failures
- toObsidian: log missing mapping/file/taskLine in syncSingleTaskToObsidian
- eventHandlers: log apiInitialized guards in all 5 event handlers
- scheduler: log lock acquisition failures during file sync
New logOperation event types: SYNC_LOCK_TIMEOUT, SYNC_DISABLED_SKIP,
SYNC_TARGET_MISSING, TASK_PARSE_FAILED
No logic changes, no Notice additions — logging only.
Previously, lineContentNewTaskCheck fired on every keystroke in Full Vault
Sync mode, creating a Todoist task after typing a single character.
Now new task detection in Full Vault Sync is handled by lastLineNewTaskCheck,
which only fires when the cursor leaves the line. lineContentNewTaskCheck is
narrowed to only handle manually-tagged #todoist tasks.
Fixes#110 (problem 4)
- Add ExcludedFoldersModal with folder tree, checkboxes, Save/Cancel
- Settings page shows summary + Configure button instead of inline tree
- Add CSS for modal, tree rows, and summary list
- Add .stignore for Syncthing
- Update feature table: priority and labels/tags sync now bidirectional
- Add sync direction controls and excluded folders to settings docs
- Add development guide (clone, build, project structure)
- Add CHANGELOG entry for 2.0.0
- Fix addTodoistTagToFile null crash with null guard (fileOperation.ts)
- Fix isProcessingModify timing window in toTodoist.ts
- Add full vault scan in scheduler getUniqueFiles() when enableFullVaultSync is on
- Add isFileExcludedFromSync() with dot-prefix, storage dir, templates, excalidraw exclusions
- Add excludedFolders setting with tree UI (checkboxes, parent-disables-children)
- Change syncEnabled default to true to prevent silent sync stop for upgrading users
- convertLegacyIds: when multiple tasks match by content, use Todoist
description filePath to disambiguate instead of skipping
- deleteIssueTask: backup file before modifications, reorder to
local-first then remote, restore from backup on local failure,
remove dead 404 detection code
Instead of pushing all fields (content, labels, due, priority, status)
to Todoist regardless of which fields conflict, now reads open issue
types from taskFileMapping and only includes fields that actually have
a mismatch. Skips API call entirely if no commands are needed.
Verify Database only generated a report without writing issues to
taskFileMapping, causing Manage Problem Tasks to show stale data.
Now calls applyDatabaseIssuesToMapping after verification so the UI
reflects the latest check results.
DatabaseChecker detects issues for tasks found in Vault/Todoist but
missing from taskFileMapping. applyDatabaseCheckerIssues silently skipped
these because ensureClonedEntry returned undefined for missing entries.
Now creates a default entry using the issue's filePath, allowing issues
to be persisted and visible in Manage Problem Tasks.
applyMatchFirstAutoRepairs skipped legacy ID migration when the old task
had no existing taskFileMapping entry. Tasks found by DatabaseChecker via
vault scan often lack mapping entries, causing Safe Repair to silently
skip all legacy conversions. Now falls back to a default entry using the
candidate's filePath.
Unifies issue normalization and case reporting so safe auto-repair and Manage Problem Tasks operate on the same canonical states, reducing stale-key drift and mismatched triage behavior.
Acquire an exclusive sync lock during rebuildCache and release it in finally, while removing the intermediate taskFileMapping clear step that could be persisted by debounced saves. This keeps rebuild atomic from reader and persistence perspectives.
Unify issue normalization and status derivation across settings, cache, sync, and Task Manager so stale links and mismatches are tracked consistently. Keep Fix Database read-only for Todoist updates while enabling guarded manual stale-link repair and stronger task-state transitions.
- Change input type to password (token no longer visible by default)
- Add eye toggle button to show/hide token
- Replace per-keystroke onChange with blur-based save (only saves on change)
- Add loading/success/failure feedback on send button
- Add tooltips to eye and send buttons
- Fix modifyTodoistAPI() to return boolean for success/failure detection
Replace full-expansion layout with list→detail navigation. Open modal shows compact task list with type badges; clicking a row shows detail view with diff table (conflicts) or preview + actions (issue/inactive). Back button returns to list. Business logic unchanged.
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)
Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Wave 3 changes for TaskManagerModal:
- T6: Remove incrementalSync from resolveConflict, keep only in loadAndRender, add refresh button
- T9: Add Re-enable and Delete buttons for nonActive tasks with reEnableTask method
- T13: Replace all saveSettings() with safeSettings.update({}, true)