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>
- 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.
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.
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.
The isEncryptionAvailable() function was throwing "Cannot read properties
of undefined" when safeStorage exists but doesn't have the
isEncryptionAvailable method (can occur on some Electron versions).
This was causing the entire settings UI to fail rendering after the
Authentication heading, hiding all API key management controls.
Fix: Add typeof check before calling safeStorage.isEncryptionAvailable()
to ensure the method exists before attempting to call it.
- Added safe electron import with fallback for non-electron environments
- Enhanced error handling when safeStorage is unavailable
- Updated encryption checks to handle cases where safeStorage is null
- Added warning message when API keys must be stored in plaintext
- Modified isEncryptionAvailable to check for both safeStorage existence and capability
Implement encryption utilities for securely storing API keys:
- encryptApiKey(): encrypts keys using Electron safeStorage with base64 encoding
- decryptApiKey(): decrypts stored keys
- isEncryptionAvailable(): checks platform support
Encryption falls back to plaintext on platforms without keyring support.
Includes comprehensive test coverage with Electron mock.