codesearch-mcp 0.0.18-alpha → 0.2.0-alpha
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/CHANGELOG.md +47 -1
- package/README.md +194 -23
- package/dist/app.js +38 -2
- package/dist/src/commands/IndexCommand.js +55 -1
- package/dist/src/commands/McpCommand.js +6 -2
- package/dist/src/config-error.d.ts +7 -0
- package/dist/src/config-error.js +14 -0
- package/dist/src/config-store.d.ts +73 -17
- package/dist/src/config-store.js +142 -27
- package/dist/src/config.d.ts +36 -11
- package/dist/src/config.js +89 -27
- package/dist/src/constants.d.ts +42 -2
- package/dist/src/constants.js +61 -7
- package/dist/src/container.js +5 -3
- package/dist/src/db/index.d.ts +1 -1
- package/dist/src/db/index.js +2 -1
- package/dist/src/db/schema.d.ts +111 -0
- package/dist/src/db/schema.js +15 -1
- package/dist/src/help.js +6 -5
- package/dist/src/interfaces/IAstParser.d.ts +14 -0
- package/dist/src/interfaces/IChunker.d.ts +24 -0
- package/dist/src/interfaces/IChunker.js +2 -0
- package/dist/src/interfaces/IDatabase.d.ts +31 -0
- package/dist/src/interfaces/IEmbedder.d.ts +14 -2
- package/dist/src/interfaces/ILogger.d.ts +7 -0
- package/dist/src/interfaces/ISearcher.d.ts +1 -0
- package/dist/src/interfaces/index.d.ts +2 -1
- package/dist/src/owner-path.d.ts +10 -0
- package/dist/src/owner-path.js +27 -0
- package/dist/src/services/AstChunker.d.ts +42 -0
- package/dist/src/services/AstChunker.js +158 -0
- package/dist/src/services/AstParserService.d.ts +6 -0
- package/dist/src/services/AstParserService.js +31 -2
- package/dist/src/services/DatabaseService.d.ts +17 -1
- package/dist/src/services/DatabaseService.js +116 -25
- package/dist/src/services/EmbedderFactory.d.ts +9 -0
- package/dist/src/services/EmbedderFactory.js +26 -0
- package/dist/src/services/IndexerService.d.ts +21 -5
- package/dist/src/services/IndexerService.js +127 -44
- package/dist/src/services/InfinityEmbedder.d.ts +38 -0
- package/dist/src/services/InfinityEmbedder.js +88 -0
- package/dist/src/services/LoggerService.d.ts +3 -1
- package/dist/src/services/LoggerService.js +17 -3
- package/dist/src/services/OpenAICompatibleEmbedder.d.ts +25 -0
- package/dist/src/services/OpenAICompatibleEmbedder.js +75 -0
- package/dist/src/services/SearcherService.d.ts +21 -1
- package/dist/src/services/SearcherService.js +129 -28
- package/dist/src/services/VoyageEmbedder.d.ts +22 -0
- package/dist/src/services/VoyageEmbedder.js +72 -0
- package/dist/src/services/WebServerService.d.ts +57 -14
- package/dist/src/services/WebServerService.js +134 -26
- package/dist/src/services/http-retry.d.ts +19 -0
- package/dist/src/services/http-retry.js +54 -0
- package/dist/src/services/infinity-provisioning.d.ts +115 -0
- package/dist/src/services/infinity-provisioning.js +516 -0
- package/dist/src/services/legacy-ollama-index.d.ts +24 -0
- package/dist/src/services/legacy-ollama-index.js +61 -0
- package/dist/src/services/reranker.d.ts +15 -0
- package/dist/src/services/reranker.js +44 -0
- package/dist/src/setup.d.ts +43 -0
- package/dist/src/setup.js +227 -55
- package/dist/src/tools/SearchCodebaseTool.js +1 -1
- package/dist/src/tools/format-helpers.js +2 -1
- package/dist/src/web/dashboard.js +5 -0
- package/docker/docker-compose.infinity-gpu.yml +19 -0
- package/docker/docker-compose.yml +20 -5
- package/docs/web-dashboard.md +36 -17
- package/package.json +18 -3
- package/dist/src/ast.d.ts +0 -2
- package/dist/src/ast.js +0 -110
- package/dist/src/commands/SetupCommand.d.ts +0 -7
- package/dist/src/commands/SetupCommand.js +0 -14
- package/dist/src/db/data-source.d.ts +0 -2
- package/dist/src/db/data-source.js +0 -13
- package/dist/src/db/entities/code-chunk.entity.d.ts +0 -9
- package/dist/src/db/entities/code-chunk.entity.js +0 -54
- package/dist/src/db/entities/code-dependency.entity.d.ts +0 -9
- package/dist/src/db/entities/code-dependency.entity.js +0 -54
- package/dist/src/db/entities/code-symbol.entity.d.ts +0 -10
- package/dist/src/db/entities/code-symbol.entity.js +0 -59
- package/dist/src/db/init.d.ts +0 -2
- package/dist/src/db/init.js +0 -62
- package/dist/src/env-loader.d.ts +0 -1
- package/dist/src/env-loader.js +0 -41
- package/dist/src/indexer.d.ts +0 -17
- package/dist/src/indexer.js +0 -242
- package/dist/src/mcp.d.ts +0 -1
- package/dist/src/mcp.js +0 -403
- package/dist/src/ollama.d.ts +0 -2
- package/dist/src/ollama.js +0 -6
- package/dist/src/searcher.d.ts +0 -74
- package/dist/src/searcher.js +0 -446
- package/dist/src/services/OllamaEmbedder.d.ts +0 -14
- package/dist/src/services/OllamaEmbedder.js +0 -63
- package/dist/vitest.config.d.ts +0 -2
- package/dist/vitest.config.js +0 -9
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ILogger } from '../interfaces/ILogger';
|
|
2
|
+
export declare class HttpError extends Error {
|
|
3
|
+
status: number;
|
|
4
|
+
constructor(status: number, message: string);
|
|
5
|
+
}
|
|
6
|
+
export interface RetryOpts {
|
|
7
|
+
/** Total attempts including the first (default 4). */
|
|
8
|
+
attempts?: number;
|
|
9
|
+
/** Base backoff in ms; grows exponentially (default 500). Set 0 in tests. */
|
|
10
|
+
baseDelayMs?: number;
|
|
11
|
+
logger?: ILogger;
|
|
12
|
+
label?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Run `fn` with bounded exponential backoff on HTTP 429/5xx and network errors.
|
|
16
|
+
* Re-throws the last error once attempts are exhausted or the error is not
|
|
17
|
+
* transient.
|
|
18
|
+
*/
|
|
19
|
+
export declare function withRetry<T>(fn: () => Promise<T>, opts?: RetryOpts): Promise<T>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.HttpError = void 0;
|
|
4
|
+
exports.withRetry = withRetry;
|
|
5
|
+
class HttpError extends Error {
|
|
6
|
+
status;
|
|
7
|
+
constructor(status, message) {
|
|
8
|
+
super(message);
|
|
9
|
+
this.status = status;
|
|
10
|
+
this.name = 'HttpError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.HttpError = HttpError;
|
|
14
|
+
function sleep(ms) {
|
|
15
|
+
return ms > 0 ? new Promise(r => setTimeout(r, ms)) : Promise.resolve();
|
|
16
|
+
}
|
|
17
|
+
/** True for transient failures worth retrying (rate limit / server error / network / timeout). */
|
|
18
|
+
function isRetryable(err) {
|
|
19
|
+
if (err instanceof HttpError)
|
|
20
|
+
return err.status === 429 || (err.status >= 500 && err.status <= 599);
|
|
21
|
+
// A request timeout (AbortSignal.timeout) rejects with a DOMException named
|
|
22
|
+
// 'TimeoutError' — the most common transient cloud failure, so retry it.
|
|
23
|
+
if (err != null && typeof err === 'object' && err.name === 'TimeoutError')
|
|
24
|
+
return true;
|
|
25
|
+
// Network-level errors (fetch throws) are transient too.
|
|
26
|
+
return err instanceof TypeError;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Run `fn` with bounded exponential backoff on HTTP 429/5xx and network errors.
|
|
30
|
+
* Re-throws the last error once attempts are exhausted or the error is not
|
|
31
|
+
* transient.
|
|
32
|
+
*/
|
|
33
|
+
async function withRetry(fn, opts = {}) {
|
|
34
|
+
const attempts = opts.attempts ?? 4;
|
|
35
|
+
const base = opts.baseDelayMs ?? 500;
|
|
36
|
+
let lastErr;
|
|
37
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
38
|
+
try {
|
|
39
|
+
return await fn();
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
lastErr = err;
|
|
43
|
+
if (attempt >= attempts || !isRetryable(err))
|
|
44
|
+
break;
|
|
45
|
+
const delay = base * Math.pow(2, attempt - 1);
|
|
46
|
+
opts.logger?.warn('http-retry: transient failure, retrying', {
|
|
47
|
+
label: opts.label, attempt, attempts, delayMs: delay,
|
|
48
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
49
|
+
});
|
|
50
|
+
await sleep(delay);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
throw lastErr;
|
|
54
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { Config } from '../config';
|
|
2
|
+
/** Result of a shell command run, mirroring the parts of `spawnSync` we use. */
|
|
3
|
+
export interface CommandResult {
|
|
4
|
+
status: number | null;
|
|
5
|
+
stdout?: string;
|
|
6
|
+
stderr?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Injection seams for the provisioning primitive. All optional, defaulted to the real implementations. */
|
|
9
|
+
export interface ProvisioningDeps {
|
|
10
|
+
fetchImpl?: typeof fetch;
|
|
11
|
+
/** Runs a shell command (docker). Defaults to `spawnSync` with captured output. */
|
|
12
|
+
runCommand?: (cmd: string, args: string[]) => CommandResult;
|
|
13
|
+
/** Sleep between readiness polls (ms), capped at 5000. Defaults to 2000; tests pass 0. */
|
|
14
|
+
pollIntervalMs?: number;
|
|
15
|
+
/** Readiness wait timeout (ms). Defaults to 1,800,000 (30 min); tests override to run fast. */
|
|
16
|
+
readinessTimeoutMs?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Strip trailing slashes and a trailing `/embeddings` or `/v1` to get the server
|
|
20
|
+
* root — Infinity serves `/health`, `/models`, `/rerank`, `/embeddings` from the
|
|
21
|
+
* root, so a baseURL written with an OpenAI-style suffix must be normalized here
|
|
22
|
+
* to keep the probe/models URLs aligned with the embeddings URL.
|
|
23
|
+
*/
|
|
24
|
+
export declare function serverRoot(baseURL: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Probe an Infinity-style `/health` endpoint. Resolves `true` when the server
|
|
27
|
+
* answers with a 2xx, `false` on any error, non-2xx, or timeout.
|
|
28
|
+
*/
|
|
29
|
+
export declare function probeInfinityHealth(baseURL: string, fetchImpl?: typeof fetch, timeoutMs?: number): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* List the model ids an Infinity server currently serves via its OpenAI-style
|
|
32
|
+
* `/models` listing (`{ data: [{ id }] }`). Returns `[]` on any error, non-2xx,
|
|
33
|
+
* or timeout — callers treat an empty/unverifiable listing as "served".
|
|
34
|
+
*/
|
|
35
|
+
export declare function listInfinityModels(baseURL: string, fetchImpl?: typeof fetch, timeoutMs?: number): Promise<string[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Two URLs target the same server when scheme, (loopback-normalised) host, and
|
|
38
|
+
* port (explicit or scheme default) all match; path is ignored. An unparsable
|
|
39
|
+
* URL is never the same server as another.
|
|
40
|
+
*/
|
|
41
|
+
export declare function sameServer(a: string, b: string): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* "Managed" per the managed-vs-external requirement: the compose file exists,
|
|
44
|
+
* declares an `infinity` service, the base URL host is loopback, and its port
|
|
45
|
+
* (explicit or scheme default) equals the service's published host port.
|
|
46
|
+
* Never throws — an unreadable/unparsable file or an unrecognised port form
|
|
47
|
+
* is simply "external".
|
|
48
|
+
*/
|
|
49
|
+
export declare function isManagedInfinity(baseURL: string, composePath: string): boolean;
|
|
50
|
+
/** The literal (non-`${…}`) `INFINITY_MODEL_ID` value in the compose file's `infinity` service, or null. */
|
|
51
|
+
export declare function extractModelIdValue(composeContent: string): string | null;
|
|
52
|
+
/** Write `content` to `targetPath` via a same-directory temp file + rename; removes the temp file on failure. */
|
|
53
|
+
export declare function atomicWriteFile(targetPath: string, content: string, mode: number): void;
|
|
54
|
+
/**
|
|
55
|
+
* Write `modelSet` (embedding model first) as the literal `INFINITY_MODEL_ID`
|
|
56
|
+
* of the compose file's `infinity` service, and remove a `profiles:` entry of
|
|
57
|
+
* that service if present (a file written by an earlier version). At most
|
|
58
|
+
* those two targeted edits — every other byte unchanged. Atomic (temp file +
|
|
59
|
+
* rename), keeps the original file's mode. Throws (no write, original file
|
|
60
|
+
* unchanged) when the file cannot be read, has no `infinity` service, has no
|
|
61
|
+
* `INFINITY_MODEL_ID:` line, or the write itself fails.
|
|
62
|
+
*/
|
|
63
|
+
export declare function writeComposeModelSet(composePath: string, modelSet: string[]): void;
|
|
64
|
+
/** True when an NVIDIA GPU + `nvidia-smi` is available on this host. */
|
|
65
|
+
export declare function hasNvidiaGpu(): boolean;
|
|
66
|
+
/** The `-f` file args a docker compose invocation against `composePath` should use (base, plus GPU override when present + detected). */
|
|
67
|
+
export declare function composeFileArgs(composePath: string): string[];
|
|
68
|
+
export type BackendAction = 'served' | 'missing-managed' | 'missing-external' | 'unreachable-managed' | 'unreachable-external';
|
|
69
|
+
export interface BackendEvaluation {
|
|
70
|
+
action: BackendAction;
|
|
71
|
+
managed: boolean;
|
|
72
|
+
/** Required models absent from the served listing; empty for `served` or an unverifiable listing. */
|
|
73
|
+
missingModels: string[];
|
|
74
|
+
/** The full served listing at evaluation time; empty for an unverifiable listing or when unreachable. */
|
|
75
|
+
servedModels: string[];
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Classify the backend against `requiredModels` without touching Docker:
|
|
79
|
+
* reachable+served (or unverifiable listing) → `served`; reachable+missing →
|
|
80
|
+
* `missing-managed`/`missing-external`; unreachable → `unreachable-managed`/
|
|
81
|
+
* `unreachable-external`. Shared by `ensureBackendReady`, the web-dashboard
|
|
82
|
+
* decision table, and `rag-setup`'s declined-Docker branch.
|
|
83
|
+
*/
|
|
84
|
+
export declare function evaluateBackend(baseURL: string, composePath: string, requiredModels: string[], deps?: ProvisioningDeps): Promise<BackendEvaluation>;
|
|
85
|
+
/** Human-readable manual instructions for a `missing-external`/`unreachable-external` evaluation. */
|
|
86
|
+
export declare function manualInstructionMessage(evaluation: BackendEvaluation, base: string, modelSetToWrite: string[]): string;
|
|
87
|
+
export interface EnsureBackendReadyOpts {
|
|
88
|
+
baseURL: string;
|
|
89
|
+
/** Models that must be served for the call to succeed without a recreate/instructions. */
|
|
90
|
+
requiredModels: string[];
|
|
91
|
+
/** Full model set to write into the compose file and bind at startup when a start/recreate is needed. */
|
|
92
|
+
modelSetToWrite: string[];
|
|
93
|
+
composePath: string;
|
|
94
|
+
deps?: ProvisioningDeps;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Bring the Infinity backend to a state serving `requiredModels`, per the
|
|
98
|
+
* managed-vs-external decision tree:
|
|
99
|
+
* served → return (no Docker)
|
|
100
|
+
* missing-managed → recreate (writes modelSetToWrite) + wait
|
|
101
|
+
* missing-external → throw (manual --model-id instructions)
|
|
102
|
+
* unreachable-managed → (re)create + wait
|
|
103
|
+
* unreachable-external → throw (manual launch instructions)
|
|
104
|
+
*/
|
|
105
|
+
export declare function ensureBackendReady(opts: EnsureBackendReadyOpts): Promise<void>;
|
|
106
|
+
/** `ensureBackendReady` with the full set as both the requirement and the write (rag-setup, web dashboard). */
|
|
107
|
+
export declare function ensureModelSetServed(baseURL: string, composePath: string, modelSet: string[], deps?: ProvisioningDeps): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* The model set a managed Infinity container must serve, computed from a
|
|
110
|
+
* `Config`: the embedding model, followed by the reranker model only when
|
|
111
|
+
* reranking is enabled with a model on the same server as embeddings (the
|
|
112
|
+
* effective `reranker.url`, which `Config` has already resolved from an
|
|
113
|
+
* explicit value or derived from `reranker.baseURL`).
|
|
114
|
+
*/
|
|
115
|
+
export declare function requiredModelSet(cfg: Config): string[];
|