diff --git a/.STATUS b/.STATUS
index 269a25c7..78fe4065 100644
--- a/.STATUS
+++ b/.STATUS
@@ -1,15 +1,15 @@
---
status: active
priority: P1
-version: 1.17.0
+version: 1.18.0
sprint: 37
started: 2026-01-08
updated: 2026-02-22
released: 2026-01-24
editor: hybrid-markdown++
next_focus: Fix 67 test file TypeScript errors (~2.5h) / v1.17.0 Three-Tab Sidebar System
-tests: 2187
-unit_tests: 2187
+tests: 2190
+unit_tests: 2190
e2e_tests: 109
test_file_errors: 67 (non-blocking, documented in docs/planning/TEST-FILE-TYPESCRIPT-ERRORS-2026-01-24.md)
tags:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f637ebea..d1f19fa7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
+## [v1.18.0] - 2026-02-22 — Sidebar Vault Fix
+
+### Fixed
+
+- **Sidebar vault expansion showing wrong notes** (PR #43) - Vault dots now filter to the correct single project instead of passing all projects. Breadcrumb syncs on vault toggle. Fixed DexieError2 race condition in browser-mode initialization.
+- **Broken brainstorm link** in MCP app spec
+
+### Added
+
+- 3 new tests for vault toggle → `onSelectProject` wiring (MissionSidebar)
+
+---
+
## [v1.16.3] - 2026-01-26
### Automated Release Pipeline
diff --git a/README.md b/README.md
index 9aec44d3..0658eee2 100644
--- a/README.md
+++ b/README.md
@@ -3,9 +3,9 @@
> **ADHD-Friendly Distraction-Free Writer**
[]()
-[]()
+[]()
[]()
-[]()
+[]()
[]()
[]()
diff --git a/BRAINSTORM-mcp-app-2026-02-22.md b/docs/archive/brainstorms/BRAINSTORM-mcp-app-2026-02-22.md
similarity index 100%
rename from BRAINSTORM-mcp-app-2026-02-22.md
rename to docs/archive/brainstorms/BRAINSTORM-mcp-app-2026-02-22.md
diff --git a/WORKFLOW-FIX-SUMMARY.md b/docs/archive/completed/WORKFLOW-FIX-SUMMARY.md
similarity index 100%
rename from WORKFLOW-FIX-SUMMARY.md
rename to docs/archive/completed/WORKFLOW-FIX-SUMMARY.md
diff --git a/docs/index.md b/docs/index.md
index d9204bc2..e52dcc66 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -3,9 +3,9 @@
> **ADHD-Friendly Distraction-Free Writer**

-
+

-
+
---
diff --git a/docs/reference/CHANGELOG.md b/docs/reference/CHANGELOG.md
index 95e7f553..65ffc87a 100644
--- a/docs/reference/CHANGELOG.md
+++ b/docs/reference/CHANGELOG.md
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
+## [v1.18.0] - 2026-02-22 — Sidebar Vault Fix
+
+### Fixed
+
+- **Sidebar vault expansion showing wrong notes** (PR #43) - Vault dots now filter to the correct single project instead of passing all projects. Breadcrumb syncs on vault toggle. Fixed DexieError2 race condition in browser-mode initialization.
+- **Broken brainstorm link** in MCP app spec
+
+### Added
+
+- 3 new tests for vault toggle → `onSelectProject` wiring (MissionSidebar)
+
+---
+
## [v1.17.0] - 2026-02-22 — Quarto Autocomplete
### Added
@@ -25,6 +38,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **Escaped `\$` handling** — literal dollar signs no longer break math context tracking
- **Migration loop prevented** — dedicated version flag for localStorage migrations
- **70 TypeScript errors resolved** across 22 test files and 1 source file
+- **Tauri JS/Rust package alignment** — updated @tauri-apps/api (2.9.1→2.10.1), plugin-dialog (2.4.2→2.6.0), CLI (2.9.6→2.10.0) to match Cargo.lock resolved versions
+- **DragRegion test mock** fixed with `vi.hoisted()` for dynamic Tauri imports
+- **5 broken relative links** fixed in documentation site
---
diff --git a/docs/reference/CLAUDE.md b/docs/reference/CLAUDE.md
index 7441ae49..c8b87504 100644
--- a/docs/reference/CLAUDE.md
+++ b/docs/reference/CLAUDE.md
@@ -240,14 +240,21 @@ scribe help --all # Full reference
---
-## 🎯 Current Status: v1.17.0 - Quarto Autocomplete ✅
+## 🎯 Current Status: v1.18.0 - Sidebar Vault Fix ✅
-**Released:** v1.17.0 (stable)
-**Dev Branch:** v1.17.0 (Quarto autocomplete, test fixes, doc sync)
+**Released:** v1.18.0 (stable)
+**Dev Branch:** v1.18.0 (Sidebar vault expansion fix, browser-mode init fix)
**Install Stable:** `brew install --cask data-wise/tap/scribe` (v1.14.0)
-**Tests:** 2,187 passing (71 files)
+**Tests:** 2,190 passing (71 files)
-### Latest Work: Quarto Autocomplete Stabilization (PR #40)
+### Latest Work: Sidebar Vault Expansion Fix (PR #43)
+
+- ✅ Vault dots filter to correct single project (not all projects)
+- ✅ Breadcrumb syncs via `onSelectProject` on vault toggle
+- ✅ Fixed DexieError2 race condition in browser-mode init
+- ✅ 3 new vault toggle wiring tests
+
+### Previous: Quarto Autocomplete Stabilization (PR #40)
- ✅ Context-aware LaTeX completions (math-only scoping, suppressed in code blocks)
- ✅ Code chunk completions (R, Python, Julia, OJS, Mermaid, Graphviz)
diff --git a/docs/reference/TESTS_SUMMARY.md b/docs/reference/TESTS_SUMMARY.md
index 922d47e4..3d27b343 100644
--- a/docs/reference/TESTS_SUMMARY.md
+++ b/docs/reference/TESTS_SUMMARY.md
@@ -1,7 +1,7 @@
# Test Coverage Summary - Scribe Editor
**Generated:** 2026-01-24
-**Total Tests:** 2,187 passing (71 test files)
+**Total Tests:** 2,190 passing (71 test files)
**Test Framework:** Vitest + Testing Library + happy-dom
**TypeScript:** 0 production errors, 67 test file warnings (documented)
diff --git a/docs/specs/SPEC-mcp-app-claude-desktop-2026-02-22.md b/docs/specs/SPEC-mcp-app-claude-desktop-2026-02-22.md
index 20a58351..3127c05e 100644
--- a/docs/specs/SPEC-mcp-app-claude-desktop-2026-02-22.md
+++ b/docs/specs/SPEC-mcp-app-claude-desktop-2026-02-22.md
@@ -5,7 +5,7 @@
**Generated:** 2026-02-22
**Status:** Draft
**Priority:** P1 (New Distribution Channel)
-**From Brainstorm:** [BRAINSTORM-mcp-app-2026-02-22.md](../../BRAINSTORM-mcp-app-2026-02-22.md)
+**From Brainstorm:** [BRAINSTORM-mcp-app-2026-02-22.md](../archive/brainstorms/BRAINSTORM-mcp-app-2026-02-22.md)
---
diff --git a/package.json b/package.json
index 054c22dd..3b02182d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "scribe",
- "version": "1.17.0",
+ "version": "1.18.0",
"description": "Scribe - ADHD-friendly distraction-free writer",
"main": "dist-electron/main/index.js",
"author": "Stat-Wise",
diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock
index c1c2d357..0432bbe7 100644
--- a/src-tauri/Cargo.lock
+++ b/src-tauri/Cargo.lock
@@ -3216,7 +3216,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "scribe"
-version = "1.17.0"
+version = "1.18.0"
dependencies = [
"chrono",
"dirs 5.0.1",
diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml
index 46776a21..3154da5a 100644
--- a/src-tauri/Cargo.toml
+++ b/src-tauri/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "scribe"
-version = "1.17.0"
+version = "1.18.0"
description = "Scribe - ADHD-friendly distraction-free writer"
authors = ["Stat-Wise"]
license = "MIT"
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index b498a285..aa963150 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -1,7 +1,7 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Scribe",
- "version": "1.17.0",
+ "version": "1.18.0",
"identifier": "com.scribe.app",
"build": {
"frontendDist": "../dist",
diff --git a/src/renderer/src/__tests__/ExpandedIconPanel.component.test.tsx b/src/renderer/src/__tests__/ExpandedIconPanel.component.test.tsx
index b2e37d1f..c7275859 100644
--- a/src/renderer/src/__tests__/ExpandedIconPanel.component.test.tsx
+++ b/src/renderer/src/__tests__/ExpandedIconPanel.component.test.tsx
@@ -290,9 +290,9 @@ describe('ExpandedIconPanel Component', () => {
})
/**
- * EIP-09: Shows all projects for pinned project vault
+ * EIP-09: Shows only the expanded project for pinned project vault
*/
- it('shows all projects when expanded icon is pinned project', () => {
+ it('shows only the expanded project when expanded icon is pinned project', () => {
const props = createDefaultProps()
const projects: Project[] = [
{
@@ -320,9 +320,9 @@ describe('ExpandedIconPanel Component', () => {
render()
- // CompactListView should receive all projects (not filtered)
+ // CompactListView should receive only the expanded project (filtered)
const compactView = screen.getByTestId('compact-list-view')
- expect(compactView).toHaveAttribute('data-project-count', '2')
+ expect(compactView).toHaveAttribute('data-project-count', '1')
})
/**
diff --git a/src/renderer/src/__tests__/MissionSidebar.test.tsx b/src/renderer/src/__tests__/MissionSidebar.test.tsx
index 38d3997d..1888977f 100644
--- a/src/renderer/src/__tests__/MissionSidebar.test.tsx
+++ b/src/renderer/src/__tests__/MissionSidebar.test.tsx
@@ -1,7 +1,7 @@
-import { describe, it, expect, vi } from 'vitest'
-import { render, screen } from '@testing-library/react'
+import { describe, it, expect, vi, beforeEach } from 'vitest'
+import { render, screen, fireEvent } from '@testing-library/react'
import { MissionSidebar } from '../components/sidebar/MissionSidebar'
-import { Project, Note } from '../types'
+import { Project, Note, SmartIconId } from '../types'
/**
* MissionSidebar Integration Tests (v1.16.0 Icon-Centric)
@@ -12,6 +12,59 @@ import { Project, Note } from '../types'
* - No collapse/expand toggle (icons control expansion)
*/
+// Hoisted mocks for store state — can be mutated per test
+const { mockToggleIcon, mockExpandedIcon, mockPinnedVaults } = vi.hoisted(() => ({
+ mockToggleIcon: vi.fn(),
+ mockExpandedIcon: { current: null as { type: 'vault' | 'smart'; id: string } | null },
+ mockPinnedVaults: {
+ current: [
+ { id: 'inbox', label: 'Inbox', order: 0, isPermanent: true, preferredMode: 'compact' as const },
+ { id: '1', label: 'Test Research Project', order: 1, isPermanent: false, preferredMode: 'compact' as const },
+ ]
+ }
+}))
+
+vi.mock('../store/useAppViewStore', () => ({
+ useAppViewStore: vi.fn((selector?: (state: any) => any) => {
+ const state = {
+ expandedIcon: mockExpandedIcon.current,
+ sidebarWidth: 280,
+ pinnedVaults: mockPinnedVaults.current,
+ smartIcons: [
+ { id: 'research' as SmartIconId, label: 'Research', icon: 'flask', color: '#3b82f6', projectType: 'research' as const, isVisible: true, isExpanded: false, order: 0, preferredMode: 'compact' as const },
+ { id: 'teaching' as SmartIconId, label: 'Teaching', icon: 'graduation-cap', color: '#f59e0b', projectType: 'teaching' as const, isVisible: true, isExpanded: false, order: 1, preferredMode: 'compact' as const },
+ { id: 'packages' as SmartIconId, label: 'R Packages', icon: 'package', color: '#10b981', projectType: 'package' as const, isVisible: true, isExpanded: false, order: 2, preferredMode: 'compact' as const },
+ { id: 'devtools' as SmartIconId, label: 'Dev Tools', icon: 'wrench', color: '#8b5cf6', projectType: 'development' as const, isVisible: true, isExpanded: false, order: 3, preferredMode: 'compact' as const },
+ ],
+ toggleIcon: mockToggleIcon,
+ setIconMode: vi.fn(),
+ collapseAll: vi.fn(),
+ setSidebarWidth: vi.fn(),
+ reorderPinnedVaults: vi.fn(),
+ recentNotes: [],
+ clearRecentNotes: vi.fn(),
+ compactModeWidth: 280,
+ cardModeWidth: 360,
+ }
+ return selector ? selector(state) : state
+ }),
+ SIDEBAR_WIDTHS: {
+ icon: 48,
+ compact: { min: 180, default: 280, max: 400 },
+ card: { min: 280, default: 360, max: 500 },
+ }
+}))
+
+vi.mock('../store/useSettingsStore', () => ({
+ useSettingsStore: vi.fn((selector?: (state: any) => any) => {
+ const state = {
+ settings: { 'appearance.sidebarWidth': 'medium' },
+ updateSetting: vi.fn(),
+ }
+ return selector ? selector(state) : state
+ })
+}))
+
describe('MissionSidebar Integration (v1.16.0)', () => {
const mockProjects: Project[] = [
{
@@ -50,7 +103,7 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
},
]
- const mockHandlers = {
+ const createMockHandlers = () => ({
onSelectProject: vi.fn(),
onSelectNote: vi.fn(),
onCreateProject: vi.fn(),
@@ -67,7 +120,12 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
onMoveNoteToProject: vi.fn(),
onDuplicateNote: vi.fn(),
onDeleteNote: vi.fn(),
- }
+ })
+
+ beforeEach(() => {
+ vi.clearAllMocks()
+ mockExpandedIcon.current = null
+ })
it('renders MissionSidebar component with icon-centric class', () => {
const { container } = render(
@@ -75,7 +133,7 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
projects={mockProjects}
notes={mockNotes}
currentProjectId={null}
- {...mockHandlers}
+ {...createMockHandlers()}
/>
)
@@ -89,7 +147,7 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
projects={mockProjects}
notes={mockNotes}
currentProjectId={null}
- {...mockHandlers}
+ {...createMockHandlers()}
/>
)
@@ -104,7 +162,7 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
projects={mockProjects}
notes={mockNotes}
currentProjectId={null}
- {...mockHandlers}
+ {...createMockHandlers()}
/>
)
@@ -122,7 +180,7 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
projects={mockProjects}
notes={mockNotes}
currentProjectId={null}
- {...mockHandlers}
+ {...createMockHandlers()}
/>
)
@@ -137,7 +195,7 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
projects={mockProjects}
notes={mockNotes}
currentProjectId={null}
- {...mockHandlers}
+ {...createMockHandlers()}
/>
)
@@ -153,7 +211,7 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
projects={mockProjects}
notes={mockNotes}
currentProjectId={null}
- {...mockHandlers}
+ {...createMockHandlers()}
/>
)
@@ -162,4 +220,82 @@ describe('MissionSidebar Integration (v1.16.0)', () => {
// Should have data-mode attribute
expect(sidebar).toHaveAttribute('data-mode')
})
+
+ /**
+ * Vault toggle → onSelectProject wiring tests
+ *
+ * When a vault dot is clicked to expand, onSelectProject should be called
+ * so the breadcrumb and search scope update to match the expanded project.
+ * When collapsing, onSelectProject should NOT be called.
+ */
+ describe('vault toggle updates currentProject', () => {
+ it('calls onSelectProject when vault dot is expanded', () => {
+ // expandedIcon is null → clicking vault '1' is an expansion
+ mockExpandedIcon.current = null
+ const handlers = createMockHandlers()
+
+ render(
+
+ )
+
+ // Click the pinned project vault dot
+ const vaultDot = screen.getByTestId('project-icon-1')
+ fireEvent.click(vaultDot)
+
+ // Should call toggleIcon (store action)
+ expect(mockToggleIcon).toHaveBeenCalledWith('vault', '1')
+ // Should call onSelectProject with the project ID (breadcrumb update)
+ expect(handlers.onSelectProject).toHaveBeenCalledWith('1')
+ })
+
+ it('does not call onSelectProject when vault dot is collapsed', () => {
+ // expandedIcon already pointing to vault '1' → clicking it is a collapse
+ mockExpandedIcon.current = { type: 'vault', id: '1' }
+ const handlers = createMockHandlers()
+
+ render(
+
+ )
+
+ // Click the same vault dot (collapsing it)
+ const vaultDot = screen.getByTestId('project-icon-1')
+ fireEvent.click(vaultDot)
+
+ // Should still call toggleIcon (to collapse)
+ expect(mockToggleIcon).toHaveBeenCalledWith('vault', '1')
+ // Should NOT call onSelectProject (we're collapsing, not selecting)
+ expect(handlers.onSelectProject).not.toHaveBeenCalled()
+ })
+
+ it('calls onSelectProject(null) when inbox vault is expanded', () => {
+ mockExpandedIcon.current = null
+ const handlers = createMockHandlers()
+
+ render(
+
+ )
+
+ // Click the inbox button
+ const inboxBtn = screen.getByTestId('inbox-icon-button')
+ fireEvent.click(inboxBtn)
+
+ // Should call onSelectProject(null) — inbox has no project
+ expect(handlers.onSelectProject).toHaveBeenCalledWith(null)
+ })
+ })
})
diff --git a/src/renderer/src/components/sidebar/ExpandedIconPanel.tsx b/src/renderer/src/components/sidebar/ExpandedIconPanel.tsx
index fd12a74d..fda36ce1 100644
--- a/src/renderer/src/components/sidebar/ExpandedIconPanel.tsx
+++ b/src/renderer/src/components/sidebar/ExpandedIconPanel.tsx
@@ -89,11 +89,11 @@ export function ExpandedIconPanel({
filteredProjects: []
}
}
- // Pinned project: Show all projects with this one selected
+ // Pinned project: Show only this project
return {
label: projects.find(p => p.id === expandedIcon.id)?.name || 'Project',
showInboxNotes: false,
- filteredProjects: projects
+ filteredProjects: projects.filter(p => p.id === expandedIcon.id)
}
}
diff --git a/src/renderer/src/components/sidebar/MissionSidebar.tsx b/src/renderer/src/components/sidebar/MissionSidebar.tsx
index d15873f8..046f045e 100644
--- a/src/renderer/src/components/sidebar/MissionSidebar.tsx
+++ b/src/renderer/src/components/sidebar/MissionSidebar.tsx
@@ -186,7 +186,15 @@ export function MissionSidebar({
projects={projects}
notes={notes}
expandedIcon={expandedIcon}
- onToggleVault={(id) => toggleIcon('vault', id)}
+ onToggleVault={(id) => {
+ // If this vault is already expanded, we're collapsing — don't update project
+ const isCollapsing = expandedIcon?.type === 'vault' && expandedIcon?.id === id
+ toggleIcon('vault', id)
+ if (!isCollapsing) {
+ // Expanding a vault: update currentProjectId so breadcrumb + search scope follow
+ onSelectProject(id === 'inbox' ? null : id)
+ }
+ }}
onToggleSmartIcon={(id) => toggleIcon('smart', id)}
onSearch={onSearch}
onDaily={onDaily}
diff --git a/src/renderer/src/lib/browser-api.ts b/src/renderer/src/lib/browser-api.ts
index 7c18642d..3c4e4389 100644
--- a/src/renderer/src/lib/browser-api.ts
+++ b/src/renderer/src/lib/browser-api.ts
@@ -669,6 +669,7 @@ export const reindexAllNotes = async (): Promise => {
*/
export const initializeBrowserApi = async (): Promise => {
console.log('[Scribe] Using IndexedDB for persistence')
+ await db.initialize()
await seedDemoData()
// Reindex existing notes for wiki links and tags
diff --git a/src/renderer/src/lib/browser-db.ts b/src/renderer/src/lib/browser-db.ts
index 5b7bbb77..127b8d3c 100644
--- a/src/renderer/src/lib/browser-db.ts
+++ b/src/renderer/src/lib/browser-db.ts
@@ -260,11 +260,6 @@ export const seedDemoData = async (): Promise => {
return true
}
-// Auto-run seed on module import (after db is initialized)
-// Skip in test environment to avoid interfering with test data
-if (!import.meta.env.VITEST) {
- ;(async () => {
- await db.initialize()
- await seedDemoData()
- })().catch(console.error)
-}
+// NOTE: Auto-initialization removed — browser-api.ts is the single init entry point.
+// This prevents double-init race conditions (DexieError2) when both modules
+// fire concurrent async init chains on import.