fix: raise session timeout default, fix VS Code MCP compatibility (#674)

* fix: raise session timeout default and fix VS Code MCP compatibility (#626, #600, #611)

- #626: Raise SESSION_TIMEOUT_MINUTES default from 5 to 30 minutes.
  Complex editing sessions easily exceed 5 min between LLM calls.

- #600: Add z.preprocess(tryParseJson, ...) to operations parameter
  in n8n_update_partial_workflow. VS Code extension sends arrays as
  JSON strings.

- #611: Strip undefined values from tool args via JSON round-trip
  before Zod validation. VS Code sends explicit undefined which
  Zod's .optional() rejects.

Conceived by Romuald Członkowski - https://www.aiadvisors.pl/en

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: deduplicate tryParseJson — export from handlers-n8n-manager

tryParseJson was duplicated in handlers-workflow-diff.ts. Now imported
from handlers-n8n-manager.ts where it was already defined. Updated
test mock to use importOriginal so the real function is available.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Romuald Członkowski
2026-03-27 18:56:30 +01:00
committed by GitHub
parent fb2d306dc3
commit 6e4a9d520d
9 changed files with 42 additions and 20 deletions

View File

@@ -334,14 +334,14 @@ describe('HTTP Server Session Management', () => {
server = new SingleSessionHTTPServer();
// Mock expired sessions
// Note: Default session timeout is 5 minutes (configurable via SESSION_TIMEOUT_MINUTES)
// Note: Default session timeout is 30 minutes (configurable via SESSION_TIMEOUT_MINUTES)
const mockSessionMetadata = {
'session-1': {
lastAccess: new Date(Date.now() - 10 * 60 * 1000), // 10 minutes ago (expired with 5 min timeout)
lastAccess: new Date(Date.now() - 45 * 60 * 1000), // 45 minutes ago (expired with 30 min timeout)
createdAt: new Date(Date.now() - 60 * 60 * 1000)
},
'session-2': {
lastAccess: new Date(Date.now() - 2 * 60 * 1000), // 2 minutes ago (not expired with 5 min timeout)
lastAccess: new Date(Date.now() - 10 * 60 * 1000), // 10 minutes ago (not expired with 30 min timeout)
createdAt: new Date(Date.now() - 20 * 60 * 1000)
}
};
@@ -517,15 +517,15 @@ describe('HTTP Server Session Management', () => {
it('should get session metrics correctly', async () => {
server = new SingleSessionHTTPServer();
// Note: Default session timeout is 5 minutes (configurable via SESSION_TIMEOUT_MINUTES)
// Note: Default session timeout is 30 minutes (configurable via SESSION_TIMEOUT_MINUTES)
const now = Date.now();
(server as any).sessionMetadata = {
'active-session': {
lastAccess: new Date(now - 2 * 60 * 1000), // 2 minutes ago (not expired with 5 min timeout)
lastAccess: new Date(now - 10 * 60 * 1000), // 10 minutes ago (not expired with 30 min timeout)
createdAt: new Date(now - 20 * 60 * 1000)
},
'expired-session': {
lastAccess: new Date(now - 10 * 60 * 1000), // 10 minutes ago (expired with 5 min timeout)
lastAccess: new Date(now - 45 * 60 * 1000), // 45 minutes ago (expired with 30 min timeout)
createdAt: new Date(now - 60 * 60 * 1000)
}
};

View File

@@ -17,9 +17,13 @@ vi.mock('@/services/workflow-diff-engine');
vi.mock('@/services/n8n-api-client');
vi.mock('@/config/n8n-api');
vi.mock('@/utils/logger');
vi.mock('@/mcp/handlers-n8n-manager', () => ({
getN8nApiClient: vi.fn(),
}));
vi.mock('@/mcp/handlers-n8n-manager', async (importOriginal) => {
const actual = await importOriginal<typeof import('@/mcp/handlers-n8n-manager')>();
return {
...actual,
getN8nApiClient: vi.fn(),
};
});
// Import mocked modules
import { getN8nApiClient } from '@/mcp/handlers-n8n-manager';