You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Custom DOM events (wg:*):wg:open-search, wg:open-palette, wg:open-template, wg:new-note, wg:new-daily, wg:toggle-split, wg:graph-command.
Shortcut global (Ctrl/⌘):K search · P palette · Shift+? shortcuts · B sidebar · J AI chat · N new note · Shift+N template · Shift+D daily · S save · E editor.
Singleton di mana-mana — seluruh engine (workspaceEngine, graphEngine, markdownEngine, …) adalah singleton global dengan state mutable
🟠 Sedang
Membuat pengujian paralel rapuh & menghalangi multi-vault/multi-window di masa depan. Pertimbangkan factory (mis. createWorkspaceEngine()) yang di-inject, atau repository pattern agar state testable via dependency injection.
C3
Toaster & DialogHost di-render dua kali — di App.tsx dan lagi di AppShell.tsx
🟢 Rendah
Hapus salah satu. Duplikasi mount berarti dua host toast (entry ganda, z-index ambiguity).
C4
Dead code MarkdownPreview — hanya dipakai untuk headingSlug oleh BacklinksPanel; mode split sudah tidak merender komponen ini
🟠 Sedang
Pilih salah satu: aktifkan kembali sebagai reading-pane di editor (sesuai spesifikasi 24_UX_Flow) atau hapus + pindahkan headingSlug ke util. Code yang tidak ter-render = spesifikasi vs kode sudah drift.
11.2 State Management
#
Temuan
Tingkat
Saran
C5
Circular dependency antar store — workspaceStore.closeWorkspace pakai import() dinamis untuk memanggil editorStore/chatStore
🟠 Sedang
import() dinamis adalah "tambalan" circular import. Pisahkan orkestrasi: buat sessionService (modul netral) yang memegang urutan flush/reset lintas store, sehingga store tetap acyclic dan bisa di-render dalam urutan apa pun.
C6
Tidak ada session/tab restore — tabs editorStore murni in-memory; restart app = semua tab hilang
🟠 Sedang
Obsidian/VS Code restore tab. Simpan openTabs[] (path + activeTabId + surfaceMode) ke .workspacegraph/ui-state.json via IPC settings atau channel baru; restore saat openVaultFlow.
C7
chatStore.sendMessage sangat monolitik — bercampur stream management, history windowing, checkpoint, dan proposal
🟠 Sedang
Ekstrak streamRuntime (status mesin state), historyWindow, checkpointWriter sebagai unit terpisah yang bisa di-test tanpa mock IPC.
C8
Tanpa middleware Zustand — tidak ada devtools/persist/logger
🟢 Rendah
Tambahkan zustand/middleware devtools (production-safe) untuk debugging; persist terbatas untuk UI-pref saja (graphStore sudah via IPC — konsistenkan).
11.3 Backend / Engines
#
Temuan
Tingkat
Saran
C9
Kontrak IPC tidak ter-generate — index.d.ts (593 baris) ditulis manual; 80+ channel berisiko drift dari handler
🔴 Tinggi
Bangun satu sumber kebenaran: tipe request/response di file shared (src/shared/ipc.ts) yang diimpor BOTH main handler & preload. Gunakan skrip typecheck + lint untuk memastikan tidak ada drift. Ini adalah proteksi terbesar terhadap bug tak terduga.
C10
Quit tidak flush editor buffer — window-all-closed → app.quit() tanpa drain flushSave; penutupan cepat bisa kehilangan perubahan 700ms-debounce
🔴 Tinggi
Di main: hook before-quit/will-quit → kirim ui:flush-before-quit (invoke dengan timeout), tunggu semua tab flush selesai, baru quit. Juga pertimbangkan autosave interval (30s) sebagai jaring pengaman.
C11
Embedding reindex per file-change — tiap event chokidar memicu reindex embedding file itu (ditambah Fuse delta debounce)
🟠 Sedang
Batch/queue embedding jobs (mis. flush tiap 5s / idle), throttle saat banyak file berubah (git checkout, folder copy). Prioritaskan: file yang terlihat (open tab) > tersembunyi.
C12
Automation scheduler 60s tick polling — untuk trigger schedule
🟢 Rendah
Ganti polling dengan setTimeout bertingkat ke next fire time; hemat resource dan lebih akurat.
C13
SearchEngine & EmbeddingEngine dua indeks terpisah
🟠 Sedang
Sudah ada note_tags normalisasi — pertahankan satu IndexDatabase sebagai source of truth metadata; pastikan rebuild dua-phase (drop-then-rebuild) atomic agar tidak ada window FTS hidup + embedding kosong.
C14
ai:stream:<requestId> channel dinamis per request — watchdog 200s membersihkan listener
🟢 Rendah
Sudah bagus. Pertahankan; tambahkan heartbeat streaming agar request yang hang (bukan 200s) tetap terdeteksi.
11.4 Frontend / Performa
#
Temuan
Tingkat
Saran
C15
Selective subscribe manual di AppShell — hanya openTab/flushSave/activeTabId yang di-selector
🟢 Rendah
Bagus (hindari re-render per keystroke). Standarkan pola ini ke komponen besar lain (Sidebar sudah). Konsistensikan: DashboardView/StatusBar subscribe penuh → bisa re-render berat.
Bagus. Pertahankan; tambahkan indikator "file terlalu besar — highlighting dinonaktifkan" agar user tidak bingung.
C17
UI language hardcoded Indonesia di tooltip/label, campur dengan English
🟠 Sedang
Tanpa i18n, pasar non-ID terhalang. Minimal: pisahkan semua string ke locales/id.ts + locales/en.ts + useT(); default id.
C18
Loading/skeleton untuk fetch state di semua view sudah ada (SkeletonRows/EmptyState)
🟢 Rendah
Konsisten — pertahankan. Tambahkan skeleton juga di ChatPanel saat loadChat.
11.5 Keamanan
#
Temuan
Tingkat
Saran
C19
sandbox: false + 'unsafe-eval' di CSP (dev)
🟠 Sedang
sandbox:false dibutuhkan preload contextBridge biasa — tapi sudah benar contextIsolation tidak dimatikan. Verifikasi nodeIntegration:false eksplisit. Untuk production, coba hilangkan 'unsafe-eval' (React refresh hanya di dev; bisa dipisah via env).
C20
Google Fonts allowlist di CSP
🟢 Rendah
Pertimbangkan self-host font penuh agar benar-benar offline (README mengklaim "local-first"; fonts.googleapis.com adalah pengecualian yang wajar tapi catat di 33_Security).
C21
Plugin sandbox sudah kuat (vm + worker + dialog gate)
🟢 Rendah
Pertahankan. Tambahkan test injection: plugin mencoba process, fetch, require, path escape — pastikan semua blocked (sekarang hanya jsRunner.test.ts).
11.6 Testing & Kualitas
#
Temuan
Tingkat
Saran
C22
1000+ test tapi komponen raksasa tidak di-cover — GraphCanvas/SettingsView/ChatPanel/AppShell hampir tanpa React test; hanya modul util yang di-test
🔴 Tinggi
Ini gap terbesar. Pecah god component dulu (C1) lalu tulis test per subkomponen (rendering, interaksi, state). Prioritas: graphStore action flow + ChatPanel stream state machine + AppShell routing/shortcuts.
C23
E2E hanya di main (qa/) — tidak ada Playwright/webdriver test untuk renderer
🟠 Sedang
Tambahkan @playwright/test E2E: buka vault fixture, buat note, link wiki, render graph, kirim chat (mock provider). Ini menangkap regression yang tak terlihat unit test.
C24
Dokumen spesifikasi (36 dokumen) vs kode drift — e.g. MarkdownPreview
🟠 Sedang
Tambahkan check CI scripts/check-docs-drift.mjs atau ADR bahwa setiap perubahan di engine harus update dokumen terkait (link di commit).
C25
Coverage gate di CI
🟢 Rendah
README bilang "with coverage" — pastikan threshold (lines >= 70%) diekspor di vitest config supaya regresi coverage menolak build.
11.7 Produk / UX
#
Temuan
Tingkat
Saran
C26
Tanpa sistem plugin UI — plugin hanya command-based
🟠 Sedang
Sesuai 28_Plugin_SDK; pertimbangkan minimal plugin view slots (mirip Obsidian) — tapi hanya jika roadmap membutuhkan.