feat: implement Obsidian MCP Bundle MVP (Phase 1-3)
- Complete project setup with TypeScript, Jest, MCPB manifest - Implement foundational infrastructure (CLI executor, logger, error handler) - Add 9 file operation tools for User Story 1 - Full MCP protocol compliance with stdio transport - Input validation and sanitization for security - Comprehensive error handling with actionable messages - Constitutional compliance: all 6 principles satisfied MVP includes: - obsidian_create_note, read, append, prepend, delete, move, rename, open, file_info - Zod validation schemas for all parameters - 30s timeout configuration with per-command overrides - Stderr-only logging with sanitized output - Graceful shutdown handling Build: ✅ 0 errors, 0 vulnerabilities Tasks: 48/167 complete (MVP milestone) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
61
src/config/timeouts.ts
Normal file
61
src/config/timeouts.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* Timeout configuration for CLI commands
|
||||
* Constitutional Principle IV: Defensive Programming
|
||||
* FR-018: 30-second default timeout with per-command overrides
|
||||
*/
|
||||
|
||||
import { TimeoutConfig } from '../utils/types.js';
|
||||
|
||||
/**
|
||||
* Default timeout configuration
|
||||
*/
|
||||
export const timeoutConfig: TimeoutConfig = {
|
||||
// Default timeout for all commands (30 seconds)
|
||||
default: 30000,
|
||||
|
||||
// Per-command overrides (in milliseconds)
|
||||
perCommand: {
|
||||
// Search operations may take longer on large vaults
|
||||
search: 45000,
|
||||
'search-tags': 45000,
|
||||
'search-properties': 45000,
|
||||
|
||||
// Sync operations may take longer
|
||||
'sync-start': 60000,
|
||||
'sync-status': 10000,
|
||||
|
||||
// Quick operations can have shorter timeouts
|
||||
'vault-list': 5000,
|
||||
'note-read': 10000,
|
||||
open: 5000,
|
||||
|
||||
// File operations are typically fast
|
||||
'create-note': 10000,
|
||||
'delete-note': 10000,
|
||||
'move-note': 10000,
|
||||
'rename-note': 10000,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Get timeout for a specific command
|
||||
*/
|
||||
export function getCommandTimeout(command: string): number {
|
||||
// Extract base command name (remove subcommands and flags)
|
||||
const baseCommand = command.split(' ')[0];
|
||||
|
||||
return timeoutConfig.perCommand[baseCommand] || timeoutConfig.default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom timeout for a command
|
||||
*/
|
||||
export function setCommandTimeout(command: string, timeout: number): void {
|
||||
if (timeout < 1000) {
|
||||
throw new Error('Timeout must be at least 1000ms (1 second)');
|
||||
}
|
||||
if (timeout > 300000) {
|
||||
throw new Error('Timeout must not exceed 300000ms (5 minutes)');
|
||||
}
|
||||
timeoutConfig.perCommand[command] = timeout;
|
||||
}
|
||||
Reference in New Issue
Block a user