Skip to content

feat: implement smart notebook & tag apply, undo, and empty notebook cleanup#26

Open
Harsh16gupta wants to merge 3 commits into
masterfrom
feat/apply-changes
Open

feat: implement smart notebook & tag apply, undo, and empty notebook cleanup#26
Harsh16gupta wants to merge 3 commits into
masterfrom
feat/apply-changes

Conversation

@Harsh16gupta

Copy link
Copy Markdown
Collaborator

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

  1. Unified Apply Action: Moves notes to cluster folders and applies tags in a single unified action.
  2. Smart Tag Matching: Automatically matches cluster keywords against each note's title/body and tags the note only if the keyword actually appears inside it.
  3. Empty Folder Clean Up: Deletes original notebook folders if they became empty of notes and subfolders after categorization.
  4. Revert (Undo): Restores notes to their original notebooks and deletes applied tags cleanly.
  5. Lock Guard: Prevents concurrent apply, undo, or cleanup operations to avoid conflicts.

Performance & Safety Optimizations

  • Unified Note Queries (2x Speedup): Fetches parent IDs, titles, and bodies in a single database call per note.
  • In-Memory Caches (10x-100x Speedup): Maps existing tags and folders at startup to replace nested database query loops with $O(1)$ Map lookups.
  • Safer Undos: Folder restoration skips deleting folders if they contain any notes or subfolders, and handles deleted parent folders gracefully.

Screen Recording:

Screencast.From.2026-07-07.17-53-33.mp4

@Harsh16gupta Harsh16gupta self-assigned this Jul 7, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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.changeLog state 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.

Comment thread src/commands/applyChanges.ts
Comment thread src/commands/applyChanges.ts Outdated
Comment thread src/commands/applyChanges.ts
Comment thread src/commands/applyChanges.ts Outdated
Comment thread src/webview/pages/DashboardPage.tsx
Comment thread src/webview/pages/DashboardPage.tsx
Comment on lines +122 to +142
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);
}
}
}

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@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:
Screenshot From 2026-07-07 21-45-12

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!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@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.

@Harsh16gupta

Copy link
Copy Markdown
Collaborator Author

All the review comments have been addressed except the one about the parent notebook (#26 (comment)).

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.

3 participants