@zokizuan/satori-mcp 3.3.0 → 3.5.0
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 +1 -1
- package/dist/core/call-graph.js +10 -10
- package/dist/core/handlers.d.ts +16 -1
- package/dist/core/handlers.js +62 -9
- package/dist/core/search-types.d.ts +9 -0
- package/dist/tools/call_graph.js +1 -1
- package/dist/tools/read_file.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ Unified semantic search with runtime/docs scope control, grouped/raw output mode
|
|
|
85
85
|
|
|
86
86
|
### `call_graph`
|
|
87
87
|
|
|
88
|
-
Traverse the prebuilt TS/Python call graph sidecar for callers/callees/bidirectional symbol relationships.
|
|
88
|
+
Traverse the prebuilt TS/JS/Python call graph sidecar for callers/callees/bidirectional symbol relationships.
|
|
89
89
|
|
|
90
90
|
| Parameter | Type | Required | Default | Description |
|
|
91
91
|
|---|---|---|---|---|
|
package/dist/core/call-graph.js
CHANGED
|
@@ -3,9 +3,10 @@ import * as os from 'node:os';
|
|
|
3
3
|
import * as path from 'node:path';
|
|
4
4
|
import crypto from 'node:crypto';
|
|
5
5
|
import ignore from 'ignore';
|
|
6
|
-
import { AstCodeSplitter } from '@zokizuan/satori-core';
|
|
7
|
-
const SUPPORTED_SOURCE_EXTENSIONS = new Set(
|
|
8
|
-
const QUERY_SUPPORTED_EXTENSIONS = new Set(
|
|
6
|
+
import { AstCodeSplitter, getLanguageIdFromExtension, getSupportedExtensionsForCapability, getSupportedLanguageIdsForCapability, } from '@zokizuan/satori-core';
|
|
7
|
+
const SUPPORTED_SOURCE_EXTENSIONS = new Set(getSupportedExtensionsForCapability('callGraphBuild'));
|
|
8
|
+
const QUERY_SUPPORTED_EXTENSIONS = new Set(getSupportedExtensionsForCapability('callGraphQuery'));
|
|
9
|
+
const QUERY_SUPPORTED_LANGUAGE_IDS = getSupportedLanguageIdsForCapability('callGraphQuery');
|
|
9
10
|
const DEFAULT_IGNORE_PATTERNS = ['**/node_modules/**', '**/.git/**', '**/dist/**', '**/build/**', '**/coverage/**', '**/.next/**'];
|
|
10
11
|
const CALL_KEYWORDS = new Set([
|
|
11
12
|
'if', 'for', 'while', 'switch', 'catch', 'return', 'new', 'typeof', 'function', 'class', 'def', 'await', 'with', 'from', 'import',
|
|
@@ -478,11 +479,9 @@ export class CallGraphSidecarManager {
|
|
|
478
479
|
}
|
|
479
480
|
getSplitLanguage(relativePath) {
|
|
480
481
|
const ext = path.extname(relativePath).toLowerCase();
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
if (ext === '.ts' || ext === '.tsx' || ext === '.js' || ext === '.jsx' || ext === '.mjs' || ext === '.cjs') {
|
|
485
|
-
return ext === '.js' || ext === '.jsx' || ext === '.mjs' || ext === '.cjs' ? 'javascript' : 'typescript';
|
|
482
|
+
const language = getLanguageIdFromExtension(ext, 'unknown');
|
|
483
|
+
if (language === 'python' || language === 'typescript' || language === 'javascript') {
|
|
484
|
+
return language;
|
|
486
485
|
}
|
|
487
486
|
return 'unknown';
|
|
488
487
|
}
|
|
@@ -495,8 +494,9 @@ export class CallGraphSidecarManager {
|
|
|
495
494
|
supported: false,
|
|
496
495
|
reason: 'unsupported_language',
|
|
497
496
|
hints: {
|
|
498
|
-
supportedExtensions:
|
|
499
|
-
|
|
497
|
+
supportedExtensions: Array.from(QUERY_SUPPORTED_EXTENSIONS).sort((a, b) => a.localeCompare(b)),
|
|
498
|
+
supportedLanguages: QUERY_SUPPORTED_LANGUAGE_IDS,
|
|
499
|
+
message: 'call_graph currently supports TypeScript, JavaScript, and Python symbols.',
|
|
500
500
|
},
|
|
501
501
|
};
|
|
502
502
|
}
|
package/dist/core/handlers.d.ts
CHANGED
|
@@ -16,6 +16,9 @@ export declare class ToolHandlers {
|
|
|
16
16
|
constructor(context: Context, snapshotManager: SnapshotManager, syncManager: SyncManager, runtimeFingerprint: IndexFingerprint, now?: () => number, callGraphManager?: CallGraphSidecarManager);
|
|
17
17
|
private buildReindexInstruction;
|
|
18
18
|
private buildReindexHint;
|
|
19
|
+
private summarizeFingerprint;
|
|
20
|
+
private buildCompatibilityDiagnostics;
|
|
21
|
+
private buildCompatibilityStatusLines;
|
|
19
22
|
private buildRequiresReindexPayload;
|
|
20
23
|
private buildRequiresReindexSearchResponse;
|
|
21
24
|
private buildRequiresReindexCallGraphPayload;
|
|
@@ -199,7 +202,19 @@ export declare class ToolHandlers {
|
|
|
199
202
|
}[];
|
|
200
203
|
isError: boolean;
|
|
201
204
|
}>;
|
|
202
|
-
handleGetIndexingStatus(args: any): Promise<
|
|
205
|
+
handleGetIndexingStatus(args: any): Promise<{
|
|
206
|
+
content: {
|
|
207
|
+
type: string;
|
|
208
|
+
text: string;
|
|
209
|
+
}[];
|
|
210
|
+
isError: boolean;
|
|
211
|
+
} | {
|
|
212
|
+
content: {
|
|
213
|
+
type: string;
|
|
214
|
+
text: string;
|
|
215
|
+
}[];
|
|
216
|
+
isError?: undefined;
|
|
217
|
+
}>;
|
|
203
218
|
/**
|
|
204
219
|
* Handle sync request - manually trigger incremental sync for a codebase
|
|
205
220
|
*/
|
package/dist/core/handlers.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as fs from "fs";
|
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import crypto from "node:crypto";
|
|
4
4
|
import ignore from "ignore";
|
|
5
|
-
import { COLLECTION_LIMIT_MESSAGE } from "@zokizuan/satori-core";
|
|
5
|
+
import { COLLECTION_LIMIT_MESSAGE, getSupportedExtensionsForCapability, isLanguageCapabilitySupportedForExtension, isLanguageCapabilitySupportedForLanguage, } from "@zokizuan/satori-core";
|
|
6
6
|
import { ensureAbsolutePath, truncateContent, trackCodebasePath } from "../utils.js";
|
|
7
7
|
import { SEARCH_MAX_CANDIDATES, SEARCH_PROXIMITY_WINDOW, SEARCH_RRF_K, SCOPE_PATH_MULTIPLIERS, STALENESS_THRESHOLDS_MS } from "./search-constants.js";
|
|
8
8
|
import { CallGraphSidecarManager } from "./call-graph.js";
|
|
@@ -14,6 +14,7 @@ const COLLECTION_LIMIT_PATTERNS = [
|
|
|
14
14
|
];
|
|
15
15
|
const SATORI_COLLECTION_PREFIXES = ['code_chunks_', 'hybrid_code_chunks_'];
|
|
16
16
|
const ZILLIZ_FREE_TIER_COLLECTION_LIMIT = 5;
|
|
17
|
+
const OUTLINE_SUPPORTED_EXTENSIONS = getSupportedExtensionsForCapability('fileOutline');
|
|
17
18
|
function collectErrorFragments(value, output, visited, depth = 0) {
|
|
18
19
|
if (value === null || value === undefined || depth > 4 || output.length >= 8) {
|
|
19
20
|
return;
|
|
@@ -119,6 +120,46 @@ export class ToolHandlers {
|
|
|
119
120
|
}
|
|
120
121
|
};
|
|
121
122
|
}
|
|
123
|
+
summarizeFingerprint(fingerprint) {
|
|
124
|
+
return `${fingerprint.embeddingProvider}/${fingerprint.embeddingModel}/${fingerprint.embeddingDimension}/${fingerprint.vectorStoreProvider}/${fingerprint.schemaVersion}`;
|
|
125
|
+
}
|
|
126
|
+
buildCompatibilityDiagnostics(codebasePath) {
|
|
127
|
+
const info = typeof this.snapshotManager.getCodebaseInfo === 'function'
|
|
128
|
+
? this.snapshotManager.getCodebaseInfo(codebasePath)
|
|
129
|
+
: undefined;
|
|
130
|
+
const statusAtCheck = info?.status
|
|
131
|
+
|| (typeof this.snapshotManager.getCodebaseStatus === 'function'
|
|
132
|
+
? this.snapshotManager.getCodebaseStatus(codebasePath)
|
|
133
|
+
: 'not_found');
|
|
134
|
+
const diagnostics = {
|
|
135
|
+
runtimeFingerprint: this.runtimeFingerprint,
|
|
136
|
+
statusAtCheck
|
|
137
|
+
};
|
|
138
|
+
if (info?.indexFingerprint) {
|
|
139
|
+
diagnostics.indexedFingerprint = info.indexFingerprint;
|
|
140
|
+
}
|
|
141
|
+
if (info?.fingerprintSource) {
|
|
142
|
+
diagnostics.fingerprintSource = info.fingerprintSource;
|
|
143
|
+
}
|
|
144
|
+
if (info?.reindexReason) {
|
|
145
|
+
diagnostics.reindexReason = info.reindexReason;
|
|
146
|
+
}
|
|
147
|
+
return diagnostics;
|
|
148
|
+
}
|
|
149
|
+
buildCompatibilityStatusLines(codebasePath) {
|
|
150
|
+
const diagnostics = this.buildCompatibilityDiagnostics(codebasePath);
|
|
151
|
+
let lines = `\n🧬 Runtime fingerprint: ${this.summarizeFingerprint(diagnostics.runtimeFingerprint)}`;
|
|
152
|
+
lines += diagnostics.indexedFingerprint
|
|
153
|
+
? `\n🧬 Indexed fingerprint: ${this.summarizeFingerprint(diagnostics.indexedFingerprint)}`
|
|
154
|
+
: `\n🧬 Indexed fingerprint: unavailable`;
|
|
155
|
+
if (diagnostics.fingerprintSource) {
|
|
156
|
+
lines += `\n🧬 Fingerprint source: ${diagnostics.fingerprintSource}`;
|
|
157
|
+
}
|
|
158
|
+
if (diagnostics.reindexReason) {
|
|
159
|
+
lines += `\n🧬 Reindex reason: ${diagnostics.reindexReason}`;
|
|
160
|
+
}
|
|
161
|
+
return lines;
|
|
162
|
+
}
|
|
122
163
|
buildRequiresReindexPayload(codebasePath, detail, searchContext) {
|
|
123
164
|
const detailLine = detail ? `${detail}\n\n` : '';
|
|
124
165
|
const base = searchContext ? {
|
|
@@ -140,7 +181,8 @@ export class ToolHandlers {
|
|
|
140
181
|
message: `${detailLine}The index at '${codebasePath}' is incompatible with the current runtime and must be rebuilt. Please run manage_index with {\"action\":\"reindex\",\"path\":\"${codebasePath}\"}.`,
|
|
141
182
|
hints: {
|
|
142
183
|
reindex: this.buildReindexHint(codebasePath)
|
|
143
|
-
}
|
|
184
|
+
},
|
|
185
|
+
compatibility: this.buildCompatibilityDiagnostics(codebasePath)
|
|
144
186
|
};
|
|
145
187
|
}
|
|
146
188
|
buildRequiresReindexSearchResponse(codebasePath, detail, searchContext) {
|
|
@@ -172,7 +214,8 @@ export class ToolHandlers {
|
|
|
172
214
|
message: `${detailLine}The index at '${codebasePath}' is incompatible with the current runtime and must be rebuilt. Please run manage_index with {"action":"reindex","path":"${codebasePath}"}.`,
|
|
173
215
|
hints: {
|
|
174
216
|
reindex: this.buildReindexHint(codebasePath)
|
|
175
|
-
}
|
|
217
|
+
},
|
|
218
|
+
compatibility: this.buildCompatibilityDiagnostics(codebasePath)
|
|
176
219
|
};
|
|
177
220
|
}
|
|
178
221
|
getMatchingBlockedRoot(absolutePath) {
|
|
@@ -431,13 +474,12 @@ export class ToolHandlers {
|
|
|
431
474
|
return `grp_${digest}`;
|
|
432
475
|
}
|
|
433
476
|
isCallGraphLanguageSupported(language, file) {
|
|
434
|
-
|
|
435
|
-
if (normalized === 'typescript' || normalized === 'ts' || normalized === 'python' || normalized === 'py') {
|
|
477
|
+
if (isLanguageCapabilitySupportedForLanguage(language, 'callGraphQuery')) {
|
|
436
478
|
return true;
|
|
437
479
|
}
|
|
438
480
|
if (typeof file === 'string') {
|
|
439
481
|
const ext = path.extname(file).toLowerCase();
|
|
440
|
-
return ext
|
|
482
|
+
return isLanguageCapabilitySupportedForExtension(ext, 'callGraphQuery');
|
|
441
483
|
}
|
|
442
484
|
return false;
|
|
443
485
|
}
|
|
@@ -1763,7 +1805,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1763
1805
|
file: normalizedFile,
|
|
1764
1806
|
outline: null,
|
|
1765
1807
|
hasMore: false,
|
|
1766
|
-
message: `File '${normalizedFile}' is not supported for sidecar outline. Supported extensions: .
|
|
1808
|
+
message: `File '${normalizedFile}' is not supported for sidecar outline. Supported extensions: ${OUTLINE_SUPPORTED_EXTENSIONS.join(', ')}.`
|
|
1767
1809
|
};
|
|
1768
1810
|
return {
|
|
1769
1811
|
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
|
|
@@ -2131,7 +2173,17 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
2131
2173
|
// Check indexing status using new status system
|
|
2132
2174
|
const statusGate = this.enforceFingerprintGate(absolutePath);
|
|
2133
2175
|
if (statusGate.blockedResponse) {
|
|
2134
|
-
|
|
2176
|
+
const statusMessage = this.buildReindexInstruction(absolutePath, statusGate.message);
|
|
2177
|
+
const compatibilityStatus = this.buildCompatibilityStatusLines(absolutePath);
|
|
2178
|
+
const pathInfo = codebasePath !== absolutePath
|
|
2179
|
+
? `\nNote: Input path '${codebasePath}' was resolved to absolute path '${absolutePath}'`
|
|
2180
|
+
: '';
|
|
2181
|
+
return {
|
|
2182
|
+
content: [{
|
|
2183
|
+
type: "text",
|
|
2184
|
+
text: statusMessage + compatibilityStatus + pathInfo
|
|
2185
|
+
}]
|
|
2186
|
+
};
|
|
2135
2187
|
}
|
|
2136
2188
|
const status = this.snapshotManager.getCodebaseStatus(absolutePath);
|
|
2137
2189
|
const info = this.snapshotManager.getCodebaseInfo(absolutePath);
|
|
@@ -2204,10 +2256,11 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
2204
2256
|
const pathInfo = codebasePath !== absolutePath
|
|
2205
2257
|
? `\nNote: Input path '${codebasePath}' was resolved to absolute path '${absolutePath}'`
|
|
2206
2258
|
: '';
|
|
2259
|
+
const compatibilityStatus = this.buildCompatibilityStatusLines(absolutePath);
|
|
2207
2260
|
return {
|
|
2208
2261
|
content: [{
|
|
2209
2262
|
type: "text",
|
|
2210
|
-
text: statusMessage + pathInfo
|
|
2263
|
+
text: statusMessage + compatibilityStatus + pathInfo
|
|
2211
2264
|
}]
|
|
2212
2265
|
};
|
|
2213
2266
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FreshnessDecision } from "./sync.js";
|
|
2
2
|
import { SearchGroupBy, SearchResultMode, SearchScope } from "./search-constants.js";
|
|
3
|
+
import { FingerprintSource, IndexFingerprint } from "../config.js";
|
|
3
4
|
export type StalenessBucket = "fresh" | "aging" | "stale" | "unknown";
|
|
4
5
|
export interface SearchSpan {
|
|
5
6
|
startLine: number;
|
|
@@ -57,6 +58,13 @@ export interface SearchGroupResult {
|
|
|
57
58
|
topChunkScore: number;
|
|
58
59
|
};
|
|
59
60
|
}
|
|
61
|
+
export interface FingerprintCompatibilityDiagnostics {
|
|
62
|
+
runtimeFingerprint: IndexFingerprint;
|
|
63
|
+
indexedFingerprint?: IndexFingerprint;
|
|
64
|
+
fingerprintSource?: FingerprintSource;
|
|
65
|
+
reindexReason?: "legacy_unverified_fingerprint" | "fingerprint_mismatch" | "missing_fingerprint";
|
|
66
|
+
statusAtCheck?: "indexed" | "indexing" | "indexfailed" | "sync_completed" | "requires_reindex" | "not_found";
|
|
67
|
+
}
|
|
60
68
|
interface SearchBaseResponseEnvelope {
|
|
61
69
|
status: "ok" | "requires_reindex" | "not_indexed";
|
|
62
70
|
path: string;
|
|
@@ -70,6 +78,7 @@ interface SearchBaseResponseEnvelope {
|
|
|
70
78
|
warnings?: string[];
|
|
71
79
|
message?: string;
|
|
72
80
|
hints?: Record<string, unknown>;
|
|
81
|
+
compatibility?: FingerprintCompatibilityDiagnostics;
|
|
73
82
|
}
|
|
74
83
|
export interface SearchGroupedResponseEnvelope extends SearchBaseResponseEnvelope {
|
|
75
84
|
resultMode: "grouped";
|
package/dist/tools/call_graph.js
CHANGED
|
@@ -18,7 +18,7 @@ const callGraphInputSchema = z.object({
|
|
|
18
18
|
});
|
|
19
19
|
export const callGraphTool = {
|
|
20
20
|
name: 'call_graph',
|
|
21
|
-
description: () => 'Traverse the prebuilt TS/Python call graph sidecar for callers/callees/bidirectional symbol relationships.',
|
|
21
|
+
description: () => 'Traverse the prebuilt TS/JS/Python call graph sidecar for callers/callees/bidirectional symbol relationships.',
|
|
22
22
|
inputSchemaZod: () => callGraphInputSchema,
|
|
23
23
|
execute: async (args, ctx) => {
|
|
24
24
|
const normalizedArgs = (args && typeof args === 'object')
|
package/dist/tools/read_file.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { isLanguageCapabilitySupportedForExtension } from "@zokizuan/satori-core";
|
|
4
5
|
import { formatZodError } from "./types.js";
|
|
5
6
|
import { ensureAbsolutePath } from "../utils.js";
|
|
6
7
|
const readFileInputSchema = z.object({
|
|
@@ -27,7 +28,7 @@ function normalizeRelativePath(value) {
|
|
|
27
28
|
}
|
|
28
29
|
function isOutlineSupportedFile(absolutePath) {
|
|
29
30
|
const ext = path.extname(absolutePath).toLowerCase();
|
|
30
|
-
return ext
|
|
31
|
+
return isLanguageCapabilitySupportedForExtension(ext, "fileOutline");
|
|
31
32
|
}
|
|
32
33
|
function resolveCodebaseRootForFile(absolutePath, ctx) {
|
|
33
34
|
const allCodebases = typeof ctx.snapshotManager?.getAllCodebases === "function"
|