- Fix template literal type issue in notifications.ts by adding
explicit String() coercion for args.recursive
- Replace Vault.trash() with FileManager.trashFile() to respect
user's configured deletion preferences (system trash or .trash/)
- Remove unused trash() method from IVaultAdapter and VaultAdapter
- Update tests to reflect new deletion behavior
This commit resolves all required and optional issues from the plugin
submission review to comply with Obsidian plugin guidelines.
Required Changes:
- Type Safety: Added eslint-disable comments with justifications for
necessary any types in JSON-RPC tool argument handling
- Command IDs: Removed redundant "mcp-server" prefix from command
identifiers (BREAKING CHANGE):
- start-mcp-server → start-server
- stop-mcp-server → stop-server
- restart-mcp-server → restart-server
- Promise Handling: Added void operator for intentional fire-and-forget
promise in notification queue processing
- ESLint Directives: Added descriptive explanations to all
eslint-disable comments
- Switch Statement Scope: Wrapped case blocks in braces to fix lexical
declaration warnings in glob pattern matcher
- Regular Expression: Added eslint-disable comment for control character
validation in Windows path checking
- Type Definitions: Changed empty object type {} to object in MCP
capabilities interface
- Import Statements: Added comprehensive justifications for require()
usage in Electron/Node.js modules (synchronous access required)
Optional Improvements:
- Code Cleanup: Removed unused imports (MCPPluginSettings, TFile,
VaultInfo)
Documentation:
- Enhanced inline code documentation for ESLint suppressions and
require() statements
- Added detailed rationale for synchronous module loading requirements
in Obsidian plugin context
- Updated CHANGELOG.md for version 1.1.2
All changes verified:
- Build: Successful with no TypeScript errors
- Tests: All 760 tests passing
- ESLint: All review-required issues resolved
Version bumped to 1.1.2 in package.json and manifest.json
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove unused vault.delete() method in favor of trashFile()
- Replace \x00-\x1F with \u0000-\u001F for clearer regex syntax
- Verify no unused imports, variables, or scoping issues
All cleanup tasks verified with tsc --noUnusedLocals --noUnusedParameters
Replace createEl('h2'), createEl('h3'), and createEl('h4') with
Setting().setHeading().setName() in settings.ts to comply with
Obsidian plugin submission requirements. The Setting API provides
consistent styling and is the recommended approach for settings tabs.
Changes:
- Replace h2 heading for 'MCP Server Settings'
- Replace h3 heading for 'Server Status'
- Replace h4 heading for 'MCP Client Configuration'
- Remove custom 'mcp-heading' class (Setting API provides styling)
Note: Modal headings in notification-history.ts are unchanged as they
use the standard Modal API which is separate from the Settings API.
- Add proper TypeScript typing to require() calls using 'as typeof import(...)'
- Add eslint-disable-next-line @typescript-eslint/no-var-requires directives
- Add clear comments explaining why require() is necessary for synchronous module loading
- require('electron') in encryption-utils.ts: needed for conditional Electron safeStorage access
- require('crypto') in crypto-adapter.ts: needed for synchronous Node.js crypto access
Both require() calls are intentional for runtime conditional module loading and
are properly handled by esbuild during bundling. These modules may not be
available in all environments, so they are loaded conditionally with proper
error handling.
Fixes Task 5 of Obsidian plugin submission review requirements.
Wrap async callbacks in void operators for DOM addEventListener calls
to properly handle Promise<void> returns in void contexts. This follows
TypeScript best practices and Obsidian plugin guidelines.
Changes:
- settings.ts: Fix 5 button click handlers (server controls, API key actions, config copy)
- notification-history.ts: Fix export button click handler
All async operations are properly awaited within void-wrapped IIFEs,
ensuring errors are not silently swallowed while maintaining the
expected void return type for event listeners.
Per Obsidian plugin submission requirements, only console.warn,
console.error, and console.debug are allowed.
Changes:
- Removed console.log from main.ts (API key generation and migration)
- Removed console.log from mcp-server.ts (server start/stop messages)
- Replaced console.log with console.debug in notifications.ts
- Updated tests to expect console.debug instead of console.log
All functionality is preserved - server status is still shown via
Notice and status bar, and tool calls are still logged when enabled.
Replace all `any` types with properly defined TypeScript interfaces and types throughout the codebase to improve type safety and eliminate type-related code quality issues.
Changes:
- Define ElectronSafeStorage interface for Electron's safeStorage API
- Create LegacySettings interface for settings migration in main.ts
- Define JSONValue, JSONRPCParams types for JSON-RPC protocol
- Define JSONSchemaProperty for tool input schemas
- Create YAMLValue type for frontmatter values
- Define FrontmatterValue type for adapter interfaces
- Update middleware to use proper Express NextFunction and JSONRPCResponse types
- Fix tool registry to handle args with proper typing (with eslint-disable for dynamic dispatch)
- Fix notifications to use proper types with eslint-disable where dynamic access is needed
- Add proper null safety assertions where appropriate
- Fix TFolder stat access with proper type extension
All type errors resolved. TypeScript compilation passes with --skipLibCheck.
Extended word count functionality to read operations (read_note, stat, list) to complement existing write operation support.
Changes:
- read_note: Now automatically includes wordCount when returning content (with withContent or parseFrontmatter options)
- stat: Added optional includeWordCount parameter with performance warning
- list: Added optional includeWordCount parameter with performance warning
- All operations use same word counting rules (excludes frontmatter and Obsidian comments)
- Best-effort error handling for batch operations
Technical details:
- Updated ParsedNote and FileMetadata type definitions to include optional wordCount field
- Added comprehensive test coverage (18 new tests)
- Updated tool descriptions with usage notes and performance warnings
- Updated CHANGELOG.md to document new features in version 1.1.0
Add automatic word count and link validation to create_note, update_note,
and update_sections operations to provide immediate feedback on note content
quality and link integrity.
Features:
- Word counting excludes frontmatter and Obsidian comments, includes all
other content (code blocks, inline code, headings, lists, etc.)
- Link validation checks wikilinks, heading links, and embeds
- Results categorized as: valid links, broken notes (note doesn't exist),
and broken headings (note exists but heading missing)
- Detailed broken link info includes line number and context snippet
- Human-readable summary (e.g., "15 links: 12 valid, 2 broken notes, 1 broken heading")
- Opt-out capability via validateLinks parameter (default: true) for
performance-critical operations
Implementation:
- New ContentUtils.countWords() for word counting logic
- Enhanced LinkUtils.validateLinks() for comprehensive link validation
- Updated create_note, update_note, update_sections to return wordCount
and linkValidation fields
- Updated MCP tool descriptions to document new features and parameters
- update_note now returns structured JSON instead of simple success message
Response format changes:
- create_note: added wordCount and linkValidation fields
- update_note: changed to structured response with wordCount and linkValidation
- update_sections: added wordCount and linkValidation fields
Breaking changes:
- update_note response format changed from simple message to structured JSON
Moved 36 inline style assignments from notification-history.ts to CSS classes in styles.css following the mcp-* naming pattern. This improves maintainability and separates presentation from logic.
Changes:
- Created CSS classes for all static styles (mcp-history-filters, mcp-history-count, mcp-history-list, mcp-history-empty, mcp-history-entry, mcp-history-entry-header, mcp-history-entry-header-meta, mcp-history-entry-args, mcp-history-entry-error, mcp-history-actions)
- Created dynamic state classes for conditional styling (mcp-history-entry-border, mcp-history-entry-title-success, mcp-history-entry-title-error)
- Updated notification-history.ts to use CSS classes via addClass() instead of inline style assignments
- Retained only truly dynamic styles (borderBottom conditional, color conditional) as class toggles
All tests pass (716/716), build succeeds.
Replace 90+ JavaScript style assignments with semantic CSS classes in
settings panel. Improves maintainability and follows Obsidian plugin
guidelines requiring styles in CSS files rather than JavaScript.
Changes:
- Add semantic CSS classes to styles.css for auth sections, tabs,
config display, labels, and helper text
- Replace all .style.* assignments in settings.ts with CSS classes
- Use conditional class application for dynamic tab active state
- Preserve all existing functionality and visual appearance
Addresses ObsidianReviewBot requirement for PR #8298
Replace vault.delete() with fileManager.trashFile() to respect user's
trash preferences configured in Obsidian settings. This ensures deleted
files go to the user's configured trash location instead of being
permanently deleted without respecting system preferences.
Changes:
- src/tools/note-tools.ts: Replace vault.delete with fileManager.trashFile
in createNote (overwrite conflict) and deleteNote (permanent delete)
- tests/note-tools.test.ts: Update test expectations to check for
fileManager.trashFile calls instead of vault.delete
Addresses ObsidianReviewBot required issue #3.
Remove 'MCP Server' prefix from command display names to comply with
Obsidian plugin guidelines. Command IDs remain unchanged for API stability.
- Start MCP Server → Start server
- Stop MCP Server → Stop server
- Restart MCP Server → Restart server
Replace hardcoded .obsidian references in exclude pattern examples
with generic 'templates' folder. Config directory location is
user-configurable in Obsidian, so examples should not reference
system directories.
Addresses ObsidianReviewBot feedback for plugin submission.
This fixes the issues introduced in the previous commit where:
- Authentication section would collapse when switching config tabs and couldn't be reopened
- Notification toggle would disappear after enabling notifications
Root cause: The previous update methods were removing or re-querying DOM elements incorrectly.
Solution:
- Store direct references to configContainerEl and notificationToggleEl
- Wrap notification toggle in dedicated container to preserve it during updates
- updateNotificationSection() now preserves both summary AND toggle, only removes additional settings
- updateConfigSection() uses stored reference instead of querying, preventing collapse
Both sections now maintain their open/closed state correctly during targeted updates.
Fixed two UI bugs in the settings panel:
- Authentication section no longer collapses when switching between Windsurf/Claude Code config tabs
- Notification settings now properly appear/disappear when toggling the notifications enable switch
Changes:
- Added authDetailsEl reference to track authentication details element state
- Created updateConfigSection() method to update only config tabs without full page re-render
- Fixed updateNotificationSection() child removal logic to properly clear settings before rebuild
- Both methods now preserve the open/closed state of their respective collapsible sections
Removed console.error calls from error handlers that gracefully skip
problematic files and continue processing. These handlers catch errors
when reading or parsing files but successfully return fallback values,
so logging errors creates unnecessary noise during testing and deployment.
Changes:
- vault-tools.ts: Remove console.error from search and frontmatter extraction
- search-utils.ts: Remove console.error from file search handlers
- waypoint-utils.ts: Remove console.error from file read handler
- frontmatter-utils.ts: Remove console.error from YAML and Excalidraw parsing
Test updates:
- Remove test assertions checking for console.error calls since these
are no longer emitted by graceful error handlers
All 709 tests pass with no console noise during error handling.
- Replace direct crypto.getRandomValues with getCryptoRandomValues
- Fixes Node.js test environment compatibility
- Maintains production behavior in Electron
- Create getCryptoRandomValues() utility
- Support both window.crypto (browser/Electron) and crypto.webcrypto (Node.js)
- Add comprehensive test coverage for adapter functionality
- Replace raw HTML inputs with Obsidian Setting components
- Add DOM element references for targeted updates
- Eliminate destructive re-render on filter changes
- Update only list container and count on filter apply
- Fix tool filter input not accepting text
- Fix status dropdown not showing selection
Co-Authored-By: Claude <noreply@anthropic.com>
- Add targeted DOM update method for notification section
- Store reference to details element during initial render
- Replace full page re-render with targeted subsection update
- Preserve open/closed state during updates
Co-Authored-By: Claude <noreply@anthropic.com>
- Update notification format to multi-line with explicit label
- First line: 'MCP Tool Called: tool_name'
- Second line: parameters (if enabled)
- Add comprehensive tests for notification formatting
Co-Authored-By: Claude <noreply@anthropic.com>
Wraps the UI Notifications section in a details/summary element for progressive disclosure. Updates all setting references from containerEl to notifDetails to properly nest settings within the collapsible section. Simplifies setting descriptions to be more concise.
- Wrap Authentication in details/summary for progressive disclosure
- Update containerEl references to authDetails within the section
- Simplify API Key description from "Use this key in the Authorization header as Bearer token" to "Use as Bearer token in Authorization header"
Root cause: electron.safeStorage was undefined (not null) when the
property doesn't exist, causing "Cannot read properties of undefined"
error when accessing isEncryptionAvailable.
Fix: Normalize undefined to null with `|| null` operator when importing
safeStorage, ensuring consistent null checks throughout the code.
Changes:
- Set safeStorage to null if electron.safeStorage is undefined
- Remove all diagnostic try-catch blocks from settings UI
- Remove console.log debugging statements
- Restore clean code that now works correctly
This resolves the settings UI crash that prevented the API key
management section from displaying.
Moved isEncryptionAvailable() to top of file and refactored to prevent
"Cannot read properties of undefined" errors when safeStorage exists
but doesn't have the isEncryptionAvailable method.
Changes:
- Move isEncryptionAvailable() before other functions so it can be used
- Add typeof check for isEncryptionAvailable method existence
- Use isEncryptionAvailable() helper in encryptApiKey() instead of
directly calling safeStorage.isEncryptionAvailable()
- Ensures consistent safe checking across all encryption operations
This fixes the settings UI crash that prevented API key management
section from rendering.