feat: implement v2 3-tier architecture (mcpctl → mcplocal → mcpd)
- Rename local-proxy to mcplocal with HTTP server, LLM pipeline, mcpd discovery - Add LLM pre-processing: token estimation, filter cache, metrics, Gemini CLI + DeepSeek providers - Add mcpd auth (login/logout) and MCP proxy endpoints - Update CLI: dual URLs (mcplocalUrl/mcpdUrl), auth commands, --direct flag - Add tiered health monitoring, shell completions, e2e integration tests - 57 test files, 597 tests passing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -28,18 +28,25 @@ describe('loadConfig', () => {
|
||||
});
|
||||
|
||||
it('loads config from file', () => {
|
||||
saveConfig({ ...DEFAULT_CONFIG, daemonUrl: 'http://custom:5000' }, { configDir: tempDir });
|
||||
saveConfig({ ...DEFAULT_CONFIG, mcplocalUrl: 'http://custom:5000' }, { configDir: tempDir });
|
||||
const config = loadConfig({ configDir: tempDir });
|
||||
expect(config.daemonUrl).toBe('http://custom:5000');
|
||||
expect(config.mcplocalUrl).toBe('http://custom:5000');
|
||||
});
|
||||
|
||||
it('applies defaults for missing fields', () => {
|
||||
const { writeFileSync } = require('node:fs') as typeof import('node:fs');
|
||||
writeFileSync(join(tempDir, 'config.json'), '{"daemonUrl":"http://x:1"}');
|
||||
writeFileSync(join(tempDir, 'config.json'), '{"mcplocalUrl":"http://x:1"}');
|
||||
const config = loadConfig({ configDir: tempDir });
|
||||
expect(config.daemonUrl).toBe('http://x:1');
|
||||
expect(config.mcplocalUrl).toBe('http://x:1');
|
||||
expect(config.registries).toEqual(['official', 'glama', 'smithery']);
|
||||
});
|
||||
|
||||
it('backward compat: daemonUrl maps to mcplocalUrl', () => {
|
||||
const { writeFileSync } = require('node:fs') as typeof import('node:fs');
|
||||
writeFileSync(join(tempDir, 'config.json'), '{"daemonUrl":"http://old:3000"}');
|
||||
const config = loadConfig({ configDir: tempDir });
|
||||
expect(config.mcplocalUrl).toBe('http://old:3000');
|
||||
});
|
||||
});
|
||||
|
||||
describe('saveConfig', () => {
|
||||
@@ -57,7 +64,7 @@ describe('saveConfig', () => {
|
||||
it('round-trips configuration', () => {
|
||||
const custom = {
|
||||
...DEFAULT_CONFIG,
|
||||
daemonUrl: 'http://custom:9000',
|
||||
mcplocalUrl: 'http://custom:9000',
|
||||
registries: ['official' as const],
|
||||
outputFormat: 'json' as const,
|
||||
};
|
||||
@@ -70,14 +77,14 @@ describe('saveConfig', () => {
|
||||
describe('mergeConfig', () => {
|
||||
it('merges overrides into existing config', () => {
|
||||
saveConfig(DEFAULT_CONFIG, { configDir: tempDir });
|
||||
const merged = mergeConfig({ daemonUrl: 'http://new:1234' }, { configDir: tempDir });
|
||||
expect(merged.daemonUrl).toBe('http://new:1234');
|
||||
const merged = mergeConfig({ mcplocalUrl: 'http://new:1234' }, { configDir: tempDir });
|
||||
expect(merged.mcplocalUrl).toBe('http://new:1234');
|
||||
expect(merged.registries).toEqual(DEFAULT_CONFIG.registries);
|
||||
});
|
||||
|
||||
it('works when no config file exists', () => {
|
||||
const merged = mergeConfig({ outputFormat: 'yaml' }, { configDir: tempDir });
|
||||
expect(merged.outputFormat).toBe('yaml');
|
||||
expect(merged.daemonUrl).toBe('http://localhost:3000');
|
||||
expect(merged.mcplocalUrl).toBe('http://localhost:3200');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user