Commit graph

368 commits

Author SHA1 Message Date
HeroBlackInk
7ba62023e6 chore: bump version to 2.0.3 2026-03-20 02:35:53 +08:00
HeroBlackInk
07643d0450 fix: add logging to 22 silent early returns across sync pipeline
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.
2026-03-20 01:46:39 +08:00
HeroBlackInk
9f600b9e21 fix: Full Vault Sync typing hijack — defer new task creation to line leave
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)
2026-03-17 22:17:36 +08:00
HeroBlackInk
799bd13a71 fix: resolve all hardcoded plugin directory paths (deviceManager, settings) 2026-03-16 18:24:24 +08:00
HeroBlackInk
ce9de79d17 fix: use static methods with manifest.dir for settings path to avoid init order issue 2026-03-16 18:15:59 +08:00
HeroBlackInk
0f59756a13 fix: use dynamic plugin directory path for settings file (fixes #108) 2026-03-16 18:08:34 +08:00
HeroBlackInk
b0285ad8f2 feat(settings): move excluded folders to dedicated modal with Configure button
- 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
2026-03-15 17:01:10 +08:00
HeroBlackInk
6bdb2824cd chore: bump version to 2.0.0 and update documentation
- 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
2026-03-15 16:10:47 +08:00
HeroBlackInk
3b9a24b3a8 feat(full-vault-sync): fix bugs, add folder exclusion, and improve sync defaults
- 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
2026-03-15 15:41:13 +08:00
HeroBlackInk
1d2dc48080 fix(backup): change backup file extension from .md to .md.bak to prevent bidirectional link pollution 2026-03-10 14:28:32 +08:00
HeroBlackInk
ed39e13052 fix(sync): disambiguate legacy ID by filePath and atomize delete flow
- 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
2026-02-27 15:45:24 +08:00
HeroBlackInk
4dcfe202f6 fix(ui): open file link in new tab instead of replacing current tab 2026-02-27 13:26:10 +08:00
HeroBlackInk
d5581d08be fix(ui): only push conflicting fields in Keep Obsidian resolution
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.
2026-02-27 13:12:18 +08:00
HeroBlackInk
54e93ae658 chore: add debug logging to legacy ID conversion and vault update flows 2026-02-27 12:42:45 +08:00
HeroBlackInk
06a2791984 fix(verify): persist detected issues to mapping after Verify Database
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.
2026-02-27 01:54:48 +08:00
HeroBlackInk
ced52a6d9b fix(issues): create mapping entry for tasks missing from taskFileMapping in applyDatabaseCheckerIssues
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.
2026-02-27 01:16:43 +08:00
HeroBlackInk
0c7ce44e80 fix(repair): create default mapping entry for legacy ID migration when missing
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.
2026-02-27 00:56:58 +08:00
HeroBlackInk
efac192fdc fix(settings): warn on reverse sync and lock safe repair execution 2026-02-26 21:22:07 +08:00
HeroBlackInk
0eeb9c8c49 fix(repair): require successful vault update before remapping legacy IDs 2026-02-26 21:21:57 +08:00
HeroBlackInk
b0c5049dca feat(issues): detect legacy ID migration issues during verification 2026-02-26 21:21:48 +08:00
HeroBlackInk
3e57581b2d fix(conflict): preserve todoist tag and guard empty due-date parsing 2026-02-26 19:33:42 +08:00
HeroBlackInk
c9c5deef60 fix(ui): avoid invalid class token in conflict diff cells 2026-02-26 19:16:42 +08:00
HeroBlackInk
eacd2c9e3c fix(sync): pull Todoist labels/priority to vault and align link generation 2026-02-26 19:10:46 +08:00
HeroBlackInk
fa8a69b40e fix(ui): use task parser comparators in conflict detail diff 2026-02-26 17:14:44 +08:00
HeroBlackInk
5199278550 refactor(compare): unify sync and checker comparisons via task parser 2026-02-26 17:14:44 +08:00
HeroBlackInk
04139499dd fix(parser): guard parent task project inheritance on missing parent 2026-02-26 16:51:08 +08:00
HeroBlackInk
ba9e71b292 refactor(issues): remove legacy issue-key alias compatibility 2026-02-26 16:51:08 +08:00
HeroBlackInk
d9abcd94d2 feat(ui): show verification report modal and reorder inactive tasks 2026-02-26 16:51:08 +08:00
HeroBlackInk
a053fa06e9 fix(sync): harden startup sync flow and preserve HTTP errors 2026-02-26 16:51:08 +08:00
HeroBlackInk
bde56a3570 refactor(issues): align match-first taxonomy across diagnostics and management flows
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.
2026-02-26 13:50:59 +08:00
HeroBlackInk
ade39de8a0 fix(sync): serialize rebuild cache and avoid transient empty mapping
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.
2026-02-25 16:02:24 +08:00
HeroBlackInk
37e7179213 feat(issues): introduce issue-driven problem task workflow
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.
2026-02-25 15:18:53 +08:00
HeroBlackInk
9594a1cc4c chore(git): normalize ignore patterns and add stignore 2026-02-25 12:27:44 +08:00
HeroBlackInk
c8122f73c4 feat(ui): add Todoist deep link in Task Manager detail view 2026-02-25 12:27:36 +08:00
HeroBlackInk
c3e24c1c82 fix(sync): guard lock acquisition while settings save is active 2026-02-25 11:46:43 +08:00
HeroBlackInk
e4c481c9a8 fix(sync): await persistence calls and enforce update-before-save ordering 2026-02-25 11:46:32 +08:00
HeroBlackInk
49e8c94b43 fix(settings): serialize settings IO and harden restore consistency 2026-02-25 11:46:19 +08:00
HeroBlackInk
b64032399f fix(settings): harden data lifecycle with schema migration, safety guards, and validation
Wave 1 - Safety fixes:
- onunload skips save when load failed (prevents corrupt data persistence)
- rebuildCache no longer persists empty mapping to disk mid-rebuild
- Backup dir computed from settings when storagePathManager unavailable
- Restore operations use atomic temp-file write pattern

Wave 2 - Schema migration framework:
- Add schemaVersion field (CURRENT_SCHEMA_VERSION = 1)
- runMigrations() with forced backup before migration
- v0→v1: isPrimaryDevice boolean → primaryDeviceId string

Wave 3 - Cleanup (depends on Wave 2):
- Replace GHOST_FIELDS denylist with KNOWN_SETTINGS_KEYS allowlist
- stripUnknownFields() auto-removes any key not in DEFAULT_SETTINGS
- sanitizeTaskFileMapping() validates filePath, upgrades missing status/syncEnabled
2026-02-25 10:59:09 +08:00
HeroBlackInk
2d69723a91 fix(settings): improve settings UI controls with Apply buttons and validation
- Sync interval: replace per-keystroke onChange with number input + Apply button
- Add restartSyncSchedulerInterval() to apply interval changes without reload
- Storage directory: replace onChange with Apply button + confirm dialog
- Default project dropdown: fix duplicate current item, add setValue()
- Backup button: add await, loading state, error handling, null checks
- Fix Database: add cacheOperation null check, local variable capture
- Error notices: use error instanceof Error pattern for safe message access
- API token description: update to reference Connect button
2026-02-25 10:44:55 +08:00
HeroBlackInk
e9fa55f26b fix(settings): harden data load with corruption recovery, normalization, and legacy migration
- Add isLoadDataUsable() validation (non-null object + JSON serializable)
- Add normalizeLoadedData() for key migration (syncInterval, todoistApiToken)
- Add buildLegacyTaskFileMapping() to migrate todoistTasksData.tasks[]
- Corruption path now returns false (stops plugin) instead of overwriting data.json
- Catch block attempts backup restore before falling back to defaults
- Add lastDatabaseCheckPassed to GHOST_FIELDS
- Add TaskMappingEntry type for mapping validation
2026-02-25 10:44:42 +08:00
HeroBlackInk
f4e92c50a9 style(settings): differentiate page title from section headings
Main title: large bold with bottom border separator.
Section headings: small uppercase muted text with top border divider.
2026-02-25 09:14:56 +08:00
HeroBlackInk
f411ec275d style(settings): change API connect from icon button to text button for clarity 2026-02-25 09:11:59 +08:00
HeroBlackInk
28a6ae2c64 style(settings): change API connect button icon from send to log-in 2026-02-25 09:10:18 +08:00
HeroBlackInk
d2fe770245 fix(settings): improve API token input security and UX
- 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
2026-02-25 09:06:04 +08:00
HeroBlackInk
c2f24ca772 fix(ui): TaskManagerModal bug fixes and CSS cleanup
- Fix stale _fileCache in resolveConflict todoist-wins path
- Fix confirm dialog DOM leak via _activeOverlay tracking
- Add navigateToList() for early-return paths in resolveConflict
- Add skipRerender param to bulk operations to avoid N re-renders
- Remove dead v2 CSS (.tm-section*, .tm-card*, .tm-table*)
- Fix tm-detail-body padding conflict with tm-scroll
- Fix tm-warning alignment and tm-bulk-bar wrapping
- Add tm-content-preview word-break override for detail view
2026-02-25 09:05:56 +08:00
HeroBlackInk
bc8e9cd145 refactor(ui): redesign TaskManagerModal to master-detail pattern
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>
2026-02-25 08:26:09 +08:00
HeroBlackInk
9014a41437 fix(data): escape wiki-link pipes and fix new_task_not_synced label in databaseChecker
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-02-25 08:26:00 +08:00
HeroBlackInk
6bfaef8d49 feat(ui): add bulk Resolve All / Delete All / Re-enable All buttons
Wave 4 (T10): Bulk operations for TaskManagerModal:
- Conflicted section: Resolve All: Keep Obsidian + Resolve All: Keep Todoist
- Issue section: Delete All with confirmation
- NonActive section: Re-enable All + Delete All with confirmation
- Progress shown in button text, _closed flag checked between iterations
2026-02-24 02:47:12 +08:00
HeroBlackInk
521d8972e7 fix(ui): deferred sync, nonActive actions, safeSettings cleanup
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)
2026-02-24 02:46:17 +08:00
HeroBlackInk
58dcb403c5 fix(ui): atomic resolve with batched API, confirmation dialog, and file cache
Wave 2 changes for TaskManagerModal:
- T5: Keep Obsidian uses batched executeCommands (item_update + item_close/uncomplete)
- T5: Keep Todoist now syncs tags/labels and priority inline
- T8: Delete action shows confirmation dialog before executing
- T12: File read cache (Map) avoids redundant vault.read() calls
2026-02-24 02:44:31 +08:00