Skip to content

Conversation

@jnahian
Copy link
Owner

@jnahian jnahian commented Oct 23, 2025

Summary

Implements Issue #9: Sidebar View for Browsing All Notes

This PR adds a comprehensive sidebar view that provides workspace-wide note browsing and management. The feature includes:

  • Dedicated Activity Bar icon for Code Notes (standalone sidebar, not in Explorer)
  • Tree view showing all notes organized by file
  • Quick navigation - Click any note to jump directly to its location
  • Real-time updates when notes are created, edited, or deleted
  • Context menus for common actions (Go to Note, Edit, Delete, View History)
  • Quick note creation - "+" button in sidebar toolbar (no text selection needed)
  • Collapse All button to reset tree to default state
  • Configurable sorting - By file path (default), date, or author
  • Configurable preview length and auto-expand behavior
  • Works seamlessly with multi-note feature (multiple notes per line)

Changes

New Files

  • src/noteTreeItem.ts - Tree item classes (Root, File, Note nodes)
  • src/notesSidebarProvider.ts - TreeDataProvider implementation
  • src/test/suite/noteTreeItem.test.ts - 59 comprehensive unit tests
  • src/test/suite/notesSidebarProvider.test.ts - 19 comprehensive unit tests
  • docs/sidebar-view-for-browsing-all-notes/USER_STORY.md - Complete implementation plan
  • docs/changelogs/v0.2.0.md - Detailed changelog entry
  • images/task.png - Activity Bar icon

Modified Files

  • src/noteManager.ts - Added EventEmitter, workspace queries, caching, file watcher
  • src/extension.ts - Sidebar registration, new commands, improved activation flow
  • package.json - Views, viewsContainers, commands, menus, configuration
  • README.md - Comprehensive sidebar documentation
  • docs/architecture/ARCHITECTURE.md - Added sidebar components

Key Features

1. Workspace-Wide Note Management

  • getAllNotes() - Get all notes across workspace
  • getNotesByFile() - Get notes grouped by file
  • Event-driven updates with debouncing (300ms)
  • Efficient caching with invalidation on changes

2. Tree Structure

  • Root Node: Total note count ("Code Notes (N)")
  • File Nodes: Relative path + note count ("src/app.ts (3)")
  • Note Nodes: Line number, preview (50 chars), author name
  • Collapsed by default for clean UI

3. Context Menus

  • Note items: Go to Note, Edit Note, View History, Delete Note
  • File items: Open File
  • All actions open inline comment editor (not external views)

4. Toolbar Actions

  • "+" button - Add note at cursor position (no selection needed)
  • Collapse All - Reset tree to default collapsed state
  • Refresh - Manual refresh trigger

5. Configuration Options

  • sidebar.sortBy - Sort by file/date/author (default: file)
  • sidebar.previewLength - Preview length 20-200 chars (default: 50)
  • sidebar.autoExpand - Auto-expand files (default: false)

6. Improved Add Note Command

  • Now works without text selection - uses current cursor line
  • Keyboard shortcut (Ctrl+Alt+N / Cmd+Alt+N) no longer requires selection
  • More convenient for quick note-taking

Test Plan

✅ Automated Testing (All Passing)

  • 78 comprehensive unit tests for sidebar components
  • NoteTreeItem tests (59 tests):
    • stripMarkdown() - 20 tests covering all markdown formats
    • truncateText() - 7 tests including edge cases
    • RootTreeItem, FileTreeItem, NoteTreeItem constructors - 32 tests
  • NotesSidebarProvider tests (19 tests):
    • getTreeItem() and getChildren() for all tree levels
    • Event listener setup and refresh behavior
    • Debouncing logic (300ms delay)
  • All tests compile successfully with TypeScript
  • Existing unit tests continue to pass (41/41)

✅ Manual Testing (All Passing)

  • Create/edit/delete notes workflow
  • Real-time sidebar updates
  • All context menu actions
  • Performance with 100+ notes across 50+ files
  • Navigation from sidebar to code
  • Sorting options
  • Configuration changes

Technical Details

Architecture:

  • Implements VSCode TreeDataProvider API
  • Event-driven with EventEmitter pattern
  • Lazy loading for optimal performance
  • Debounced refresh (300ms) to prevent excessive updates
  • Markdown stripping for clean previews
  • Content hash tracking for note stability

Performance:

  • Efficient caching reduces file I/O
  • Lazy loading prevents loading all note content upfront
  • Debouncing prevents UI thrashing
  • No memory leaks from event listeners
  • Tested with 100+ notes across 50+ files

Benefits

For Users:

  • Quick overview of all notes in the project at a glance
  • Fast navigation to any note without opening files
  • Visual understanding of note distribution across codebase
  • Better project-wide note management

For Teams:

  • Shared understanding of documented code areas
  • Easy discovery of team members' annotations
  • Better collaboration through visible note organization
  • Quick access to implementation decisions and technical debt notes

Migration Notes

  • ✅ No breaking changes - purely additive feature
  • ✅ No data migration required
  • ✅ Works with existing note storage format
  • ✅ Backward compatible with all existing notes
  • ✅ Sidebar can be hidden/shown via VSCode view controls if not needed

Closes

Closes #9

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Summary by CodeRabbit

  • New Features

    • Workspace Sidebar for browsing/managing notes (Activity Bar view, file grouping, per-note previews/counts)
    • Full-text Search with filters, QuickPick UI, history and keyboard shortcuts
    • Sidebar actions: Go to Note, Open File, Edit, Delete, View History, Refresh, Collapse All
    • Add Note now works without selection; command renamed/updated with icon and revised keybinding
  • Configuration

    • Settings for sidebar preview length, auto-expand, and sort mode (file/date/author)
  • Documentation

    • Expanded README, architecture, user stories, and changelogs for sidebar and search
  • Tests

    • Unit tests for sidebar tree items, provider behaviors, and search components
  • Chores

    • Updated ignore files and minor documentation housekeeping

…notes

- Implement NotesSidebarProvider with TreeDataProvider for workspace-wide note navigation
- Add new methods to NoteManager for querying notes across workspace
- Create tree view structure with file and note nodes
- Support real-time updates and lazy loading of notes
- Add context menu actions for note and file nodes
- Implement configuration options for sidebar behavior
- Create empty state and refresh mechanisms for sidebar view
- Update extension.ts and noteManager.ts to support new sidebar functionality
- Add comprehensive changelog and user story documentation for feature
Enables developers to quickly overview and navigate notes across entire workspace, improving code context and collaboration.
- Updated architecture documentation to include Sidebar Provider and Note Tree Items.
- Added NotesSidebarProvider for workspace-wide tree view of notes.
- Created NoteTreeItem classes for tree structure representation.
- Implemented sorting and filtering options for sidebar notes.
- Added comprehensive unit tests for sidebar components and utility methods.
- Completed manual testing for sidebar functionality and performance.
- Updated user story documentation to reflect completion status and testing results.
@jnahian jnahian linked an issue Oct 23, 2025 that may be closed by this pull request
4 tasks
@vercel
Copy link

vercel bot commented Oct 23, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
code-context-notes Ready Ready Preview Comment Oct 27, 2025 4:59pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 23, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds a Workspace Sidebar (TreeView) and search subsystem, new TreeItem classes and NotesSidebarProvider, NoteManager event/caching APIs, SearchManager and types, extension activation/command updates, filesystem watcher, unit tests, manifest contributions, and extensive documentation and changelogs.

Changes

Cohort / File(s) Summary
Ignore & Packaging
\.gitignore, \.vscodeignore
Added .code-notes to ignore lists; added node_modules/prettier/** to .vscodeignore; minor reflow of ignore entries.
Documentation & Blueprints
README.md, CLAUDE.md, docs/architecture/ARCHITECTURE.md, docs/sidebar-view-for-browsing-all-notes/USER_STORY.md, docs/search-and-filter-notes/USER_STORY.md, docs/changelogs/v0.2.0.md, docs/changelogs/v0.3.0.md
Large documentation additions and rewrites describing the Workspace Sidebar and Search features, architecture updates, user stories, usage, shortcuts, and changelogs.
Manifest / Extension Metadata
package.json
Added activity bar / sidebar view and welcome content, new sidebar-related commands and menus, new configuration keys (sidebar.previewLength, sidebar.autoExpand, sidebar.sortBy), changed addNote title/icon and relaxed its keybinding when-clause.
Extension bootstrap
src/extension.ts
Integrates NotesSidebarProvider and SearchManager, builds initial search index, defers command registration until providers are ready, registers sidebar commands, adds .code-notes FS watcher, and supports no-workspace activation path.
Note management & events
src/noteManager.ts
NoteManager now extends EventEmitter; adds workspace caches and query APIs (getAllNotes, getNotesByFile, getNoteCount, getFileCount), setSearchManager, cache invalidation, and emits lifecycle events (noteCreated/noteUpdated/noteDeleted/noteChanged).
Sidebar tree items
src/noteTreeItem.ts
New TreeItem classes: BaseTreeItem, RootTreeItem, FileTreeItem, NoteTreeItem with preview generation, markdown stripping, tooltips, icons, commands, and collapsible states.
Sidebar provider
src/notesSidebarProvider.ts
New NotesSidebarProvider (TreeDataProvider) with debounced refresh (300ms), NoteManager event wiring, lazy getChildren, configurable sorting (file/date/author) and previewLength, and public refresh/getTreeItem/getChildren.
Search subsystem types & manager
src/searchTypes.ts, src/searchManager.ts
New search types and SearchManager with inverted index, indexing/update APIs, search/filter pipelines, caching, history persistence, scoring, and public search/index methods.
Tests
src/test/suite/noteTreeItem.test.ts, src/test/suite/notesSidebarProvider.test.ts
Added unit tests covering NoteTreeItem utilities and NotesSidebarProvider behavior, including sorting, labels, tooltips, debounced refresh, and event-driven updates.
Misc & packaging notes
README.md (edits), CLAUDE.md, package.json (EOF), other small files
Minor README/CLAUDE edits, ensured newline at EOF in package.json, and ignore-list updates.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant VSCode as "VS Code UI"
    participant Extension as "extension.ts"
    participant SidebarProv as "NotesSidebarProvider"
    participant NoteMgr as "NoteManager"
    participant SearchMgr as "SearchManager"
    participant Storage as "StorageManager / FS"

    User->>VSCode: Open workspace
    VSCode->>Extension: activate()
    Extension->>NoteMgr: initialize()
    Extension->>SearchMgr: buildIndex(allNotes)
    NoteMgr->>Storage: read .code-notes (workspace)
    Storage-->>NoteMgr: notes[]
    NoteMgr-->>SearchMgr: provide notes -> index
    Extension->>SidebarProv: create(provider)
    VSCode->>SidebarProv: getChildren(root)
    SidebarProv->>NoteMgr: getAllNotes()
    NoteMgr-->>SidebarProv: notes[]
    SidebarProv->>VSCode: return TreeItems (Root → File → Note)
    VSCode->>User: Render sidebar tree

    note over Storage,NoteMgr: External file CRUD
    Storage->>NoteMgr: FS event (create/update/delete)
    NoteMgr->>NoteMgr: emit noteFileChanged / noteChanged
    NoteMgr->>SidebarProv: event triggers refresh()
    SidebarProv->>SidebarProv: debounce (300ms)
    SidebarProv-->>VSCode: onDidChangeTreeData -> UI refresh
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Potential focus areas:

  • src/noteTreeItem.ts — markdown stripping, tooltip formatting, preview truncation edge cases.
  • src/notesSidebarProvider.ts — debouncing correctness, sorting implementations, config reads (autoExpand unused).
  • src/noteManager.ts — event emission correctness, cache invalidation, SearchManager integration.
  • src/searchManager.ts & src/searchTypes.ts — indexing, scoring, serialization/deserialization of history and regex/date handling.
  • src/extension.ts — activation sequencing, lifecycle/disposal of watcher and provider, and command registration timing.

Possibly related PRs

Poem

🐇 I hopped through files and counted leaves,

Built a little tree of notes with ease,
A click, a jump — I show the line,
From root to leaf each preview fine,
I nibble bugs and stash my notes with glee.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The changeset includes several files that appear to implement search and filtering functionality (docs/changelogs/v0.3.0.md, docs/search-and-filter-notes/USER_STORY.md, src/searchManager.ts, src/searchTypes.ts), which are unrelated to Issue #9's sidebar view feature and instead address Epic 13 (search and filter notes). Additionally, CLAUDE.md contains an instruction entry about updating task user stories, which is metadata documentation rather than feature implementation. These changes fall outside the scope of the sidebar view implementation specified in Issue #9. Remove the search-related files (docs/changelogs/v0.3.0.md, docs/search-and-filter-notes/USER_STORY.md, src/searchManager.ts, src/searchTypes.ts) from this PR as they implement Epic 13 and should be submitted in a separate pull request. Similarly, the CLAUDE.md metadata change should be removed or justified if it is not directly related to the sidebar feature implementation. Keep this PR focused solely on the sidebar view feature specified in Issue #9.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "feat: Add sidebar view for browsing all notes (Issue #9)" accurately describes the primary change in the changeset. It is concise, specific, and clearly identifies the main feature being added — a sidebar view for browsing all notes. The title directly relates to the bulk of the modifications, which focus on implementing the sidebar UI components, integration, and supporting infrastructure. The title effectively communicates the change to someone reviewing the git history.
Linked Issues Check ✅ Passed The code changes comprehensively address all objectives from Issue #9. The PR successfully implements a VSCode sidebar panel with an Activity Bar icon, organizes notes hierarchically by file in a collapsible tree structure, displays previews with configurable truncation, enables click-to-navigate functionality via commands, supports expanding/collapsing file groups, and provides workspace-wide note overview. The implementation includes new TreeDataProvider classes (RootTreeItem, FileTreeItem, NoteTreeItem), a NotesSidebarProvider managing the tree data, NoteManager enhancements for workspace queries and event emission, command registration for sidebar interactions, and comprehensive unit tests (78 sidebar-related tests). All core requirements from the linked issue have been fulfilled through the code changes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 68f0857 and 94459bb.

📒 Files selected for processing (6)
  • package.json (6 hunks)
  • src/extension.ts (9 hunks)
  • src/noteTreeItem.ts (1 hunks)
  • src/notesSidebarProvider.ts (1 hunks)
  • src/searchManager.ts (1 hunks)
  • src/searchTypes.ts (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (9)
src/noteManager.ts (4)

418-447: Parallelize workspace note loading

The loop awaits each file read sequentially; this will be slow with many notes. Use Promise.allSettled.

-  async getAllNotes(): Promise<Note[]> {
-    // Check cache first
-    if (this.workspaceNotesCache !== null) {
-      return this.workspaceNotesCache;
-    }
-
-    // Load all note files from storage
-    const allNoteFiles = await this.storage.getAllNoteFiles();
-    const notes: Note[] = [];
-
-    for (const noteFilePath of allNoteFiles) {
-      try {
-        const noteId = this.extractNoteIdFromFilePath(noteFilePath);
-        const note = await this.storage.loadNoteById(noteId);
-
-        // Include only non-deleted notes
-        if (note && !note.isDeleted) {
-          notes.push(note);
-        }
-      } catch (error) {
-        console.error(`Failed to load note from ${noteFilePath}:`, error);
-        // Continue with other files
-      }
-    }
-
-    // Cache the results
-    this.workspaceNotesCache = notes;
-
-    return notes;
-  }
+  async getAllNotes(): Promise<Note[]> {
+    if (this.workspaceNotesCache !== null) return this.workspaceNotesCache;
+
+    const allNoteFiles = await this.storage.getAllNoteFiles();
+    const results = await Promise.allSettled(
+      allNoteFiles.map(async fp => {
+        const noteId = this.extractNoteIdFromFilePath(fp);
+        return this.storage.loadNoteById(noteId);
+      })
+    );
+
+    const notes: Note[] = [];
+    for (const r of results) {
+      if (r.status === 'fulfilled' && r.value && !r.value.isDeleted) {
+        notes.push(r.value);
+      }
+    }
+    this.workspaceNotesCache = notes;
+    return notes;
+  }

342-344: Make cache clearing comprehensive

clearAllCache() doesn’t clear workspace caches; name implies it should. Either rename or also call clearWorkspaceCache().

   clearAllCache(): void {
-    this.noteCache.clear();
+    this.noteCache.clear();
+    this.clearWorkspaceCache();
   }

Also applies to: 503-506


274-279: Emit change event when positions update

Without an event, UI consumers (sidebar, codelens) may not refresh after position shifts.

     if (updatedNotes.length > 0) {
       this.noteCache.set(filePath, notes);
+      this.clearWorkspaceCache();
+      this.emit('noteChanged', { type: 'positionsUpdated', filePath, notes: updatedNotes });
     }

405-408: Optional: avoid fire‑and‑forget init

initializeDefaultAuthor() is async; consider awaiting in a separate async update if you need the value immediately. Safe to keep as is since method handles errors internally.

src/notesSidebarProvider.ts (3)

106-117: Use autoExpand setting

The setting is read but unused. Expand file nodes when enabled.

   private async getFileNodes(): Promise<FileTreeItem[]> {
     const notesByFile = await this.noteManager.getNotesByFile();
     const fileNodes: FileTreeItem[] = [];
     const sortBy = this.getSortBy();
+    const autoExpand = this.getAutoExpand();

     // Create file nodes
     for (const [filePath, notes] of notesByFile.entries()) {
       if (notes.length > 0) {
-        fileNodes.push(new FileTreeItem(filePath, notes, this.workspaceRoot));
+        const node = new FileTreeItem(filePath, notes, this.workspaceRoot);
+        if (autoExpand) {
+          node.collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
+        }
+        fileNodes.push(node);
       }
     }

Also applies to: 177-180


21-23: Prefer portable debounce timer type

ReturnType<typeof setTimeout> works in both Node and browser typings.


129-139: Author sort heuristic may be surprising

Sorting a file group by the first note’s author is arbitrary. Consider using most‑recent note’s author or a stable aggregate (e.g., min(author)) for predictability.

docs/architecture/ARCHITECTURE.md (1)

7-42: Add language to fenced block to satisfy linters

Label the diagram block as text.

-```
+```text
 ...
-```
+```
docs/changelogs/v0.2.0.md (1)

113-116: Resolve contradiction about sorting

Feature list says date/author sorting exists; Known Limitations says otherwise. Align the limitations section.

- - Sort options limited to file path (date/author sorting planned for future)
+ - No folder grouping in file list yet
+ - Sorting modes currently: file path, date (most recent first), author; custom/grouped sorts TBD

Also applies to: 22-24

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b5ad968 and 1f53d33.

⛔ Files ignored due to path filters (1)
  • images/task.png is excluded by !**/*.png
📒 Files selected for processing (14)
  • .gitignore (1 hunks)
  • .vscodeignore (2 hunks)
  • CLAUDE.md (1 hunks)
  • README.md (5 hunks)
  • docs/architecture/ARCHITECTURE.md (2 hunks)
  • docs/changelogs/v0.2.0.md (1 hunks)
  • docs/sidebar-view-for-browsing-all-notes/USER_STORY.md (1 hunks)
  • package.json (6 hunks)
  • src/extension.ts (8 hunks)
  • src/noteManager.ts (6 hunks)
  • src/noteTreeItem.ts (1 hunks)
  • src/notesSidebarProvider.ts (1 hunks)
  • src/test/suite/noteTreeItem.test.ts (1 hunks)
  • src/test/suite/notesSidebarProvider.test.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
src/test/suite/noteTreeItem.test.ts (2)
src/noteTreeItem.ts (3)
  • NoteTreeItem (66-158)
  • FileTreeItem (37-59)
  • RootTreeItem (21-31)
src/types.ts (1)
  • Note (37-58)
src/test/suite/notesSidebarProvider.test.ts (3)
src/notesSidebarProvider.ts (1)
  • NotesSidebarProvider (15-189)
src/types.ts (1)
  • Note (37-58)
src/noteTreeItem.ts (3)
  • RootTreeItem (21-31)
  • FileTreeItem (37-59)
  • NoteTreeItem (66-158)
src/noteManager.ts (2)
src/storageManager.ts (1)
  • StorageManager (15-377)
src/types.ts (1)
  • Note (37-58)
src/noteTreeItem.ts (1)
src/types.ts (1)
  • Note (37-58)
src/notesSidebarProvider.ts (1)
src/noteTreeItem.ts (3)
  • RootTreeItem (21-31)
  • FileTreeItem (37-59)
  • NoteTreeItem (66-158)
src/extension.ts (4)
src/noteManager.ts (1)
  • NoteManager (18-516)
src/commentController.ts (1)
  • CommentController (15-907)
src/codeLensProvider.ts (1)
  • CodeNotesLensProvider (13-190)
src/notesSidebarProvider.ts (1)
  • NotesSidebarProvider (15-189)
🪛 LanguageTool
README.md

[uncategorized] ~109-~109: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...d+Alt+Non Mac) 3. Type your note with markdown formatting 4. Click Save or pressCtrl...

(MARKDOWN_NNP)

docs/sidebar-view-for-browsing-all-notes/USER_STORY.md

[uncategorized] ~117-~117: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...Test stripMarkdown() static method (all markdown formats) - [x] Test truncateText() stat...

(MARKDOWN_NNP)

docs/changelogs/v0.2.0.md

[grammar] ~50-~50: Ensure spelling is correct
Context: ... refresh behavior - Debouncing logic (300ms delay) - All tests compile successfully...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

docs/architecture/ARCHITECTURE.md

[grammar] ~300-~300: Ensure spelling is correct
Context: ...hods**: - getChildren(element?) - Get tree children (lazy loading) - `getTreeItem(...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[uncategorized] ~360-~360: Did you mean the formatting language “Markdown” (= proper noun)?
Context: ...ods**: - stripMarkdown(text) - Remove markdown formatting from preview - `truncateText...

(MARKDOWN_NNP)

🪛 markdownlint-cli2 (0.18.1)
README.md

106-106: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


112-112: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


123-123: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


130-130: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


136-136: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


143-143: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

docs/architecture/ARCHITECTURE.md

305-305: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (15)
.gitignore (1)

12-13: LGTM! Appropriate gitignore entries.

Adding .vscode and .code-notes to the ignore list is correct. The .code-notes entry allows users to keep notes local by default while still having the option to commit them for team sharing (as documented in the README).

.vscodeignore (1)

32-32: LGTM! Appropriate vscodeignore entries.

The additions are correct:

  • node_modules/prettier/** reduces extension package size
  • .code-notes ensures user note storage isn't bundled with the extension

Also applies to: 63-64

CLAUDE.md (1)

8-8: LGTM! Development process reminder.

Adding a reminder to update user stories after task completion is a good practice for maintaining documentation.

docs/sidebar-view-for-browsing-all-notes/USER_STORY.md (1)

1-420: LGTM! Comprehensive feature documentation.

This user story document provides excellent project planning and specification for the Sidebar View feature, including:

  • Clear task breakdown across 7 phases (all marked complete)
  • Detailed acceptance criteria and technical design
  • UI/UX specifications with examples
  • Success metrics and timeline estimates

The documentation will be valuable for understanding the feature scope and implementation approach.

src/test/suite/noteTreeItem.test.ts (1)

1-419: LGTM! Comprehensive test coverage.

This test suite provides excellent coverage for the NoteTreeItem classes with 59 tests covering:

  • Markdown stripping for all common formats (bold, italic, code, links, images, headings, lists, etc.)
  • Text truncation edge cases (empty, short, long, minimum ellipsis length)
  • Tree item construction and properties (labels, tooltips, icons, collapsible states, commands)

The tests are well-organized, have clear assertions, and cover both happy paths and edge cases.

src/test/suite/notesSidebarProvider.test.ts (1)

1-402: LGTM! Thorough provider testing.

This test suite provides solid coverage for NotesSidebarProvider with 19 tests covering:

  • TreeItem identity and structure
  • Hierarchical loading (root → files → notes)
  • Sorting behavior (alphabetical by file path)
  • Debounced refresh mechanism (300ms delay, timer reset on rapid calls)
  • Event-driven updates (noteChanged, noteFileChanged)

The use of MockNoteManager and MockExtensionContext is appropriate for isolating the provider logic.

src/extension.ts (6)

32-56: LGTM! Graceful workspace-less handling.

The extension properly handles the case when no workspace folder is open by:

  • Creating an empty sidebar provider to prevent UI errors
  • Registering commands (they show appropriate error messages if invoked)
  • Informing the user that a folder is needed

This provides good UX for users who open VSCode without a workspace.


93-99: LGTM! Proper sidebar initialization.

The sidebar provider and tree view are correctly initialized with:

  • Appropriate dependencies (noteManager, workspaceRoot, context)
  • showCollapseAll: true for UI collapse functionality
  • Proper cleanup via subscriptions

116-125: LGTM! Proper command registration timing.

Moving command registration to after provider initialization is correct - ensures noteManager, commentController, and sidebarProvider are available when commands execute. The error handling is appropriate with logging, user notification, and re-throw.


213-222: LGTM! Improved addNote UX.

The update allows adding notes without a selection by using the current cursor line. This is a nice usability improvement that's well-documented in the README.


784-919: LGTM! Comprehensive sidebar commands.

The seven new sidebar commands provide complete interaction:

  • Navigation: openNoteFromSidebar, openFileFromSidebar
  • Modification: editNoteFromSidebar, deleteNoteFromSidebar
  • Information: viewNoteHistoryFromSidebar
  • UI control: refreshSidebar, collapseAll

All commands have appropriate:

  • Workspace/provider availability checks
  • Error handling with user-friendly messages
  • Integration with existing commentController for inline editing

The flexible argument handling in openNoteFromSidebar (line 795) correctly supports both direct Note objects and TreeItem wrappers.


1042-1082: File watcher implementation is safe and properly guarded.

Verification confirms the workspace guard at line 32-60 (with early return) ensures setupEventListeners is only called when a workspace folder exists. The non-null assertion at line 1047 is therefore safe.

Minor suggestion for clarity: Consider adding a comment at line 1047 documenting the assumption that workspaceFolder exists due to the activation-time guard, or add a defensive check for future-proofing if the code structure changes. This is optional for maintainability.

README.md (1)

1-499: LGTM! Comprehensive documentation updates.

The README updates thoroughly document the new sidebar feature with:

  • Clear multi-method Quick Start guide (From Code, From Sidebar)
  • Detailed Sidebar View section covering structure, navigation, and actions
  • New configuration options (sortBy, previewLength, autoExpand) with examples
  • Updated commands and keyboard shortcuts
  • FAQ updates

The documentation is well-organized, user-friendly, and accurately reflects the implemented feature.

Note: The markdownlint hints about "emphasis instead of heading" are false positives - the bold text for "Method 1:", "Method 2:", etc. are appropriate formatting for method labels, not headings.

package.json (2)

203-207: Verify keybinding when condition relaxation is intentional and working.

The addNote keybinding was changed from "editorTextFocus && editorHasSelection" to just "editorTextFocus". While the PR objectives mention support for multiple notes per line (implying no selection requirement), please confirm:

  • This change is intentional and aligns with the sidebar feature requirements.
  • The command handler gracefully handles invocation without an active selection (e.g., adding a note to the current line without pre-selected text).
  • Manual testing validated this workflow across both inline and sidebar contexts.

377-382: Verify viewsWelcome command invocation works correctly.

The welcome content references command:codeContextNotes.addNote, but this command normally expects editor context. Please confirm that:

  • The command handler supports execution from the welcome view context (e.g., creates a fresh note or prompts for file selection).
  • Clicking the link does not fail silently or throw an error.
  • The UX is clear to users (e.g., whether it opens a new editor, note dialog, or something else).

- Added SearchManager to handle indexing and querying of notes.
- Introduced search infrastructure with full-text search, regex support, and metadata indexing (author, date, file path).
- Created UI components for search input and filters in the sidebar.
- Implemented filtering capabilities by author, date range, and file path.
- Integrated search functionality with NoteManager for real-time index updates on note creation, update, and deletion.
- Established caching and search history management for improved performance.
- Documented user story, acceptance criteria, and technical implementation details in USER_STORY.md.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/noteManager.ts (1)

298-304: Update search index, clear workspace caches, and emit events after position shifts

updateNotePositions() saves moved notes but doesn’t refresh workspace caches, update the search index, or emit update events → stale sidebar/search.

   // Update cache
   if (updatedNotes.length > 0) {
     this.noteCache.set(filePath, notes);
+    // Keep workspace aggregates and search fresh
+    this.clearWorkspaceCache();
+    if (this.searchManager) {
+      for (const n of updatedNotes) {
+        await this.searchManager.updateIndex(n);
+      }
+    }
+    for (const n of updatedNotes) {
+      this.emit('noteUpdated', n);
+      this.emit('noteChanged', { type: 'updated', note: n });
+    }
   }
♻️ Duplicate comments (1)
src/noteManager.ts (1)

536-539: Cross‑platform path parsing for note IDs

Splitting by “/” breaks on Windows. Use Node’s path helpers. This was flagged earlier; applying here too.

+import * as path from 'path';
@@
-  private extractNoteIdFromFilePath(filePath: string): string {
-    const fileName = filePath.split('/').pop() || '';
-    return fileName.replace('.md', '');
-  }
+  private extractNoteIdFromFilePath(filePath: string): string {
+    const fileName = path.basename(filePath);
+    return fileName.endsWith('.md') ? fileName.slice(0, -3) : fileName;
+  }
🧹 Nitpick comments (8)
src/searchTypes.ts (1)

6-34: RegExp in SearchQuery is not JSON‑serializable; cache/history will break

Using RegExp here causes JSON.stringify(query) to drop/empty the pattern, leading to cache key collisions and broken history replays. Either:

  • Provide a serializable query shape (e.g., { regex?: { source: string; flags: string } }), or
  • Keep the interface but ensure SearchManager serializes/deserializes regex and dates when caching/persisting. I’ve proposed concrete fixes in SearchManager comments.
docs/search-and-filter-notes/USER_STORY.md (2)

161-179: Add fenced code languages to satisfy markdownlint

Specify languages for code fences:

  • ASCII UI blocks: use text
  • TypeScript samples: ts
  • JSON config: json
    This clears MD040 violations.

Also applies to: 182-191, 194-205, 212-221


424-438: Use headings instead of bold for section titles

Replace emphasis headings (e.g., “Risk: …”) with proper Markdown headings (e.g., ### Risk: …) to satisfy MD036 and improve structure.

src/searchManager.ts (4)

680-688: Glob matching is too naive; use a proven glob library

globToRegex() doesn’t support **, extglobs, or path‑separator semantics. Prefer minimatch/picomatch to match file paths reliably.

-  private globToRegex(pattern: string): RegExp {
-    let regex = pattern
-      .replace(/[.+^${}()|[\]\\]/g, '\\$&')
-      .replace(/\*/g, '.*')
-      .replace(/\?/g, '.');
-    return new RegExp(`^${regex}$`, 'i');
-  }
+  // Using 'minimatch' (or 'picomatch') keeps semantics consistent with VS Code.
+  // import minimatch from 'minimatch';
+  private globToRegex(pattern: string): RegExp {
+    // fallback shim if library is not desired: keep current impl, else remove this and use minimatch() directly where needed
+    return new RegExp(''); // placeholder if migrating; see usage sites
+  }

150-169: Author filter is case‑sensitive; consider normalization

Indexing author strings as‑is makes filtering brittle (“John Doe” vs “john doe”). Normalize (e.g., toLowerCase) on both index and query.


561-566: Regex safety (ReDoS) mitigation recommended

User‑supplied patterns can hang the extension host. Pre‑validate with a safe‑regex check or cap work (max match count/timebox).

Also applies to: 686-688


79-81: Prefer OutputChannel over console.log in extensions

Route logs to a dedicated vscode.OutputChannel for discoverability.

src/noteManager.ts (1)

103-107: Optional: avoid blocking create/update/delete on indexing

Index updates are awaited; UI may feel slower. Consider fire‑and‑forget with error logging if immediate searchability isn’t required.

Also applies to: 159-163, 205-209

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1f53d33 and f5038a4.

📒 Files selected for processing (5)
  • docs/changelogs/v0.3.0.md (1 hunks)
  • docs/search-and-filter-notes/USER_STORY.md (1 hunks)
  • src/noteManager.ts (6 hunks)
  • src/searchManager.ts (1 hunks)
  • src/searchTypes.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • docs/changelogs/v0.3.0.md
🧰 Additional context used
🧬 Code graph analysis (3)
src/searchTypes.ts (1)
src/types.ts (1)
  • Note (37-58)
src/searchManager.ts (2)
src/searchTypes.ts (7)
  • InvertedIndexEntry (130-142)
  • SearchCacheEntry (147-159)
  • SearchHistoryEntry (90-105)
  • SearchStats (110-125)
  • SearchQuery (6-34)
  • SearchResult (39-54)
  • SearchMatch (59-71)
src/types.ts (1)
  • Note (37-58)
src/noteManager.ts (1)
src/types.ts (1)
  • Note (37-58)
🪛 ast-grep (0.39.6)
src/searchManager.ts

[warning] 561-561: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(query.regex.source, query.regex.flags + 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 686-686: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${regex}$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 LanguageTool
docs/search-and-filter-notes/USER_STORY.md

[grammar] ~142-~142: Ensure spelling is correct
Context: ...Performance - [ ] Search completes in < 500ms with 100 notes - [ ] Search completes i...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
docs/search-and-filter-notes/USER_STORY.md

161-161: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


182-182: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


194-194: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


212-212: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


424-424: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


427-427: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


430-430: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


433-433: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


436-436: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (2)
src/searchManager.ts (1)

140-147: Implement fuzzy matching or remove the unused fuzzy flag from SearchQuery

The fuzzy flag is defined in SearchQuery (src/searchTypes.ts:24) but is never checked or applied in any search or scoring logic throughout searchManager.ts. Either implement fuzzy matching to honor this flag, or remove it until the feature is ready for implementation.

docs/search-and-filter-notes/USER_STORY.md (1)

66-68: Shortcut conflict verified: Ctrl/Cmd+Shift+F is VS Code's built-in Find in Files

In VS Code, Ctrl+Shift+F opens the global Search (Find in Files) view, which would shadow your planned notes search feature. Use Ctrl/Cmd+Alt+F instead to match your existing keybinding pattern (Ctrl+Alt+N, Ctrl+Alt+D, etc.) and avoid conflicts when implementing this feature.

@jnahian jnahian self-assigned this Oct 24, 2025
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
jnahian and others added 3 commits October 27, 2025 22:14
…nting proper disposable management for event listeners.
- Initialize SearchManager in extension.ts and build search index
- Fix RegExp flag duplication and lastIndex state leakage bugs
- Implement proper serialization for RegExp and Date in cache keys
- Fix search history persistence with proper type handling
- Update truncateText to handle small maxLength edge cases
- Add .js extensions to imports for ESM compatibility

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@jnahian jnahian merged commit d27b82b into main Oct 27, 2025
2 checks passed
@jnahian jnahian deleted the 9-feature-sidebar-view-for-browsing-all-notes branch October 27, 2025 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE] Sidebar view for browsing all notes

2 participants