AI Auto-Classification
The AI Auto-Classification & Active Watcher automatically processes unstructured files created in the _drafts/ directory. By scanning contents, proposing tags, suggesting clean file names, and identifying matching folder structures, it maintains a highly organized vault without manual upkeep.
1. Overview
In a large note vault, finding the correct folder and tags for a note takes time. People often create a note in a hurry, leave it untitled or improperly sorted, and lose track of it. This feature resolves that bottleneck:
- Passive Watcher: Listens for file saves in the
_drafts/directory. - LLM Categorization: Dynamically scans the document contents, compares it with existing vault directories, and generates structural suggestions.
- Active Prompting: Proposes names, tags, and destinations. The user can tweak suggestions in real-time.
- Relocation: Renames the note, saves it to the chosen folder, writes metadata back to the frontmatter, and deletes any directories left empty.
2. User Experience (UX) Flow
- Write and Save: The user creates a new note inside
_drafts/. They type their content and hitSave. - Prompt: A toast pops up: "Classify this note with AI?"
- If Later: The prompt is dismissed, and the file remains in drafts.
- If Yes: The LLM processes the note.
- Refine Metadata:
- Tags: A VS Code input box prompts: "Suggested tags", pre-populated with the LLM's tags (e.g.
meeting, sprint-15). The user can add or delete tags. - Directory: A QuickPick prompts the user to select the destination. It offers options like:
- Use existing folder:
<proposed-folder> - Create new folder:
<proposed-folder> - Other (specify manually)
- Use existing folder:
- Name: An input box prompts: "Suggested note name", pre-populated with a clean lowercase-slug (e.g.
sprint-retro-notes).
- Tags: A VS Code input box prompts: "Suggested tags", pre-populated with the LLM's tags (e.g.
- Automatic Move:
The extension updates the file's YAML frontmatter, creates the target folder if needed, renames and moves the file into place, and cleans up empty directories in drafts.
3. Under the Hood & Code Walkthrough
3.1 Filesystem Watcher Debouncing
To prevent duplicate triggers on quick sequential saves, AutoClassifyWatcher implements a 5-second debounce window. It also automatically skips files that already have tags in their YAML block:
private onSave(doc: vscode.TextDocument): void {
const filePath = doc.uri.fsPath;
if (!filePath.startsWith(this.draftsDir)) { return; }
if (!filePath.endsWith('.md')) { return; }
const content = doc.getText().trim();
if (content.length === 0) { return; }
if (this.hasTags(content)) { return; }
if (this.dismissed.has(filePath)) { return; }
const existing = this.debounceTimers.get(filePath);
if (existing) { return; }
const timer = setTimeout(() => {
this.debounceTimers.delete(filePath);
}, 5000);
this.debounceTimers.set(filePath, timer);
this.showClassifyPrompt(doc);
}
3.2 Folder Restructure & Empty Directory Cleanup
After moving a note, the extension runs a cleanup crawl up to the workspace root. If folders are left completely empty by the note relocation, they are deleted automatically:
async function removeEmptyDirsRecursively(dir: string) {
const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
let curr = dir;
while (curr !== workspaceFolder) {
const entries = await fs.promises.readdir(curr);
if (entries.length === 0) {
await fs.promises.rmdir(curr);
curr = path.dirname(curr);
} else {
break;
}
}
}