feat: implement smart notebook & tag apply, undo, and empty notebook cleanup#26
feat: implement smart notebook & tag apply, undo, and empty notebook cleanup#26Harsh16gupta wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds an “application layer” to the plugin so users can apply categorization results (move notes + apply semantic tags), undo the last apply via a persisted change log, and optionally clean up original notebooks that became empty. It also adds corresponding UI controls and plugin-side settings to support these operations.
Changes:
- Adds apply/undo/cleanup commands and a persisted
categorization.changeLogstate to support revert and cleanup workflows. - Extends the webview state machine and UI (Dashboard + History) to trigger and monitor apply/undo/cleanup progress and results.
- Introduces new message types (
apply,undo,cleanUpEmptyNotebooks, settings get/update) to coordinate between webview and plugin.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/webview/panel.css | Adds styling for Apply/Undo/Cleanup UI controls and status banners. |
| src/webview/pages/HistoryPage.tsx | Implements a History view that surfaces undo/cleanup actions and status based on stored change log. |
| src/webview/pages/DashboardPage.tsx | Adds “Apply categorization” UI + wires up apply state/progress/error handling. |
| src/webview/context/AppStateContext.tsx | Adds settings fetch/update and apply/undo/cleanup state + polling handling in the app state context. |
| src/types/panel.ts | Adds ApplyOptions, ApplyMessage, and new panel message types for apply/undo/cleanup + settings. |
| src/index.ts | Registers plugin settings and routes new webview messages to apply/undo/cleanup background operations with a lock guard. |
| src/commands/applyChanges.ts | New core implementation for apply, undo, and cleanup (tag matching, moving notes, change log persistence). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const folderMap: { [clusterId: number]: string } = {}; | ||
| const createdFolderIds: string[] = []; | ||
| let uncategorizedFolderId = ''; | ||
| if (options.method === 'notebooks' || options.method === 'both') { | ||
| for (const clusterId of uniqueClusterIds) { | ||
| const clusterName = clusterNames[clusterId] || `Cluster ${clusterId + 1}`; | ||
| const { id: childFolderId, created } = await getOrCreateFolderOptimized(clusterName); | ||
| folderMap[clusterId] = childFolderId; | ||
| if (created) { | ||
| createdFolderIds.push(childFolderId); | ||
| } | ||
| } | ||
|
|
||
| if (assignments.includes(-1)) { | ||
| const { id: noiseFolderId, created } = await getOrCreateFolderOptimized('Uncategorized'); | ||
| uncategorizedFolderId = noiseFolderId; | ||
| if (created) { | ||
| createdFolderIds.push(noiseFolderId); | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
@HahaBill, I have a quick question about the folder structure when applying categorization.
Right now, when the user clicks Apply, the plugin creates cluster folders (like "Machine Learning", "Web Development") directly at the root level of the notebook list. So they just sit alongside all the user's existing notebooks.
The other option is to nest them under a single parent folder, something like:

This keeps things cleaner (I don't like this approach as it creates an extra level of nesting).
Which approach do you think works better? Let me know what you think!
There was a problem hiding this comment.
@Harsh16gupta Personally, I think not having AI Categorized Notes and put them all at the root level is cleaner and better UX.
I would try to think of a smooth UI/UX strategy to make users know that those folders were AI-generated. If that is too ambitious then putting them at the root level suffice for now.
|
All the review comments have been addressed except the one about the parent notebook (#26 (comment)). |
Overview
This PR implements the note categorization application layer, allowing users to apply folder organizations and smart semantic tags to notes in one click, revert changes (Undo), and clean up empty original notebook folders.
Key Features
Performance & Safety Optimizations
$O(1)$Map lookups.Screen Recording:
Screencast.From.2026-07-07.17-53-33.mp4