codevault 1.8.4 → 1.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -2
- package/dist/chunking/token-counter.d.ts.map +1 -1
- package/dist/chunking/token-counter.js +16 -10
- package/dist/chunking/token-counter.js.map +1 -1
- package/dist/cli/commands/index-cmd.d.ts.map +1 -1
- package/dist/cli/commands/index-cmd.js +108 -97
- package/dist/cli/commands/index-cmd.js.map +1 -1
- package/dist/cli/commands/interactive-config.d.ts.map +1 -1
- package/dist/cli/commands/interactive-config.js +40 -3
- package/dist/cli/commands/interactive-config.js.map +1 -1
- package/dist/cli/commands/search-cmd.d.ts.map +1 -1
- package/dist/cli/commands/search-cmd.js +11 -7
- package/dist/cli/commands/search-cmd.js.map +1 -1
- package/dist/cli/commands/search-with-code-cmd.d.ts.map +1 -1
- package/dist/cli/commands/search-with-code-cmd.js +3 -1
- package/dist/cli/commands/search-with-code-cmd.js.map +1 -1
- package/dist/cli/utils.d.ts +56 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +98 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/config/constants.d.ts +4 -0
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +2 -0
- package/dist/config/constants.js.map +1 -1
- package/dist/context/packs.d.ts.map +1 -1
- package/dist/context/packs.js +3 -1
- package/dist/context/packs.js.map +1 -1
- package/dist/core/IndexerEngine.d.ts +2 -0
- package/dist/core/IndexerEngine.d.ts.map +1 -1
- package/dist/core/IndexerEngine.js +34 -26
- package/dist/core/IndexerEngine.js.map +1 -1
- package/dist/core/SearchService.d.ts +1 -0
- package/dist/core/SearchService.d.ts.map +1 -1
- package/dist/core/SearchService.js +18 -12
- package/dist/core/SearchService.js.map +1 -1
- package/dist/core/batch-indexer.d.ts.map +1 -1
- package/dist/core/batch-indexer.js +5 -13
- package/dist/core/batch-indexer.js.map +1 -1
- package/dist/core/indexing/IndexFinalizationStage.d.ts.map +1 -1
- package/dist/core/indexing/IndexFinalizationStage.js +21 -2
- package/dist/core/indexing/IndexFinalizationStage.js.map +1 -1
- package/dist/core/indexing/IndexState.d.ts +3 -8
- package/dist/core/indexing/IndexState.d.ts.map +1 -1
- package/dist/core/indexing/IndexState.js.map +1 -1
- package/dist/core/indexing/PersistManager.d.ts +1 -1
- package/dist/core/indexing/PersistManager.d.ts.map +1 -1
- package/dist/core/indexing/PersistManager.js +17 -17
- package/dist/core/indexing/PersistManager.js.map +1 -1
- package/dist/core/search/HybridFusion.d.ts +0 -1
- package/dist/core/search/HybridFusion.d.ts.map +1 -1
- package/dist/core/search/HybridFusion.js +2 -14
- package/dist/core/search/HybridFusion.js.map +1 -1
- package/dist/core/search/ResultMapper.d.ts +0 -1
- package/dist/core/search/ResultMapper.d.ts.map +1 -1
- package/dist/core/search/ResultMapper.js +2 -13
- package/dist/core/search/ResultMapper.js.map +1 -1
- package/dist/core/search/SearchContextManager.d.ts +3 -0
- package/dist/core/search/SearchContextManager.d.ts.map +1 -1
- package/dist/core/search/SearchContextManager.js +15 -2
- package/dist/core/search/SearchContextManager.js.map +1 -1
- package/dist/core/search.d.ts.map +1 -1
- package/dist/core/search.js +9 -4
- package/dist/core/search.js.map +1 -1
- package/dist/languages/rules.d.ts.map +1 -1
- package/dist/languages/rules.js +14 -5
- package/dist/languages/rules.js.map +1 -1
- package/dist/mcp/schemas.d.ts +2 -2
- package/dist/mcp-server.d.ts +1 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +32 -21
- package/dist/mcp-server.js.map +1 -1
- package/dist/providers/base.d.ts +3 -2
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/base.js +3 -1
- package/dist/providers/base.js.map +1 -1
- package/dist/providers/chat-llm.d.ts +2 -2
- package/dist/providers/chat-llm.d.ts.map +1 -1
- package/dist/providers/chat-llm.js +4 -1
- package/dist/providers/chat-llm.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +4 -1
- package/dist/providers/openai.js.map +1 -1
- package/dist/ranking/api-reranker.d.ts.map +1 -1
- package/dist/ranking/api-reranker.js +27 -8
- package/dist/ranking/api-reranker.js.map +1 -1
- package/dist/ranking/symbol-boost.d.ts.map +1 -1
- package/dist/ranking/symbol-boost.js +4 -11
- package/dist/ranking/symbol-boost.js.map +1 -1
- package/dist/search/bm25.d.ts +10 -0
- package/dist/search/bm25.d.ts.map +1 -1
- package/dist/search/bm25.js +16 -0
- package/dist/search/bm25.js.map +1 -1
- package/dist/storage/encrypted-chunks.d.ts +3 -0
- package/dist/storage/encrypted-chunks.d.ts.map +1 -1
- package/dist/storage/encrypted-chunks.js +108 -16
- package/dist/storage/encrypted-chunks.js.map +1 -1
- package/dist/synthesis/conversational-synthesizer.d.ts +2 -1
- package/dist/synthesis/conversational-synthesizer.d.ts.map +1 -1
- package/dist/synthesis/conversational-synthesizer.js +6 -1
- package/dist/synthesis/conversational-synthesizer.js.map +1 -1
- package/dist/synthesis/prompt-builder.d.ts.map +1 -1
- package/dist/synthesis/prompt-builder.js +40 -13
- package/dist/synthesis/prompt-builder.js.map +1 -1
- package/dist/synthesis/synthesizer.d.ts.map +1 -1
- package/dist/synthesis/synthesizer.js +14 -2
- package/dist/synthesis/synthesizer.js.map +1 -1
- package/dist/tests/api-reranker.test.d.ts +2 -0
- package/dist/tests/api-reranker.test.d.ts.map +1 -0
- package/dist/tests/api-reranker.test.js +575 -0
- package/dist/tests/api-reranker.test.js.map +1 -0
- package/dist/tests/bm25.test.d.ts +2 -0
- package/dist/tests/bm25.test.d.ts.map +1 -0
- package/dist/tests/bm25.test.js +340 -0
- package/dist/tests/bm25.test.js.map +1 -0
- package/dist/tests/chunking/file-grouper.test.d.ts +2 -0
- package/dist/tests/chunking/file-grouper.test.d.ts.map +1 -0
- package/dist/tests/chunking/file-grouper.test.js +495 -0
- package/dist/tests/chunking/file-grouper.test.js.map +1 -0
- package/dist/tests/chunking/semantic-chunker.test.d.ts +2 -0
- package/dist/tests/chunking/semantic-chunker.test.d.ts.map +1 -0
- package/dist/tests/chunking/semantic-chunker.test.js +509 -0
- package/dist/tests/chunking/semantic-chunker.test.js.map +1 -0
- package/dist/tests/chunking/token-counter.test.d.ts +2 -0
- package/dist/tests/chunking/token-counter.test.d.ts.map +1 -0
- package/dist/tests/chunking/token-counter.test.js +441 -0
- package/dist/tests/chunking/token-counter.test.js.map +1 -0
- package/dist/tests/cli/ask-cmd.test.d.ts +2 -0
- package/dist/tests/cli/ask-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/ask-cmd.test.js +152 -0
- package/dist/tests/cli/ask-cmd.test.js.map +1 -0
- package/dist/tests/cli/chat-cmd.test.d.ts +2 -0
- package/dist/tests/cli/chat-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/chat-cmd.test.js +118 -0
- package/dist/tests/cli/chat-cmd.test.js.map +1 -0
- package/dist/tests/cli/config-cmd.test.d.ts +2 -0
- package/dist/tests/cli/config-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/config-cmd.test.js +226 -0
- package/dist/tests/cli/config-cmd.test.js.map +1 -0
- package/dist/tests/cli/context.test.d.ts +2 -0
- package/dist/tests/cli/context.test.d.ts.map +1 -0
- package/dist/tests/cli/context.test.js +158 -0
- package/dist/tests/cli/context.test.js.map +1 -0
- package/dist/tests/cli/index-cmd.test.d.ts +2 -0
- package/dist/tests/cli/index-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/index-cmd.test.js +89 -0
- package/dist/tests/cli/index-cmd.test.js.map +1 -0
- package/dist/tests/cli/index.test.d.ts +2 -0
- package/dist/tests/cli/index.test.d.ts.map +1 -0
- package/dist/tests/cli/index.test.js +167 -0
- package/dist/tests/cli/index.test.js.map +1 -0
- package/dist/tests/cli/info-cmd.test.d.ts +2 -0
- package/dist/tests/cli/info-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/info-cmd.test.js +47 -0
- package/dist/tests/cli/info-cmd.test.js.map +1 -0
- package/dist/tests/cli/interactive-config.test.d.ts +2 -0
- package/dist/tests/cli/interactive-config.test.d.ts.map +1 -0
- package/dist/tests/cli/interactive-config.test.js +30 -0
- package/dist/tests/cli/interactive-config.test.js.map +1 -0
- package/dist/tests/cli/mcp-cmd.test.d.ts +2 -0
- package/dist/tests/cli/mcp-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/mcp-cmd.test.js +47 -0
- package/dist/tests/cli/mcp-cmd.test.js.map +1 -0
- package/dist/tests/cli/search-cmd.test.d.ts +2 -0
- package/dist/tests/cli/search-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/search-cmd.test.js +120 -0
- package/dist/tests/cli/search-cmd.test.js.map +1 -0
- package/dist/tests/cli/search-with-code-cmd.test.d.ts +2 -0
- package/dist/tests/cli/search-with-code-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/search-with-code-cmd.test.js +140 -0
- package/dist/tests/cli/search-with-code-cmd.test.js.map +1 -0
- package/dist/tests/cli/update-cmd.test.d.ts +2 -0
- package/dist/tests/cli/update-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/update-cmd.test.js +75 -0
- package/dist/tests/cli/update-cmd.test.js.map +1 -0
- package/dist/tests/cli/utils.test.d.ts +2 -0
- package/dist/tests/cli/utils.test.d.ts.map +1 -0
- package/dist/tests/cli/utils.test.js +119 -0
- package/dist/tests/cli/utils.test.js.map +1 -0
- package/dist/tests/cli/watch-cmd.test.d.ts +2 -0
- package/dist/tests/cli/watch-cmd.test.d.ts.map +1 -0
- package/dist/tests/cli/watch-cmd.test.js +84 -0
- package/dist/tests/cli/watch-cmd.test.js.map +1 -0
- package/dist/tests/cli-ui.test.d.ts +2 -0
- package/dist/tests/cli-ui.test.d.ts.map +1 -0
- package/dist/tests/cli-ui.test.js +608 -0
- package/dist/tests/cli-ui.test.js.map +1 -0
- package/dist/tests/codemap-io.test.d.ts +2 -0
- package/dist/tests/codemap-io.test.d.ts.map +1 -0
- package/dist/tests/codemap-io.test.js +992 -0
- package/dist/tests/codemap-io.test.js.map +1 -0
- package/dist/tests/config/apply-env.test.d.ts +2 -0
- package/dist/tests/config/apply-env.test.d.ts.map +1 -0
- package/dist/tests/config/apply-env.test.js +717 -0
- package/dist/tests/config/apply-env.test.js.map +1 -0
- package/dist/tests/config/constants.test.d.ts +2 -0
- package/dist/tests/config/constants.test.d.ts.map +1 -0
- package/dist/tests/config/constants.test.js +406 -0
- package/dist/tests/config/constants.test.js.map +1 -0
- package/dist/tests/config/loader.test.d.ts +2 -0
- package/dist/tests/config/loader.test.d.ts.map +1 -0
- package/dist/tests/config/loader.test.js +716 -0
- package/dist/tests/config/loader.test.js.map +1 -0
- package/dist/tests/config/resolver.test.d.ts +2 -0
- package/dist/tests/config/resolver.test.d.ts.map +1 -0
- package/dist/tests/config/resolver.test.js +402 -0
- package/dist/tests/config/resolver.test.js.map +1 -0
- package/dist/tests/config/types.test.d.ts +2 -0
- package/dist/tests/config/types.test.d.ts.map +1 -0
- package/dist/tests/config/types.test.js +460 -0
- package/dist/tests/config/types.test.js.map +1 -0
- package/dist/tests/context-packs.test.d.ts +2 -0
- package/dist/tests/context-packs.test.d.ts.map +1 -0
- package/dist/tests/context-packs.test.js +826 -0
- package/dist/tests/context-packs.test.js.map +1 -0
- package/dist/tests/conversational-synthesizer.test.d.ts +2 -0
- package/dist/tests/conversational-synthesizer.test.d.ts.map +1 -0
- package/dist/tests/conversational-synthesizer.test.js +595 -0
- package/dist/tests/conversational-synthesizer.test.js.map +1 -0
- package/dist/tests/database.test.d.ts +2 -0
- package/dist/tests/database.test.d.ts.map +1 -0
- package/dist/tests/database.test.js +965 -0
- package/dist/tests/database.test.js.map +1 -0
- package/dist/tests/encrypted-chunks.test.d.ts +2 -0
- package/dist/tests/encrypted-chunks.test.d.ts.map +1 -0
- package/dist/tests/encrypted-chunks.test.js +1470 -0
- package/dist/tests/encrypted-chunks.test.js.map +1 -0
- package/dist/tests/hybrid.test.d.ts +2 -0
- package/dist/tests/hybrid.test.d.ts.map +1 -0
- package/dist/tests/hybrid.test.js +456 -0
- package/dist/tests/hybrid.test.js.map +1 -0
- package/dist/tests/indexer/ChangeQueue.test.d.ts +12 -0
- package/dist/tests/indexer/ChangeQueue.test.d.ts.map +1 -0
- package/dist/tests/indexer/ChangeQueue.test.js +441 -0
- package/dist/tests/indexer/ChangeQueue.test.js.map +1 -0
- package/dist/tests/indexer/ProviderManager.test.d.ts +12 -0
- package/dist/tests/indexer/ProviderManager.test.d.ts.map +1 -0
- package/dist/tests/indexer/ProviderManager.test.js +290 -0
- package/dist/tests/indexer/ProviderManager.test.js.map +1 -0
- package/dist/tests/indexer/WatchService.test.d.ts +14 -0
- package/dist/tests/indexer/WatchService.test.d.ts.map +1 -0
- package/dist/tests/indexer/WatchService.test.js +667 -0
- package/dist/tests/indexer/WatchService.test.js.map +1 -0
- package/dist/tests/indexer/merkle.test.d.ts +11 -0
- package/dist/tests/indexer/merkle.test.d.ts.map +1 -0
- package/dist/tests/indexer/merkle.test.js +497 -0
- package/dist/tests/indexer/merkle.test.js.map +1 -0
- package/dist/tests/indexer/update.test.d.ts +10 -0
- package/dist/tests/indexer/update.test.d.ts.map +1 -0
- package/dist/tests/indexer/update.test.js +317 -0
- package/dist/tests/indexer/update.test.js.map +1 -0
- package/dist/tests/indexer/watch.test.d.ts +8 -0
- package/dist/tests/indexer/watch.test.d.ts.map +1 -0
- package/dist/tests/indexer/watch.test.js +95 -0
- package/dist/tests/indexer/watch.test.js.map +1 -0
- package/dist/tests/integration/index-search.integration.test.js +1 -0
- package/dist/tests/integration/index-search.integration.test.js.map +1 -1
- package/dist/tests/languages.test.d.ts +2 -0
- package/dist/tests/languages.test.d.ts.map +1 -0
- package/dist/tests/languages.test.js +575 -0
- package/dist/tests/languages.test.js.map +1 -0
- package/dist/tests/logger-redaction.test.d.ts +2 -0
- package/dist/tests/logger-redaction.test.d.ts.map +1 -0
- package/dist/tests/logger-redaction.test.js +48 -0
- package/dist/tests/logger-redaction.test.js.map +1 -0
- package/dist/tests/logger.test.d.ts +2 -0
- package/dist/tests/logger.test.d.ts.map +1 -0
- package/dist/tests/logger.test.js +468 -0
- package/dist/tests/logger.test.js.map +1 -0
- package/dist/tests/markdown-formatter.test.d.ts +2 -0
- package/dist/tests/markdown-formatter.test.d.ts.map +1 -0
- package/dist/tests/markdown-formatter.test.js +453 -0
- package/dist/tests/markdown-formatter.test.js.map +1 -0
- package/dist/tests/mcp/tools/use-context-pack.test.d.ts +7 -0
- package/dist/tests/mcp/tools/use-context-pack.test.d.ts.map +1 -0
- package/dist/tests/mcp/tools/use-context-pack.test.js +505 -0
- package/dist/tests/mcp/tools/use-context-pack.test.js.map +1 -0
- package/dist/tests/mutex.test.d.ts +2 -0
- package/dist/tests/mutex.test.d.ts.map +1 -0
- package/dist/tests/mutex.test.js +489 -0
- package/dist/tests/mutex.test.js.map +1 -0
- package/dist/tests/path-helpers.test.d.ts +2 -0
- package/dist/tests/path-helpers.test.d.ts.map +1 -0
- package/dist/tests/path-helpers.test.js +332 -0
- package/dist/tests/path-helpers.test.js.map +1 -0
- package/dist/tests/prompt-builder.test.d.ts +2 -0
- package/dist/tests/prompt-builder.test.d.ts.map +1 -0
- package/dist/tests/prompt-builder.test.js +417 -0
- package/dist/tests/prompt-builder.test.js.map +1 -0
- package/dist/tests/providers/base.test.d.ts +2 -0
- package/dist/tests/providers/base.test.d.ts.map +1 -0
- package/dist/tests/providers/base.test.js +299 -0
- package/dist/tests/providers/base.test.js.map +1 -0
- package/dist/tests/providers/chat-llm.test.d.ts +2 -0
- package/dist/tests/providers/chat-llm.test.d.ts.map +1 -0
- package/dist/tests/providers/chat-llm.test.js +435 -0
- package/dist/tests/providers/chat-llm.test.js.map +1 -0
- package/dist/tests/providers/index.test.d.ts +2 -0
- package/dist/tests/providers/index.test.d.ts.map +1 -0
- package/dist/tests/providers/index.test.js +204 -0
- package/dist/tests/providers/index.test.js.map +1 -0
- package/dist/tests/providers/mock.test.d.ts +2 -0
- package/dist/tests/providers/mock.test.d.ts.map +1 -0
- package/dist/tests/providers/mock.test.js +225 -0
- package/dist/tests/providers/mock.test.js.map +1 -0
- package/dist/tests/providers/openai.test.d.ts +2 -0
- package/dist/tests/providers/openai.test.d.ts.map +1 -0
- package/dist/tests/providers/openai.test.js +408 -0
- package/dist/tests/providers/openai.test.js.map +1 -0
- package/dist/tests/providers/token-counter.test.d.ts +2 -0
- package/dist/tests/providers/token-counter.test.d.ts.map +1 -0
- package/dist/tests/providers/token-counter.test.js +247 -0
- package/dist/tests/providers/token-counter.test.js.map +1 -0
- package/dist/tests/rate-limiter.test.js +392 -1
- package/dist/tests/rate-limiter.test.js.map +1 -1
- package/dist/tests/scope.test.d.ts +2 -0
- package/dist/tests/scope.test.d.ts.map +1 -0
- package/dist/tests/scope.test.js +529 -0
- package/dist/tests/scope.test.js.map +1 -0
- package/dist/tests/simple-lru.test.js +377 -0
- package/dist/tests/simple-lru.test.js.map +1 -1
- package/dist/tests/symbol-boost.test.js +730 -10
- package/dist/tests/symbol-boost.test.js.map +1 -1
- package/dist/tests/symbols-extract.test.d.ts +2 -0
- package/dist/tests/symbols-extract.test.d.ts.map +1 -0
- package/dist/tests/symbols-extract.test.js +536 -0
- package/dist/tests/symbols-extract.test.js.map +1 -0
- package/dist/tests/symbols-graph.test.d.ts +2 -0
- package/dist/tests/symbols-graph.test.d.ts.map +1 -0
- package/dist/tests/symbols-graph.test.js +656 -0
- package/dist/tests/symbols-graph.test.js.map +1 -0
- package/dist/tests/synthesizer.test.d.ts +2 -0
- package/dist/tests/synthesizer.test.d.ts.map +1 -0
- package/dist/tests/synthesizer.test.js +381 -0
- package/dist/tests/synthesizer.test.js.map +1 -0
- package/dist/types/context-pack.d.ts +3 -3
- package/dist/utils/logger.d.ts +5 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +149 -4
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/mutex.d.ts +7 -2
- package/dist/utils/mutex.d.ts.map +1 -1
- package/dist/utils/mutex.js +31 -7
- package/dist/utils/mutex.js.map +1 -1
- package/dist/utils/path-helpers.d.ts.map +1 -1
- package/dist/utils/path-helpers.js +5 -2
- package/dist/utils/path-helpers.js.map +1 -1
- package/dist/utils/simple-lru.d.ts +6 -0
- package/dist/utils/simple-lru.d.ts.map +1 -1
- package/dist/utils/simple-lru.js +26 -0
- package/dist/utils/simple-lru.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,717 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
import { getConfigEnvOverrides, applyConfigToEnv, getEffectiveConfig, } from '../../config/apply-env.js';
|
|
7
|
+
/**
|
|
8
|
+
* Helper to create a temporary directory for tests
|
|
9
|
+
*/
|
|
10
|
+
function createTempDir() {
|
|
11
|
+
return fs.mkdtempSync(path.join(os.tmpdir(), 'codevault-apply-env-test-'));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Helper to clean up temporary directory
|
|
15
|
+
*/
|
|
16
|
+
function cleanupTempDir(dir) {
|
|
17
|
+
if (fs.existsSync(dir)) {
|
|
18
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Helper to save original env and restore later
|
|
23
|
+
*/
|
|
24
|
+
function saveEnv() {
|
|
25
|
+
const envVars = [
|
|
26
|
+
'CODEVAULT_EMBEDDING_API_KEY',
|
|
27
|
+
'OPENAI_API_KEY',
|
|
28
|
+
'CODEVAULT_EMBEDDING_BASE_URL',
|
|
29
|
+
'OPENAI_BASE_URL',
|
|
30
|
+
'CODEVAULT_EMBEDDING_MODEL',
|
|
31
|
+
'CODEVAULT_OPENAI_EMBEDDING_MODEL',
|
|
32
|
+
'OPENAI_MODEL',
|
|
33
|
+
'CODEVAULT_EMBEDDING_DIMENSIONS',
|
|
34
|
+
'CODEVAULT_DIMENSIONS',
|
|
35
|
+
'CODEVAULT_EMBEDDING_MAX_TOKENS',
|
|
36
|
+
'CODEVAULT_MAX_TOKENS',
|
|
37
|
+
'CODEVAULT_EMBEDDING_RATE_LIMIT_RPM',
|
|
38
|
+
'CODEVAULT_RATE_LIMIT_RPM',
|
|
39
|
+
'CODEVAULT_RATE_LIMIT',
|
|
40
|
+
'CODEVAULT_EMBEDDING_RATE_LIMIT_TPM',
|
|
41
|
+
'CODEVAULT_RATE_LIMIT_TPM',
|
|
42
|
+
'CODEVAULT_ENCRYPTION_KEY',
|
|
43
|
+
'CODEVAULT_RERANK_API_URL',
|
|
44
|
+
'CODEVAULT_RERANK_API_KEY',
|
|
45
|
+
'CODEVAULT_RERANK_MODEL',
|
|
46
|
+
'CODEVAULT_CHAT_API_KEY',
|
|
47
|
+
'CODEVAULT_CHAT_BASE_URL',
|
|
48
|
+
'CODEVAULT_CHAT_MODEL',
|
|
49
|
+
'CODEVAULT_OPENAI_CHAT_MODEL',
|
|
50
|
+
'CODEVAULT_CHAT_MAX_TOKENS',
|
|
51
|
+
'CODEVAULT_CHAT_TEMPERATURE',
|
|
52
|
+
];
|
|
53
|
+
const saved = {};
|
|
54
|
+
for (const key of envVars) {
|
|
55
|
+
saved[key] = process.env[key];
|
|
56
|
+
}
|
|
57
|
+
return saved;
|
|
58
|
+
}
|
|
59
|
+
function restoreEnv(saved) {
|
|
60
|
+
for (const [key, value] of Object.entries(saved)) {
|
|
61
|
+
if (value === undefined) {
|
|
62
|
+
delete process.env[key];
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
process.env[key] = value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function clearEnv(keys) {
|
|
70
|
+
for (const key of keys) {
|
|
71
|
+
delete process.env[key];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// =============================================================================
|
|
75
|
+
// getConfigEnvOverrides tests
|
|
76
|
+
// =============================================================================
|
|
77
|
+
test('getConfigEnvOverrides returns object type', () => {
|
|
78
|
+
const tempDir = createTempDir();
|
|
79
|
+
const saved = saveEnv();
|
|
80
|
+
clearEnv(Object.keys(saved));
|
|
81
|
+
try {
|
|
82
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
83
|
+
// Should always return an object
|
|
84
|
+
assert.ok(typeof overrides === 'object');
|
|
85
|
+
// When no project config exists in tempDir and env is cleared,
|
|
86
|
+
// the result depends on whether global config exists
|
|
87
|
+
// We just verify the function returns without error
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
restoreEnv(saved);
|
|
91
|
+
cleanupTempDir(tempDir);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
test('getConfigEnvOverrides generates embedding API key overrides', () => {
|
|
95
|
+
const tempDir = createTempDir();
|
|
96
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
97
|
+
const saved = saveEnv();
|
|
98
|
+
clearEnv(Object.keys(saved));
|
|
99
|
+
try {
|
|
100
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
101
|
+
const testConfig = {
|
|
102
|
+
providers: {
|
|
103
|
+
openai: {
|
|
104
|
+
apiKey: 'test-api-key'
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
109
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
110
|
+
assert.equal(overrides.CODEVAULT_EMBEDDING_API_KEY, 'test-api-key');
|
|
111
|
+
assert.equal(overrides.OPENAI_API_KEY, 'test-api-key');
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
restoreEnv(saved);
|
|
115
|
+
cleanupTempDir(tempDir);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
test('getConfigEnvOverrides generates embedding base URL overrides', () => {
|
|
119
|
+
const tempDir = createTempDir();
|
|
120
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
121
|
+
const saved = saveEnv();
|
|
122
|
+
clearEnv(Object.keys(saved));
|
|
123
|
+
try {
|
|
124
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
125
|
+
const testConfig = {
|
|
126
|
+
providers: {
|
|
127
|
+
openai: {
|
|
128
|
+
baseUrl: 'https://api.example.com'
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
133
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
134
|
+
assert.equal(overrides.CODEVAULT_EMBEDDING_BASE_URL, 'https://api.example.com');
|
|
135
|
+
assert.equal(overrides.OPENAI_BASE_URL, 'https://api.example.com');
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
restoreEnv(saved);
|
|
139
|
+
cleanupTempDir(tempDir);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
test('getConfigEnvOverrides generates embedding model overrides', () => {
|
|
143
|
+
const tempDir = createTempDir();
|
|
144
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
145
|
+
const saved = saveEnv();
|
|
146
|
+
clearEnv(Object.keys(saved));
|
|
147
|
+
try {
|
|
148
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
149
|
+
const testConfig = {
|
|
150
|
+
providers: {
|
|
151
|
+
openai: {
|
|
152
|
+
model: 'text-embedding-3-large'
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
157
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
158
|
+
assert.equal(overrides.CODEVAULT_EMBEDDING_MODEL, 'text-embedding-3-large');
|
|
159
|
+
assert.equal(overrides.CODEVAULT_OPENAI_EMBEDDING_MODEL, 'text-embedding-3-large');
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
restoreEnv(saved);
|
|
163
|
+
cleanupTempDir(tempDir);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
test('getConfigEnvOverrides generates embedding dimensions overrides', () => {
|
|
167
|
+
const tempDir = createTempDir();
|
|
168
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
169
|
+
const saved = saveEnv();
|
|
170
|
+
clearEnv(Object.keys(saved));
|
|
171
|
+
try {
|
|
172
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
173
|
+
const testConfig = {
|
|
174
|
+
providers: {
|
|
175
|
+
openai: {
|
|
176
|
+
dimensions: 1536
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
181
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
182
|
+
assert.equal(overrides.CODEVAULT_EMBEDDING_DIMENSIONS, '1536');
|
|
183
|
+
assert.equal(overrides.CODEVAULT_DIMENSIONS, '1536');
|
|
184
|
+
}
|
|
185
|
+
finally {
|
|
186
|
+
restoreEnv(saved);
|
|
187
|
+
cleanupTempDir(tempDir);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
test('getConfigEnvOverrides generates maxTokens overrides', () => {
|
|
191
|
+
const tempDir = createTempDir();
|
|
192
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
193
|
+
const saved = saveEnv();
|
|
194
|
+
clearEnv(Object.keys(saved));
|
|
195
|
+
try {
|
|
196
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
197
|
+
const testConfig = {
|
|
198
|
+
maxTokens: 8192
|
|
199
|
+
};
|
|
200
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
201
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
202
|
+
assert.equal(overrides.CODEVAULT_EMBEDDING_MAX_TOKENS, '8192');
|
|
203
|
+
assert.equal(overrides.CODEVAULT_MAX_TOKENS, '8192');
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
restoreEnv(saved);
|
|
207
|
+
cleanupTempDir(tempDir);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
test('getConfigEnvOverrides generates rate limit overrides', () => {
|
|
211
|
+
const tempDir = createTempDir();
|
|
212
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
213
|
+
const saved = saveEnv();
|
|
214
|
+
clearEnv(Object.keys(saved));
|
|
215
|
+
try {
|
|
216
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
217
|
+
const testConfig = {
|
|
218
|
+
rateLimit: {
|
|
219
|
+
rpm: 100,
|
|
220
|
+
tpm: 50000
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
224
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
225
|
+
assert.equal(overrides.CODEVAULT_EMBEDDING_RATE_LIMIT_RPM, '100');
|
|
226
|
+
assert.equal(overrides.CODEVAULT_RATE_LIMIT_RPM, '100');
|
|
227
|
+
assert.equal(overrides.CODEVAULT_EMBEDDING_RATE_LIMIT_TPM, '50000');
|
|
228
|
+
assert.equal(overrides.CODEVAULT_RATE_LIMIT_TPM, '50000');
|
|
229
|
+
}
|
|
230
|
+
finally {
|
|
231
|
+
restoreEnv(saved);
|
|
232
|
+
cleanupTempDir(tempDir);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
test('getConfigEnvOverrides generates encryption key override', () => {
|
|
236
|
+
const tempDir = createTempDir();
|
|
237
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
238
|
+
const saved = saveEnv();
|
|
239
|
+
clearEnv(Object.keys(saved));
|
|
240
|
+
try {
|
|
241
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
242
|
+
const testConfig = {
|
|
243
|
+
encryption: {
|
|
244
|
+
enabled: true,
|
|
245
|
+
key: 'my-encryption-key'
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
249
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
250
|
+
assert.equal(overrides.CODEVAULT_ENCRYPTION_KEY, 'my-encryption-key');
|
|
251
|
+
}
|
|
252
|
+
finally {
|
|
253
|
+
restoreEnv(saved);
|
|
254
|
+
cleanupTempDir(tempDir);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
test('getConfigEnvOverrides generates reranker overrides', () => {
|
|
258
|
+
const tempDir = createTempDir();
|
|
259
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
260
|
+
const saved = saveEnv();
|
|
261
|
+
clearEnv(Object.keys(saved));
|
|
262
|
+
try {
|
|
263
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
264
|
+
const testConfig = {
|
|
265
|
+
reranker: {
|
|
266
|
+
apiUrl: 'https://reranker.example.com',
|
|
267
|
+
apiKey: 'reranker-key',
|
|
268
|
+
model: 'rerank-v1'
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
272
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
273
|
+
assert.equal(overrides.CODEVAULT_RERANK_API_URL, 'https://reranker.example.com');
|
|
274
|
+
assert.equal(overrides.CODEVAULT_RERANK_API_KEY, 'reranker-key');
|
|
275
|
+
assert.equal(overrides.CODEVAULT_RERANK_MODEL, 'rerank-v1');
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
restoreEnv(saved);
|
|
279
|
+
cleanupTempDir(tempDir);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
test('getConfigEnvOverrides generates chat LLM overrides', () => {
|
|
283
|
+
const tempDir = createTempDir();
|
|
284
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
285
|
+
const saved = saveEnv();
|
|
286
|
+
clearEnv(Object.keys(saved));
|
|
287
|
+
try {
|
|
288
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
289
|
+
const testConfig = {
|
|
290
|
+
chatLLM: {
|
|
291
|
+
openai: {
|
|
292
|
+
apiKey: 'chat-api-key',
|
|
293
|
+
baseUrl: 'https://chat.example.com',
|
|
294
|
+
model: 'gpt-4',
|
|
295
|
+
maxTokens: 4096,
|
|
296
|
+
temperature: 0.7
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
301
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
302
|
+
assert.equal(overrides.CODEVAULT_CHAT_API_KEY, 'chat-api-key');
|
|
303
|
+
assert.equal(overrides.CODEVAULT_CHAT_BASE_URL, 'https://chat.example.com');
|
|
304
|
+
assert.equal(overrides.CODEVAULT_CHAT_MODEL, 'gpt-4');
|
|
305
|
+
assert.equal(overrides.CODEVAULT_CHAT_MAX_TOKENS, '4096');
|
|
306
|
+
assert.equal(overrides.CODEVAULT_CHAT_TEMPERATURE, '0.7');
|
|
307
|
+
}
|
|
308
|
+
finally {
|
|
309
|
+
restoreEnv(saved);
|
|
310
|
+
cleanupTempDir(tempDir);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
test('getConfigEnvOverrides handles temperature of 0', () => {
|
|
314
|
+
const tempDir = createTempDir();
|
|
315
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
316
|
+
const saved = saveEnv();
|
|
317
|
+
clearEnv(Object.keys(saved));
|
|
318
|
+
try {
|
|
319
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
320
|
+
const testConfig = {
|
|
321
|
+
chatLLM: {
|
|
322
|
+
openai: {
|
|
323
|
+
temperature: 0
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
328
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
329
|
+
// Temperature of 0 should still be included
|
|
330
|
+
assert.equal(overrides.CODEVAULT_CHAT_TEMPERATURE, '0');
|
|
331
|
+
}
|
|
332
|
+
finally {
|
|
333
|
+
restoreEnv(saved);
|
|
334
|
+
cleanupTempDir(tempDir);
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
test('getConfigEnvOverrides generates all overrides for complete config', () => {
|
|
338
|
+
const tempDir = createTempDir();
|
|
339
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
340
|
+
const saved = saveEnv();
|
|
341
|
+
clearEnv(Object.keys(saved));
|
|
342
|
+
try {
|
|
343
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
344
|
+
const testConfig = {
|
|
345
|
+
maxTokens: 8192,
|
|
346
|
+
providers: {
|
|
347
|
+
openai: {
|
|
348
|
+
apiKey: 'embed-key',
|
|
349
|
+
baseUrl: 'https://embed.example.com',
|
|
350
|
+
model: 'text-embedding-3-small',
|
|
351
|
+
dimensions: 1536
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
rateLimit: {
|
|
355
|
+
rpm: 100,
|
|
356
|
+
tpm: 50000
|
|
357
|
+
},
|
|
358
|
+
encryption: {
|
|
359
|
+
enabled: true,
|
|
360
|
+
key: 'encryption-key'
|
|
361
|
+
},
|
|
362
|
+
reranker: {
|
|
363
|
+
apiUrl: 'https://reranker.example.com',
|
|
364
|
+
apiKey: 'reranker-key',
|
|
365
|
+
model: 'rerank-v1'
|
|
366
|
+
},
|
|
367
|
+
chatLLM: {
|
|
368
|
+
openai: {
|
|
369
|
+
apiKey: 'chat-key',
|
|
370
|
+
baseUrl: 'https://chat.example.com',
|
|
371
|
+
model: 'gpt-4',
|
|
372
|
+
maxTokens: 4096,
|
|
373
|
+
temperature: 0.5
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
378
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
379
|
+
// Verify all expected keys are present
|
|
380
|
+
const expectedKeys = [
|
|
381
|
+
'CODEVAULT_EMBEDDING_API_KEY',
|
|
382
|
+
'OPENAI_API_KEY',
|
|
383
|
+
'CODEVAULT_EMBEDDING_BASE_URL',
|
|
384
|
+
'OPENAI_BASE_URL',
|
|
385
|
+
'CODEVAULT_EMBEDDING_MODEL',
|
|
386
|
+
'CODEVAULT_OPENAI_EMBEDDING_MODEL',
|
|
387
|
+
'CODEVAULT_EMBEDDING_DIMENSIONS',
|
|
388
|
+
'CODEVAULT_DIMENSIONS',
|
|
389
|
+
'CODEVAULT_EMBEDDING_MAX_TOKENS',
|
|
390
|
+
'CODEVAULT_MAX_TOKENS',
|
|
391
|
+
'CODEVAULT_EMBEDDING_RATE_LIMIT_RPM',
|
|
392
|
+
'CODEVAULT_RATE_LIMIT_RPM',
|
|
393
|
+
'CODEVAULT_EMBEDDING_RATE_LIMIT_TPM',
|
|
394
|
+
'CODEVAULT_RATE_LIMIT_TPM',
|
|
395
|
+
'CODEVAULT_ENCRYPTION_KEY',
|
|
396
|
+
'CODEVAULT_RERANK_API_URL',
|
|
397
|
+
'CODEVAULT_RERANK_API_KEY',
|
|
398
|
+
'CODEVAULT_RERANK_MODEL',
|
|
399
|
+
'CODEVAULT_CHAT_API_KEY',
|
|
400
|
+
'CODEVAULT_CHAT_BASE_URL',
|
|
401
|
+
'CODEVAULT_CHAT_MODEL',
|
|
402
|
+
'CODEVAULT_CHAT_MAX_TOKENS',
|
|
403
|
+
'CODEVAULT_CHAT_TEMPERATURE'
|
|
404
|
+
];
|
|
405
|
+
for (const key of expectedKeys) {
|
|
406
|
+
assert.ok(key in overrides, `should have ${key} in overrides`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
finally {
|
|
410
|
+
restoreEnv(saved);
|
|
411
|
+
cleanupTempDir(tempDir);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
// =============================================================================
|
|
415
|
+
// applyConfigToEnv tests
|
|
416
|
+
// =============================================================================
|
|
417
|
+
test('applyConfigToEnv sets environment variables from config', () => {
|
|
418
|
+
const tempDir = createTempDir();
|
|
419
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
420
|
+
const saved = saveEnv();
|
|
421
|
+
clearEnv(Object.keys(saved));
|
|
422
|
+
try {
|
|
423
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
424
|
+
const testConfig = {
|
|
425
|
+
providers: {
|
|
426
|
+
openai: {
|
|
427
|
+
apiKey: 'applied-key',
|
|
428
|
+
model: 'applied-model'
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
433
|
+
applyConfigToEnv(tempDir);
|
|
434
|
+
assert.equal(process.env.CODEVAULT_EMBEDDING_API_KEY, 'applied-key');
|
|
435
|
+
assert.equal(process.env.OPENAI_API_KEY, 'applied-key');
|
|
436
|
+
assert.equal(process.env.CODEVAULT_EMBEDDING_MODEL, 'applied-model');
|
|
437
|
+
assert.equal(process.env.CODEVAULT_OPENAI_EMBEDDING_MODEL, 'applied-model');
|
|
438
|
+
}
|
|
439
|
+
finally {
|
|
440
|
+
restoreEnv(saved);
|
|
441
|
+
cleanupTempDir(tempDir);
|
|
442
|
+
}
|
|
443
|
+
});
|
|
444
|
+
test('applyConfigToEnv does not override existing environment variables', () => {
|
|
445
|
+
const tempDir = createTempDir();
|
|
446
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
447
|
+
const saved = saveEnv();
|
|
448
|
+
clearEnv(Object.keys(saved));
|
|
449
|
+
try {
|
|
450
|
+
// Set existing env var
|
|
451
|
+
process.env.CODEVAULT_EMBEDDING_API_KEY = 'existing-key';
|
|
452
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
453
|
+
const testConfig = {
|
|
454
|
+
providers: {
|
|
455
|
+
openai: {
|
|
456
|
+
apiKey: 'config-key',
|
|
457
|
+
model: 'config-model'
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
462
|
+
applyConfigToEnv(tempDir);
|
|
463
|
+
// Existing key should not be overwritten
|
|
464
|
+
assert.equal(process.env.CODEVAULT_EMBEDDING_API_KEY, 'existing-key');
|
|
465
|
+
// But other keys should be set
|
|
466
|
+
assert.equal(process.env.CODEVAULT_EMBEDDING_MODEL, 'config-model');
|
|
467
|
+
assert.equal(process.env.CODEVAULT_OPENAI_EMBEDDING_MODEL, 'config-model');
|
|
468
|
+
}
|
|
469
|
+
finally {
|
|
470
|
+
restoreEnv(saved);
|
|
471
|
+
cleanupTempDir(tempDir);
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
test('applyConfigToEnv handles empty project config gracefully', () => {
|
|
475
|
+
const tempDir = createTempDir();
|
|
476
|
+
const saved = saveEnv();
|
|
477
|
+
clearEnv(Object.keys(saved));
|
|
478
|
+
try {
|
|
479
|
+
// Should not throw for no project config in temp dir
|
|
480
|
+
applyConfigToEnv(tempDir);
|
|
481
|
+
// Function should complete without error
|
|
482
|
+
// Note: global config may still set some values
|
|
483
|
+
assert.ok(true, 'applyConfigToEnv should complete without error');
|
|
484
|
+
}
|
|
485
|
+
finally {
|
|
486
|
+
restoreEnv(saved);
|
|
487
|
+
cleanupTempDir(tempDir);
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
test('applyConfigToEnv applies all config sections', () => {
|
|
491
|
+
const tempDir = createTempDir();
|
|
492
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
493
|
+
const saved = saveEnv();
|
|
494
|
+
clearEnv(Object.keys(saved));
|
|
495
|
+
try {
|
|
496
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
497
|
+
const testConfig = {
|
|
498
|
+
maxTokens: 4096,
|
|
499
|
+
providers: {
|
|
500
|
+
openai: {
|
|
501
|
+
apiKey: 'embed-key'
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
rateLimit: {
|
|
505
|
+
rpm: 100
|
|
506
|
+
},
|
|
507
|
+
encryption: {
|
|
508
|
+
key: 'enc-key'
|
|
509
|
+
},
|
|
510
|
+
reranker: {
|
|
511
|
+
apiKey: 'rerank-key'
|
|
512
|
+
},
|
|
513
|
+
chatLLM: {
|
|
514
|
+
openai: {
|
|
515
|
+
apiKey: 'chat-key'
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
520
|
+
applyConfigToEnv(tempDir);
|
|
521
|
+
assert.equal(process.env.CODEVAULT_EMBEDDING_API_KEY, 'embed-key');
|
|
522
|
+
assert.equal(process.env.CODEVAULT_EMBEDDING_MAX_TOKENS, '4096');
|
|
523
|
+
assert.equal(process.env.CODEVAULT_EMBEDDING_RATE_LIMIT_RPM, '100');
|
|
524
|
+
assert.equal(process.env.CODEVAULT_ENCRYPTION_KEY, 'enc-key');
|
|
525
|
+
assert.equal(process.env.CODEVAULT_RERANK_API_KEY, 'rerank-key');
|
|
526
|
+
assert.equal(process.env.CODEVAULT_CHAT_API_KEY, 'chat-key');
|
|
527
|
+
}
|
|
528
|
+
finally {
|
|
529
|
+
restoreEnv(saved);
|
|
530
|
+
cleanupTempDir(tempDir);
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
test('applyConfigToEnv uses default basePath', () => {
|
|
534
|
+
const saved = saveEnv();
|
|
535
|
+
clearEnv(Object.keys(saved));
|
|
536
|
+
try {
|
|
537
|
+
// Should not throw when called without basePath
|
|
538
|
+
applyConfigToEnv();
|
|
539
|
+
}
|
|
540
|
+
finally {
|
|
541
|
+
restoreEnv(saved);
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
// =============================================================================
|
|
545
|
+
// getEffectiveConfig tests
|
|
546
|
+
// =============================================================================
|
|
547
|
+
test('getEffectiveConfig returns merged config', () => {
|
|
548
|
+
const tempDir = createTempDir();
|
|
549
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
550
|
+
const saved = saveEnv();
|
|
551
|
+
clearEnv(Object.keys(saved));
|
|
552
|
+
try {
|
|
553
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
554
|
+
const testConfig = {
|
|
555
|
+
maxTokens: 4096,
|
|
556
|
+
providers: {
|
|
557
|
+
openai: {
|
|
558
|
+
model: 'project-model'
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
563
|
+
// Set env override
|
|
564
|
+
process.env.CODEVAULT_EMBEDDING_API_KEY = 'env-key';
|
|
565
|
+
const effective = getEffectiveConfig(tempDir);
|
|
566
|
+
// Should have both project and env values
|
|
567
|
+
assert.equal(effective.maxTokens, 4096);
|
|
568
|
+
assert.equal(effective.providers?.openai?.model, 'project-model');
|
|
569
|
+
assert.equal(effective.providers?.openai?.apiKey, 'env-key');
|
|
570
|
+
}
|
|
571
|
+
finally {
|
|
572
|
+
restoreEnv(saved);
|
|
573
|
+
cleanupTempDir(tempDir);
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
test('getEffectiveConfig returns object for isolated temp dir', () => {
|
|
577
|
+
const tempDir = createTempDir();
|
|
578
|
+
const saved = saveEnv();
|
|
579
|
+
clearEnv(Object.keys(saved));
|
|
580
|
+
try {
|
|
581
|
+
const effective = getEffectiveConfig(tempDir);
|
|
582
|
+
// Should always return an object
|
|
583
|
+
assert.ok(typeof effective === 'object');
|
|
584
|
+
// Note: global config may still populate some fields
|
|
585
|
+
// We just verify the function returns without error
|
|
586
|
+
}
|
|
587
|
+
finally {
|
|
588
|
+
restoreEnv(saved);
|
|
589
|
+
cleanupTempDir(tempDir);
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
test('getEffectiveConfig uses default basePath', () => {
|
|
593
|
+
const saved = saveEnv();
|
|
594
|
+
clearEnv(Object.keys(saved));
|
|
595
|
+
try {
|
|
596
|
+
// Should not throw when called without basePath
|
|
597
|
+
const effective = getEffectiveConfig();
|
|
598
|
+
assert.ok(typeof effective === 'object');
|
|
599
|
+
}
|
|
600
|
+
finally {
|
|
601
|
+
restoreEnv(saved);
|
|
602
|
+
}
|
|
603
|
+
});
|
|
604
|
+
test('getEffectiveConfig reflects env priority', () => {
|
|
605
|
+
const tempDir = createTempDir();
|
|
606
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
607
|
+
const saved = saveEnv();
|
|
608
|
+
clearEnv(Object.keys(saved));
|
|
609
|
+
try {
|
|
610
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
611
|
+
const testConfig = {
|
|
612
|
+
maxTokens: 2000,
|
|
613
|
+
providers: {
|
|
614
|
+
openai: {
|
|
615
|
+
apiKey: 'project-key',
|
|
616
|
+
model: 'project-model'
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
621
|
+
// Set env to override
|
|
622
|
+
process.env.CODEVAULT_EMBEDDING_MAX_TOKENS = '8000';
|
|
623
|
+
process.env.CODEVAULT_EMBEDDING_API_KEY = 'env-key';
|
|
624
|
+
const effective = getEffectiveConfig(tempDir);
|
|
625
|
+
// Env should override
|
|
626
|
+
assert.equal(effective.maxTokens, 8000);
|
|
627
|
+
assert.equal(effective.providers?.openai?.apiKey, 'env-key');
|
|
628
|
+
// Non-overridden values should remain
|
|
629
|
+
assert.equal(effective.providers?.openai?.model, 'project-model');
|
|
630
|
+
}
|
|
631
|
+
finally {
|
|
632
|
+
restoreEnv(saved);
|
|
633
|
+
cleanupTempDir(tempDir);
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
// =============================================================================
|
|
637
|
+
// Edge cases
|
|
638
|
+
// =============================================================================
|
|
639
|
+
test('getConfigEnvOverrides returns overrides based on project config structure', () => {
|
|
640
|
+
const tempDir = createTempDir();
|
|
641
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
642
|
+
const saved = saveEnv();
|
|
643
|
+
clearEnv(Object.keys(saved));
|
|
644
|
+
try {
|
|
645
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
646
|
+
// Config with empty nested objects - project config with empty values
|
|
647
|
+
const testConfig = {
|
|
648
|
+
providers: {
|
|
649
|
+
openai: {}
|
|
650
|
+
},
|
|
651
|
+
rateLimit: {},
|
|
652
|
+
encryption: {},
|
|
653
|
+
reranker: {},
|
|
654
|
+
chatLLM: {
|
|
655
|
+
openai: {}
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
659
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
660
|
+
// The function returns an object - global config may still contribute values
|
|
661
|
+
// We verify the function runs without error
|
|
662
|
+
assert.ok(typeof overrides === 'object');
|
|
663
|
+
}
|
|
664
|
+
finally {
|
|
665
|
+
restoreEnv(saved);
|
|
666
|
+
cleanupTempDir(tempDir);
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
test('applyConfigToEnv sets project rate limits', () => {
|
|
670
|
+
const tempDir = createTempDir();
|
|
671
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
672
|
+
const saved = saveEnv();
|
|
673
|
+
clearEnv(Object.keys(saved));
|
|
674
|
+
try {
|
|
675
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
676
|
+
// Only RPM, no TPM in project config
|
|
677
|
+
const testConfig = {
|
|
678
|
+
rateLimit: {
|
|
679
|
+
rpm: 50
|
|
680
|
+
// tpm not set
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
684
|
+
applyConfigToEnv(tempDir);
|
|
685
|
+
// The project config RPM should be set (or merged with global)
|
|
686
|
+
// We verify the function runs and RPM is set
|
|
687
|
+
const rpm = process.env.CODEVAULT_EMBEDDING_RATE_LIMIT_RPM;
|
|
688
|
+
assert.ok(rpm !== undefined, 'RPM should be set');
|
|
689
|
+
}
|
|
690
|
+
finally {
|
|
691
|
+
restoreEnv(saved);
|
|
692
|
+
cleanupTempDir(tempDir);
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
test('getConfigEnvOverrides does not include encryption key without value', () => {
|
|
696
|
+
const tempDir = createTempDir();
|
|
697
|
+
const configDir = path.join(tempDir, '.codevault');
|
|
698
|
+
const saved = saveEnv();
|
|
699
|
+
clearEnv(Object.keys(saved));
|
|
700
|
+
try {
|
|
701
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
702
|
+
const testConfig = {
|
|
703
|
+
encryption: {
|
|
704
|
+
enabled: true
|
|
705
|
+
// key not set
|
|
706
|
+
}
|
|
707
|
+
};
|
|
708
|
+
fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(testConfig));
|
|
709
|
+
const overrides = getConfigEnvOverrides(tempDir);
|
|
710
|
+
assert.ok(!('CODEVAULT_ENCRYPTION_KEY' in overrides));
|
|
711
|
+
}
|
|
712
|
+
finally {
|
|
713
|
+
restoreEnv(saved);
|
|
714
|
+
cleanupTempDir(tempDir);
|
|
715
|
+
}
|
|
716
|
+
});
|
|
717
|
+
//# sourceMappingURL=apply-env.test.js.map
|