@zokizuan/satori-mcp 3.4.0 → 3.8.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 +20 -3
- package/dist/config.d.ts +8 -0
- package/dist/config.js +4 -4
- package/dist/core/call-graph.js +10 -10
- package/dist/core/handlers.d.ts +6 -0
- package/dist/core/handlers.js +175 -18
- package/dist/core/search-constants.d.ts +4 -0
- package/dist/core/search-constants.js +10 -0
- package/dist/core/search-types.d.ts +19 -3
- package/dist/core/snapshot.d.ts +5 -0
- package/dist/core/snapshot.js +65 -0
- package/dist/core/sync.d.ts +36 -4
- package/dist/core/sync.js +257 -33
- package/dist/index.js +1 -1
- package/dist/tools/call_graph.js +1 -1
- package/dist/tools/file_outline.js +13 -0
- package/dist/tools/manage_index.js +1 -1
- package/dist/tools/read_file.js +100 -3
- package/dist/tools/search_codebase.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -45,6 +45,10 @@ Tool surface is hard-broken to 6 tools. This keeps routing explicit while exposi
|
|
|
45
45
|
- Enabled by default. Set `MCP_ENABLE_WATCHER=false` to disable
|
|
46
46
|
- Debounce window via `MCP_WATCH_DEBOUNCE_MS` (default `5000`)
|
|
47
47
|
- Watch events reuse the same incremental sync pipeline (`reindexByChange`)
|
|
48
|
+
- Ignore control files (`.satoriignore`, root `.gitignore`) trigger no-reindex reconciliation:
|
|
49
|
+
- delete indexed paths now ignored by active rules
|
|
50
|
+
- incremental sync picks up newly unignored files
|
|
51
|
+
- signature checks in `ensureFreshness` keep this working even when watcher events are missed
|
|
48
52
|
- Safety gates:
|
|
49
53
|
- Watch-triggered sync only runs for `indexed`/`sync_completed` codebases
|
|
50
54
|
- Events are dropped for `indexing`, `indexfailed`, and `requires_reindex`
|
|
@@ -57,7 +61,7 @@ Tool surface is hard-broken to 6 tools. This keeps routing explicit while exposi
|
|
|
57
61
|
|
|
58
62
|
### `manage_index`
|
|
59
63
|
|
|
60
|
-
Manage index lifecycle operations (create/reindex/sync/status/clear) for a codebase path.
|
|
64
|
+
Manage index lifecycle operations (create/reindex/sync/status/clear) for a codebase path. Ignore-rule edits in repo-root .satoriignore/.gitignore reconcile automatically in the normal sync path (no full reindex required). If you need immediate convergence after ignore edits, run action="sync" and then rerun search_codebase. Use action="reindex" for fingerprint/schema incompatibility or full rebuild recovery.
|
|
61
65
|
|
|
62
66
|
| Parameter | Type | Required | Default | Description |
|
|
63
67
|
|---|---|---|---|---|
|
|
@@ -71,7 +75,7 @@ Manage index lifecycle operations (create/reindex/sync/status/clear) for a codeb
|
|
|
71
75
|
|
|
72
76
|
### `search_codebase`
|
|
73
77
|
|
|
74
|
-
Unified semantic search with runtime/docs scope control, grouped/raw output modes, deterministic ranking, and structured freshness
|
|
78
|
+
Unified semantic search with runtime/docs scope control, grouped/raw output modes, deterministic ranking, and structured freshness decisions. For runtime debugging, start with scope="runtime". If you need both runtime and docs context, use scope="mixed". If top results are dominated by tests/fixtures/docs, edit repo-root .satoriignore using your host/editor (examples, not exhaustive: **/*.test.*, **/*.spec.*, **/__tests__/**, **/__fixtures__/**, **/fixtures/**, coverage/**), wait one debounce window (MCP_WATCH_DEBOUNCE_MS, default 5000ms), then rerun search_codebase. For immediate convergence, run manage_index with {"action":"sync","path":"<same path used in search_codebase>"}.
|
|
75
79
|
|
|
76
80
|
| Parameter | Type | Required | Default | Description |
|
|
77
81
|
|---|---|---|---|---|
|
|
@@ -85,7 +89,7 @@ Unified semantic search with runtime/docs scope control, grouped/raw output mode
|
|
|
85
89
|
|
|
86
90
|
### `call_graph`
|
|
87
91
|
|
|
88
|
-
Traverse the prebuilt TS/Python call graph sidecar for callers/callees/bidirectional symbol relationships.
|
|
92
|
+
Traverse the prebuilt TS/JS/Python call graph sidecar for callers/callees/bidirectional symbol relationships.
|
|
89
93
|
|
|
90
94
|
| Parameter | Type | Required | Default | Description |
|
|
91
95
|
|---|---|---|---|---|
|
|
@@ -106,6 +110,9 @@ Return a sidecar-backed symbol outline for one file, including call_graph jump h
|
|
|
106
110
|
| `start_line` | integer | no | | Optional start line filter (1-based, inclusive). |
|
|
107
111
|
| `end_line` | integer | no | | Optional end line filter (1-based, inclusive). |
|
|
108
112
|
| `limitSymbols` | integer | no | `500` | Maximum number of returned symbols after line filtering. |
|
|
113
|
+
| `resolveMode` | enum("outline", "exact") | no | `"outline"` | Outline mode returns all symbols (windowed/limited). Exact mode resolves deterministic symbol matches in this file. |
|
|
114
|
+
| `symbolIdExact` | string | no | | Used with resolveMode="exact": exact symbolId match in the target file. |
|
|
115
|
+
| `symbolLabelExact` | string | no | | Used with resolveMode="exact": exact symbol label match in the target file. |
|
|
109
116
|
|
|
110
117
|
### `read_file`
|
|
111
118
|
|
|
@@ -117,6 +124,7 @@ Read file content from the local filesystem, with optional 1-based inclusive lin
|
|
|
117
124
|
| `start_line` | integer | no | | Optional start line (1-based, inclusive). |
|
|
118
125
|
| `end_line` | integer | no | | Optional end line (1-based, inclusive). |
|
|
119
126
|
| `mode` | enum("plain", "annotated") | no | `"plain"` | Output mode. plain returns text only; annotated returns content plus sidecar-backed outline metadata. |
|
|
127
|
+
| `open_symbol` | object | no | | Optional deterministic symbol jump request for this file path. Uses exact symbol resolution within `path` when symbolId/symbolLabel is provided. |
|
|
120
128
|
|
|
121
129
|
### `list_codebases`
|
|
122
130
|
|
|
@@ -127,6 +135,15 @@ No parameters.
|
|
|
127
135
|
|
|
128
136
|
<!-- TOOLS_END -->
|
|
129
137
|
|
|
138
|
+
### `read_file.open_symbol` Fields
|
|
139
|
+
|
|
140
|
+
`open_symbol` resolves symbols inside the same file passed in `read_file.path`.
|
|
141
|
+
|
|
142
|
+
- `symbolId` (string, optional): deterministic symbol id to resolve in `path`.
|
|
143
|
+
- `symbolLabel` (string, optional): exact symbol label to resolve in `path`.
|
|
144
|
+
- `start_line` (integer, optional): direct 1-based start line for span-based jump.
|
|
145
|
+
- `end_line` (integer, optional): direct 1-based end line (inclusive).
|
|
146
|
+
|
|
130
147
|
## MCP Config Examples
|
|
131
148
|
|
|
132
149
|
### JSON-style (Claude Desktop, Cursor)
|
package/dist/config.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type EmbeddingProvider = 'OpenAI' | 'VoyageAI' | 'Gemini' | 'Ollama';
|
|
2
2
|
export type VectorStoreProvider = 'Milvus';
|
|
3
3
|
export type FingerprintSource = 'verified' | 'assumed_v2';
|
|
4
|
+
export declare const DEFAULT_WATCH_DEBOUNCE_MS = 5000;
|
|
4
5
|
export interface IndexFingerprint {
|
|
5
6
|
embeddingProvider: EmbeddingProvider;
|
|
6
7
|
embeddingModel: string;
|
|
@@ -37,6 +38,10 @@ export interface CallGraphSidecarInfo {
|
|
|
37
38
|
noteCount: number;
|
|
38
39
|
fingerprint: IndexFingerprint;
|
|
39
40
|
}
|
|
41
|
+
export interface CodebaseIndexManifest {
|
|
42
|
+
indexedPaths: string[];
|
|
43
|
+
updatedAt: string;
|
|
44
|
+
}
|
|
40
45
|
export interface CodebaseSnapshotV1 {
|
|
41
46
|
indexedCodebases: string[];
|
|
42
47
|
indexingCodebases: string[] | Record<string, number>;
|
|
@@ -48,6 +53,9 @@ interface CodebaseInfoBase {
|
|
|
48
53
|
fingerprintSource?: FingerprintSource;
|
|
49
54
|
reindexReason?: 'legacy_unverified_fingerprint' | 'fingerprint_mismatch' | 'missing_fingerprint';
|
|
50
55
|
callGraphSidecar?: CallGraphSidecarInfo;
|
|
56
|
+
indexManifest?: CodebaseIndexManifest;
|
|
57
|
+
ignoreRulesVersion?: number;
|
|
58
|
+
ignoreControlSignature?: string;
|
|
51
59
|
}
|
|
52
60
|
export interface CodebaseInfoIndexing extends CodebaseInfoBase {
|
|
53
61
|
status: 'indexing';
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { envManager } from "@zokizuan/satori-core";
|
|
2
|
+
export const DEFAULT_WATCH_DEBOUNCE_MS = 5000;
|
|
2
3
|
// Helper function to get default model for each provider
|
|
3
4
|
export function getDefaultModelForProvider(provider) {
|
|
4
5
|
switch (provider) {
|
|
@@ -51,7 +52,6 @@ export function buildRuntimeIndexFingerprint(config, embeddingDimension) {
|
|
|
51
52
|
export function createMcpConfig() {
|
|
52
53
|
const defaultProvider = envManager.get('EMBEDDING_PROVIDER') || 'VoyageAI';
|
|
53
54
|
const defaultReadFileMaxLines = 1000;
|
|
54
|
-
const defaultWatchDebounceMs = 5000;
|
|
55
55
|
// Parse output dimension from env var
|
|
56
56
|
const outputDimensionStr = envManager.get('EMBEDDING_OUTPUT_DIMENSION');
|
|
57
57
|
let encoderOutputDimension;
|
|
@@ -92,7 +92,7 @@ export function createMcpConfig() {
|
|
|
92
92
|
const watchSyncEnabled = watchSyncEnabledRaw
|
|
93
93
|
? watchSyncEnabledRaw.toLowerCase() === 'true'
|
|
94
94
|
: true;
|
|
95
|
-
let watchDebounceMs =
|
|
95
|
+
let watchDebounceMs = DEFAULT_WATCH_DEBOUNCE_MS;
|
|
96
96
|
const watchDebounceRaw = envManager.get('MCP_WATCH_DEBOUNCE_MS');
|
|
97
97
|
if (watchDebounceRaw) {
|
|
98
98
|
const parsed = Number.parseInt(watchDebounceRaw, 10);
|
|
@@ -100,7 +100,7 @@ export function createMcpConfig() {
|
|
|
100
100
|
watchDebounceMs = parsed;
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
|
-
console.warn(`[WARN] Invalid MCP_WATCH_DEBOUNCE_MS value: ${watchDebounceRaw}. Using default ${
|
|
103
|
+
console.warn(`[WARN] Invalid MCP_WATCH_DEBOUNCE_MS value: ${watchDebounceRaw}. Using default ${DEFAULT_WATCH_DEBOUNCE_MS}.`);
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
const config = {
|
|
@@ -140,7 +140,7 @@ export function logConfigurationSummary(config) {
|
|
|
140
140
|
console.log(`[MCP] Embedding Provider: ${config.encoderProvider}`);
|
|
141
141
|
console.log(`[MCP] Embedding Model: ${config.encoderModel}`);
|
|
142
142
|
console.log(`[MCP] Milvus Address: ${config.milvusEndpoint || (config.milvusApiToken ? '[Auto-resolve from token]' : '[Not configured]')}`);
|
|
143
|
-
console.log(`[MCP] Proactive Watcher: ${config.watchSyncEnabled ? `enabled (${config.watchDebounceMs ||
|
|
143
|
+
console.log(`[MCP] Proactive Watcher: ${config.watchSyncEnabled ? `enabled (${config.watchDebounceMs || DEFAULT_WATCH_DEBOUNCE_MS}ms debounce)` : 'disabled'}`);
|
|
144
144
|
// Log provider-specific configuration without exposing sensitive data
|
|
145
145
|
switch (config.encoderProvider) {
|
|
146
146
|
case 'OpenAI':
|
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
|
@@ -34,8 +34,12 @@ export declare class ToolHandlers {
|
|
|
34
34
|
private isTestPath;
|
|
35
35
|
private isDocPath;
|
|
36
36
|
private isGeneratedPath;
|
|
37
|
+
private isFixturePath;
|
|
37
38
|
private isEntrypointPath;
|
|
38
39
|
private classifyPathCategory;
|
|
40
|
+
private classifyNoiseCategory;
|
|
41
|
+
private roundRatio;
|
|
42
|
+
private buildNoiseMitigationHint;
|
|
39
43
|
private shouldIncludeCategoryInScope;
|
|
40
44
|
private parseIndexedAtMs;
|
|
41
45
|
private getStalenessBucket;
|
|
@@ -64,6 +68,8 @@ export declare class ToolHandlers {
|
|
|
64
68
|
private parseCodebaseFromMetadata;
|
|
65
69
|
private resolveCollectionCodebasePath;
|
|
66
70
|
private formatCollectionTimestamp;
|
|
71
|
+
private parseTimestampMs;
|
|
72
|
+
private resolveCollectionSortTimestampMs;
|
|
67
73
|
private buildZillizCollectionLimitGuidance;
|
|
68
74
|
private buildCollectionLimitMessage;
|
|
69
75
|
private clearAllCollectionsForForceReindex;
|
package/dist/core/handlers.js
CHANGED
|
@@ -2,9 +2,10 @@ 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
|
-
import {
|
|
7
|
+
import { DEFAULT_WATCH_DEBOUNCE_MS } from "../config.js";
|
|
8
|
+
import { SEARCH_MAX_CANDIDATES, SEARCH_NOISE_HINT_PATTERNS, SEARCH_NOISE_HINT_THRESHOLD, SEARCH_NOISE_HINT_TOP_K, SEARCH_PROXIMITY_WINDOW, SEARCH_RRF_K, SCOPE_PATH_MULTIPLIERS, STALENESS_THRESHOLDS_MS } from "./search-constants.js";
|
|
8
9
|
import { CallGraphSidecarManager } from "./call-graph.js";
|
|
9
10
|
const COLLECTION_LIMIT_PATTERNS = [
|
|
10
11
|
/exceeded the limit number of collections/i,
|
|
@@ -14,6 +15,8 @@ const COLLECTION_LIMIT_PATTERNS = [
|
|
|
14
15
|
];
|
|
15
16
|
const SATORI_COLLECTION_PREFIXES = ['code_chunks_', 'hybrid_code_chunks_'];
|
|
16
17
|
const ZILLIZ_FREE_TIER_COLLECTION_LIMIT = 5;
|
|
18
|
+
const OUTLINE_SUPPORTED_EXTENSIONS = getSupportedExtensionsForCapability('fileOutline');
|
|
19
|
+
const MIN_RELIABLE_COLLECTION_CREATED_AT_MS = Date.UTC(2000, 0, 1);
|
|
17
20
|
function collectErrorFragments(value, output, visited, depth = 0) {
|
|
18
21
|
if (value === null || value === undefined || depth > 4 || output.length >= 8) {
|
|
19
22
|
return;
|
|
@@ -403,6 +406,10 @@ export class ToolHandlers {
|
|
|
403
406
|
|| normalizedPath.endsWith('.min.js')
|
|
404
407
|
|| normalizedPath.endsWith('.min.css');
|
|
405
408
|
}
|
|
409
|
+
isFixturePath(normalizedPath) {
|
|
410
|
+
return this.hasPathSegment(normalizedPath, 'fixtures')
|
|
411
|
+
|| this.hasPathSegment(normalizedPath, '__fixtures__');
|
|
412
|
+
}
|
|
406
413
|
isEntrypointPath(normalizedPath) {
|
|
407
414
|
const entryNames = ['main.', 'index.', 'app.', 'server.', 'cli.', 'entry.'];
|
|
408
415
|
const baseName = normalizedPath.split('/').pop() || '';
|
|
@@ -424,6 +431,68 @@ export class ToolHandlers {
|
|
|
424
431
|
return 'srcRuntime';
|
|
425
432
|
return 'neutral';
|
|
426
433
|
}
|
|
434
|
+
classifyNoiseCategory(relativePath) {
|
|
435
|
+
const normalized = this.normalizeSearchPath(relativePath);
|
|
436
|
+
// Deterministic precedence: generated > tests > fixtures > docs > runtime.
|
|
437
|
+
if (this.isGeneratedPath(normalized)
|
|
438
|
+
|| this.hasPathSegment(normalized, 'coverage')
|
|
439
|
+
|| this.hasPathSegment(normalized, 'dist')
|
|
440
|
+
|| this.hasPathSegment(normalized, 'build'))
|
|
441
|
+
return 'generated';
|
|
442
|
+
if (this.isTestPath(normalized))
|
|
443
|
+
return 'tests';
|
|
444
|
+
if (this.isFixturePath(normalized))
|
|
445
|
+
return 'fixtures';
|
|
446
|
+
if (this.isDocPath(normalized))
|
|
447
|
+
return 'docs';
|
|
448
|
+
return 'runtime';
|
|
449
|
+
}
|
|
450
|
+
roundRatio(value) {
|
|
451
|
+
return Math.round(value * 100) / 100;
|
|
452
|
+
}
|
|
453
|
+
buildNoiseMitigationHint(filesInOrder) {
|
|
454
|
+
if (!Array.isArray(filesInOrder) || filesInOrder.length === 0) {
|
|
455
|
+
return undefined;
|
|
456
|
+
}
|
|
457
|
+
const topK = Math.min(SEARCH_NOISE_HINT_TOP_K, filesInOrder.length);
|
|
458
|
+
if (topK <= 0) {
|
|
459
|
+
return undefined;
|
|
460
|
+
}
|
|
461
|
+
const counts = {
|
|
462
|
+
tests: 0,
|
|
463
|
+
fixtures: 0,
|
|
464
|
+
docs: 0,
|
|
465
|
+
generated: 0,
|
|
466
|
+
runtime: 0,
|
|
467
|
+
};
|
|
468
|
+
for (let i = 0; i < topK; i++) {
|
|
469
|
+
const category = this.classifyNoiseCategory(filesInOrder[i]);
|
|
470
|
+
counts[category] += 1;
|
|
471
|
+
}
|
|
472
|
+
const noisyRatio = (counts.tests + counts.fixtures + counts.docs + counts.generated) / topK;
|
|
473
|
+
if (noisyRatio < SEARCH_NOISE_HINT_THRESHOLD) {
|
|
474
|
+
return undefined;
|
|
475
|
+
}
|
|
476
|
+
const ratios = {
|
|
477
|
+
tests: this.roundRatio(counts.tests / topK),
|
|
478
|
+
fixtures: this.roundRatio(counts.fixtures / topK),
|
|
479
|
+
docs: this.roundRatio(counts.docs / topK),
|
|
480
|
+
generated: this.roundRatio(counts.generated / topK),
|
|
481
|
+
runtime: this.roundRatio(counts.runtime / topK),
|
|
482
|
+
};
|
|
483
|
+
const debounceMs = typeof this.syncManager?.getWatchDebounceMs === 'function'
|
|
484
|
+
? this.syncManager.getWatchDebounceMs()
|
|
485
|
+
: DEFAULT_WATCH_DEBOUNCE_MS;
|
|
486
|
+
return {
|
|
487
|
+
reason: 'top_results_noise_dominant',
|
|
488
|
+
topK,
|
|
489
|
+
ratios,
|
|
490
|
+
recommendedScope: 'runtime',
|
|
491
|
+
suggestedIgnorePatterns: [...SEARCH_NOISE_HINT_PATTERNS],
|
|
492
|
+
debounceMs,
|
|
493
|
+
nextStep: 'Use scope="runtime". If you still need docs context, use scope="mixed". Edit repo-root .satoriignore using your host/editor, wait one debounce window, rerun search_codebase, or run manage_index with {"action":"sync","path":"<same path used in search_codebase>"} for immediate convergence.',
|
|
494
|
+
};
|
|
495
|
+
}
|
|
427
496
|
shouldIncludeCategoryInScope(scope, category) {
|
|
428
497
|
if (scope === 'runtime') {
|
|
429
498
|
return category !== 'docs' && category !== 'tests';
|
|
@@ -473,13 +542,12 @@ export class ToolHandlers {
|
|
|
473
542
|
return `grp_${digest}`;
|
|
474
543
|
}
|
|
475
544
|
isCallGraphLanguageSupported(language, file) {
|
|
476
|
-
|
|
477
|
-
if (normalized === 'typescript' || normalized === 'ts' || normalized === 'python' || normalized === 'py') {
|
|
545
|
+
if (isLanguageCapabilitySupportedForLanguage(language, 'callGraphQuery')) {
|
|
478
546
|
return true;
|
|
479
547
|
}
|
|
480
548
|
if (typeof file === 'string') {
|
|
481
549
|
const ext = path.extname(file).toLowerCase();
|
|
482
|
-
return ext
|
|
550
|
+
return isLanguageCapabilitySupportedForExtension(ext, 'callGraphQuery');
|
|
483
551
|
}
|
|
484
552
|
return false;
|
|
485
553
|
}
|
|
@@ -574,9 +642,9 @@ export class ToolHandlers {
|
|
|
574
642
|
}
|
|
575
643
|
return 'not_ready';
|
|
576
644
|
}
|
|
577
|
-
getContextIgnorePatterns() {
|
|
645
|
+
getContextIgnorePatterns(codebasePath) {
|
|
578
646
|
if (typeof this.context.getActiveIgnorePatterns === 'function') {
|
|
579
|
-
const patterns = this.context.getActiveIgnorePatterns();
|
|
647
|
+
const patterns = this.context.getActiveIgnorePatterns(codebasePath);
|
|
580
648
|
if (Array.isArray(patterns)) {
|
|
581
649
|
return patterns.filter((pattern) => typeof pattern === 'string');
|
|
582
650
|
}
|
|
@@ -585,7 +653,7 @@ export class ToolHandlers {
|
|
|
585
653
|
}
|
|
586
654
|
async rebuildCallGraphForIndex(codebasePath) {
|
|
587
655
|
try {
|
|
588
|
-
const sidecar = await this.callGraphManager.rebuildForCodebase(codebasePath, this.getContextIgnorePatterns());
|
|
656
|
+
const sidecar = await this.callGraphManager.rebuildForCodebase(codebasePath, this.getContextIgnorePatterns(codebasePath));
|
|
589
657
|
this.snapshotManager.setCodebaseCallGraphSidecar(codebasePath, sidecar);
|
|
590
658
|
this.snapshotManager.saveCodebaseSnapshot();
|
|
591
659
|
console.log(`[CALL-GRAPH] Rebuilt sidecar for '${codebasePath}' (${sidecar.nodeCount} nodes, ${sidecar.edgeCount} edges).`);
|
|
@@ -596,7 +664,7 @@ export class ToolHandlers {
|
|
|
596
664
|
}
|
|
597
665
|
async rebuildCallGraphForSyncDelta(codebasePath, changedFiles) {
|
|
598
666
|
try {
|
|
599
|
-
const sidecar = await this.callGraphManager.rebuildIfSupportedDelta(codebasePath, changedFiles, this.getContextIgnorePatterns());
|
|
667
|
+
const sidecar = await this.callGraphManager.rebuildIfSupportedDelta(codebasePath, changedFiles, this.getContextIgnorePatterns(codebasePath));
|
|
600
668
|
if (!sidecar) {
|
|
601
669
|
return false;
|
|
602
670
|
}
|
|
@@ -707,6 +775,27 @@ export class ToolHandlers {
|
|
|
707
775
|
}
|
|
708
776
|
return new Date(timestamp).toISOString();
|
|
709
777
|
}
|
|
778
|
+
parseTimestampMs(timestamp) {
|
|
779
|
+
if (!timestamp) {
|
|
780
|
+
return undefined;
|
|
781
|
+
}
|
|
782
|
+
const parsed = Date.parse(timestamp);
|
|
783
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
784
|
+
}
|
|
785
|
+
resolveCollectionSortTimestampMs(createdAt, codebasePath, snapshotLastUpdatedByPath) {
|
|
786
|
+
const createdAtMs = this.parseTimestampMs(createdAt);
|
|
787
|
+
const snapshotMs = codebasePath ? snapshotLastUpdatedByPath.get(codebasePath) : undefined;
|
|
788
|
+
// Prefer collection metadata when it looks reliable.
|
|
789
|
+
if (createdAtMs !== undefined && createdAtMs >= MIN_RELIABLE_COLLECTION_CREATED_AT_MS) {
|
|
790
|
+
return createdAtMs;
|
|
791
|
+
}
|
|
792
|
+
// Fallback to snapshot timestamps when collection metadata is missing or suspicious.
|
|
793
|
+
if (snapshotMs !== undefined) {
|
|
794
|
+
return snapshotMs;
|
|
795
|
+
}
|
|
796
|
+
// Last resort for deterministic ordering when nothing else is available.
|
|
797
|
+
return createdAtMs;
|
|
798
|
+
}
|
|
710
799
|
async buildZillizCollectionLimitGuidance(targetCodebasePath) {
|
|
711
800
|
const targetCollectionName = this.context.resolveCollectionName(targetCodebasePath);
|
|
712
801
|
const vectorDb = this.getVectorStore();
|
|
@@ -717,6 +806,13 @@ export class ToolHandlers {
|
|
|
717
806
|
for (const codebasePath of trackedCodebases) {
|
|
718
807
|
byCollectionName.set(this.context.resolveCollectionName(codebasePath), codebasePath);
|
|
719
808
|
}
|
|
809
|
+
const snapshotLastUpdatedByPath = new Map();
|
|
810
|
+
for (const entry of this.snapshotManager.getAllCodebases()) {
|
|
811
|
+
const lastUpdatedMs = this.parseTimestampMs(entry.info.lastUpdated);
|
|
812
|
+
if (lastUpdatedMs !== undefined) {
|
|
813
|
+
snapshotLastUpdatedByPath.set(entry.path, lastUpdatedMs);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
720
816
|
const candidates = [];
|
|
721
817
|
for (const detail of codeCollections) {
|
|
722
818
|
const codebasePath = await this.resolveCollectionCodebasePath(vectorDb, detail.name, byCollectionName);
|
|
@@ -725,15 +821,14 @@ export class ToolHandlers {
|
|
|
725
821
|
createdAt: detail.createdAt,
|
|
726
822
|
codebasePath,
|
|
727
823
|
isTargetCollection: detail.name === targetCollectionName,
|
|
824
|
+
sortTimestampMs: this.resolveCollectionSortTimestampMs(detail.createdAt, codebasePath, snapshotLastUpdatedByPath),
|
|
728
825
|
});
|
|
729
826
|
}
|
|
730
827
|
candidates.sort((a, b) => {
|
|
731
|
-
const
|
|
732
|
-
const
|
|
733
|
-
const aValid = Number.isFinite(aTime);
|
|
734
|
-
const bValid = Number.isFinite(bTime);
|
|
828
|
+
const aValid = Number.isFinite(a.sortTimestampMs);
|
|
829
|
+
const bValid = Number.isFinite(b.sortTimestampMs);
|
|
735
830
|
if (aValid && bValid) {
|
|
736
|
-
return
|
|
831
|
+
return a.sortTimestampMs - b.sortTimestampMs;
|
|
737
832
|
}
|
|
738
833
|
if (aValid)
|
|
739
834
|
return -1;
|
|
@@ -1237,7 +1332,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1237
1332
|
await this.context.loadResolvedIgnorePatterns(absolutePath);
|
|
1238
1333
|
// Initialize file synchronizer with proper ignore patterns (including project-specific patterns)
|
|
1239
1334
|
const { FileSynchronizer } = await import("@zokizuan/satori-core");
|
|
1240
|
-
const ignorePatterns = this.context.getActiveIgnorePatterns() || [];
|
|
1335
|
+
const ignorePatterns = this.context.getActiveIgnorePatterns(absolutePath) || [];
|
|
1241
1336
|
console.log(`[BACKGROUND-INDEX] Using ignore patterns: ${ignorePatterns.join(', ')}`);
|
|
1242
1337
|
const synchronizer = new FileSynchronizer(absolutePath, ignorePatterns);
|
|
1243
1338
|
await synchronizer.initialize();
|
|
@@ -1269,6 +1364,12 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1269
1364
|
console.log(`[BACKGROUND-INDEX] ✅ Indexing completed successfully! Files: ${stats.indexedFiles}, Chunks: ${stats.totalChunks}`);
|
|
1270
1365
|
// Set codebase to indexed status with complete statistics
|
|
1271
1366
|
this.snapshotManager.setCodebaseIndexed(absolutePath, stats, this.runtimeFingerprint, 'verified');
|
|
1367
|
+
if (typeof this.context.getTrackedRelativePaths === 'function') {
|
|
1368
|
+
const trackedPaths = this.context.getTrackedRelativePaths(absolutePath);
|
|
1369
|
+
if (typeof this.snapshotManager.setCodebaseIndexManifest === 'function') {
|
|
1370
|
+
this.snapshotManager.setCodebaseIndexManifest(absolutePath, trackedPaths);
|
|
1371
|
+
}
|
|
1372
|
+
}
|
|
1272
1373
|
this.indexingStats = { indexedFiles: stats.indexedFiles, totalChunks: stats.totalChunks };
|
|
1273
1374
|
// Save snapshot after updating codebase lists
|
|
1274
1375
|
this.snapshotManager.saveCodebaseSnapshot();
|
|
@@ -1568,6 +1669,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1568
1669
|
}
|
|
1569
1670
|
} : {})
|
|
1570
1671
|
}));
|
|
1672
|
+
const noiseMitigationHint = this.buildNoiseMitigationHint(rawResults.map((result) => result.file));
|
|
1571
1673
|
const envelope = {
|
|
1572
1674
|
status: "ok",
|
|
1573
1675
|
path: absolutePath,
|
|
@@ -1578,6 +1680,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1578
1680
|
resultMode: "raw",
|
|
1579
1681
|
freshnessDecision,
|
|
1580
1682
|
...(searchWarnings.length > 0 ? { warnings: searchWarnings } : {}),
|
|
1683
|
+
...(noiseMitigationHint ? { hints: { version: 1, noiseMitigation: noiseMitigationHint } } : {}),
|
|
1581
1684
|
results: rawResults
|
|
1582
1685
|
};
|
|
1583
1686
|
return {
|
|
@@ -1666,6 +1769,8 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1666
1769
|
return labelCmp;
|
|
1667
1770
|
return this.compareNullableStringsAsc(a.symbolId, b.symbolId);
|
|
1668
1771
|
});
|
|
1772
|
+
const visibleGroupedResults = groupedResults.slice(0, input.limit);
|
|
1773
|
+
const noiseMitigationHint = this.buildNoiseMitigationHint(visibleGroupedResults.map((result) => result.file));
|
|
1669
1774
|
const envelope = {
|
|
1670
1775
|
status: "ok",
|
|
1671
1776
|
path: absolutePath,
|
|
@@ -1676,7 +1781,8 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1676
1781
|
resultMode: "grouped",
|
|
1677
1782
|
freshnessDecision,
|
|
1678
1783
|
...(searchWarnings.length > 0 ? { warnings: searchWarnings } : {}),
|
|
1679
|
-
|
|
1784
|
+
...(noiseMitigationHint ? { hints: { version: 1, noiseMitigation: noiseMitigationHint } } : {}),
|
|
1785
|
+
results: visibleGroupedResults
|
|
1680
1786
|
};
|
|
1681
1787
|
return {
|
|
1682
1788
|
content: [{ type: "text", text: JSON.stringify(envelope, null, 2) }],
|
|
@@ -1705,6 +1811,9 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1705
1811
|
: 500;
|
|
1706
1812
|
const requestedStartLine = Number.isFinite(args?.start_line) ? Math.max(1, Number(args.start_line)) : undefined;
|
|
1707
1813
|
const requestedEndLine = Number.isFinite(args?.end_line) ? Math.max(1, Number(args.end_line)) : undefined;
|
|
1814
|
+
const resolveMode = args?.resolveMode === 'exact' ? 'exact' : 'outline';
|
|
1815
|
+
const symbolIdExact = typeof args?.symbolIdExact === 'string' ? args.symbolIdExact.trim() : undefined;
|
|
1816
|
+
const symbolLabelExact = typeof args?.symbolLabelExact === 'string' ? args.symbolLabelExact.trim() : undefined;
|
|
1708
1817
|
try {
|
|
1709
1818
|
await this.syncIndexedCodebasesFromCloud();
|
|
1710
1819
|
const absoluteRoot = ensureAbsolutePath(args.path);
|
|
@@ -1805,7 +1914,7 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1805
1914
|
file: normalizedFile,
|
|
1806
1915
|
outline: null,
|
|
1807
1916
|
hasMore: false,
|
|
1808
|
-
message: `File '${normalizedFile}' is not supported for sidecar outline. Supported extensions: .
|
|
1917
|
+
message: `File '${normalizedFile}' is not supported for sidecar outline. Supported extensions: ${OUTLINE_SUPPORTED_EXTENSIONS.join(', ')}.`
|
|
1809
1918
|
};
|
|
1810
1919
|
return {
|
|
1811
1920
|
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
|
|
@@ -1859,13 +1968,55 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
1859
1968
|
}
|
|
1860
1969
|
};
|
|
1861
1970
|
}));
|
|
1862
|
-
const hasMore = symbols.length > limitSymbols;
|
|
1863
1971
|
const missingSymbolMetadataCount = sidecar.notes.filter((note) => {
|
|
1864
1972
|
return note.type === 'missing_symbol_metadata' && this.normalizeRelativeFilePath(note.file) === normalizedFile;
|
|
1865
1973
|
}).length;
|
|
1866
1974
|
const warnings = missingSymbolMetadataCount > 0
|
|
1867
1975
|
? [`OUTLINE_MISSING_SYMBOL_METADATA:${missingSymbolMetadataCount}`]
|
|
1868
1976
|
: undefined;
|
|
1977
|
+
if (resolveMode === 'exact') {
|
|
1978
|
+
const exactMatches = this.sortFileOutlineSymbols(symbols.filter((symbol) => {
|
|
1979
|
+
if (symbolIdExact && symbol.symbolId !== symbolIdExact) {
|
|
1980
|
+
return false;
|
|
1981
|
+
}
|
|
1982
|
+
if (symbolLabelExact && symbol.symbolLabel !== symbolLabelExact) {
|
|
1983
|
+
return false;
|
|
1984
|
+
}
|
|
1985
|
+
return true;
|
|
1986
|
+
}));
|
|
1987
|
+
if (exactMatches.length === 0) {
|
|
1988
|
+
const payload = {
|
|
1989
|
+
status: 'not_found',
|
|
1990
|
+
path: absoluteRoot,
|
|
1991
|
+
file: normalizedFile,
|
|
1992
|
+
outline: null,
|
|
1993
|
+
hasMore: false,
|
|
1994
|
+
message: 'No exact symbol match found in file outline.',
|
|
1995
|
+
...(warnings ? { warnings } : {})
|
|
1996
|
+
};
|
|
1997
|
+
return {
|
|
1998
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }]
|
|
1999
|
+
};
|
|
2000
|
+
}
|
|
2001
|
+
const hasMoreExact = exactMatches.length > limitSymbols;
|
|
2002
|
+
const exactPayload = {
|
|
2003
|
+
status: exactMatches.length > 1 ? 'ambiguous' : 'ok',
|
|
2004
|
+
path: absoluteRoot,
|
|
2005
|
+
file: normalizedFile,
|
|
2006
|
+
outline: {
|
|
2007
|
+
symbols: exactMatches.slice(0, limitSymbols)
|
|
2008
|
+
},
|
|
2009
|
+
hasMore: hasMoreExact,
|
|
2010
|
+
...(exactMatches.length > 1 ? {
|
|
2011
|
+
message: `Multiple exact symbol matches found (${exactMatches.length}). Narrow with symbolIdExact for deterministic selection.`
|
|
2012
|
+
} : {}),
|
|
2013
|
+
...(warnings ? { warnings } : {})
|
|
2014
|
+
};
|
|
2015
|
+
return {
|
|
2016
|
+
content: [{ type: "text", text: JSON.stringify(exactPayload, null, 2) }]
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
const hasMore = symbols.length > limitSymbols;
|
|
1869
2020
|
const payload = {
|
|
1870
2021
|
status: 'ok',
|
|
1871
2022
|
path: absoluteRoot,
|
|
@@ -2329,6 +2480,12 @@ To force rebuild from scratch: call manage_index with {"action":"create","path":
|
|
|
2329
2480
|
removed: syncStats.removed,
|
|
2330
2481
|
modified: syncStats.modified
|
|
2331
2482
|
};
|
|
2483
|
+
if (typeof this.context.getTrackedRelativePaths === 'function') {
|
|
2484
|
+
const trackedPaths = this.context.getTrackedRelativePaths(absolutePath);
|
|
2485
|
+
if (typeof this.snapshotManager.setCodebaseIndexManifest === 'function') {
|
|
2486
|
+
this.snapshotManager.setCodebaseIndexManifest(absolutePath, trackedPaths);
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2332
2489
|
// Store sync result in snapshot
|
|
2333
2490
|
this.snapshotManager.setCodebaseSyncCompleted(absolutePath, syncTotals, this.runtimeFingerprint, 'verified');
|
|
2334
2491
|
this.snapshotManager.saveCodebaseSnapshot();
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export declare const SEARCH_RRF_K = 60;
|
|
2
2
|
export declare const SEARCH_MAX_CANDIDATES = 80;
|
|
3
3
|
export declare const SEARCH_PROXIMITY_WINDOW = 25;
|
|
4
|
+
export declare const SEARCH_NOISE_HINT_TOP_K = 5;
|
|
5
|
+
export declare const SEARCH_NOISE_HINT_THRESHOLD = 0.6;
|
|
6
|
+
export declare const SEARCH_NOISE_HINT_PATTERNS: readonly ["**/*.test.*", "**/*.spec.*", "**/__tests__/**", "**/__fixtures__/**", "**/fixtures/**", "coverage/**"];
|
|
4
7
|
export declare const STALENESS_THRESHOLDS_MS: {
|
|
5
8
|
readonly fresh: number;
|
|
6
9
|
readonly aging: number;
|
|
@@ -8,6 +11,7 @@ export declare const STALENESS_THRESHOLDS_MS: {
|
|
|
8
11
|
export type SearchScope = 'runtime' | 'mixed' | 'docs';
|
|
9
12
|
export type SearchResultMode = 'grouped' | 'raw';
|
|
10
13
|
export type SearchGroupBy = 'symbol' | 'file';
|
|
14
|
+
export type SearchNoiseCategory = 'tests' | 'fixtures' | 'docs' | 'generated' | 'runtime';
|
|
11
15
|
export type PathCategory = 'entrypoint' | 'core' | 'srcRuntime' | 'neutral' | 'tests' | 'docs' | 'generated';
|
|
12
16
|
export declare const SCOPE_PATH_MULTIPLIERS: Record<SearchScope, Record<PathCategory, number>>;
|
|
13
17
|
//# sourceMappingURL=search-constants.d.ts.map
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
export const SEARCH_RRF_K = 60;
|
|
2
2
|
export const SEARCH_MAX_CANDIDATES = 80;
|
|
3
3
|
export const SEARCH_PROXIMITY_WINDOW = 25;
|
|
4
|
+
export const SEARCH_NOISE_HINT_TOP_K = 5;
|
|
5
|
+
export const SEARCH_NOISE_HINT_THRESHOLD = 0.60;
|
|
6
|
+
export const SEARCH_NOISE_HINT_PATTERNS = [
|
|
7
|
+
'**/*.test.*',
|
|
8
|
+
'**/*.spec.*',
|
|
9
|
+
'**/__tests__/**',
|
|
10
|
+
'**/__fixtures__/**',
|
|
11
|
+
'**/fixtures/**',
|
|
12
|
+
'coverage/**',
|
|
13
|
+
];
|
|
4
14
|
export const STALENESS_THRESHOLDS_MS = {
|
|
5
15
|
fresh: 30 * 60 * 1000,
|
|
6
16
|
aging: 24 * 60 * 60 * 1000,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FreshnessDecision } from "./sync.js";
|
|
2
|
-
import { SearchGroupBy, SearchResultMode, SearchScope } from "./search-constants.js";
|
|
2
|
+
import { SearchGroupBy, SearchNoiseCategory, SearchResultMode, SearchScope } from "./search-constants.js";
|
|
3
3
|
import { FingerprintSource, IndexFingerprint } from "../config.js";
|
|
4
4
|
export type StalenessBucket = "fresh" | "aging" | "stale" | "unknown";
|
|
5
5
|
export interface SearchSpan {
|
|
@@ -65,6 +65,19 @@ export interface FingerprintCompatibilityDiagnostics {
|
|
|
65
65
|
reindexReason?: "legacy_unverified_fingerprint" | "fingerprint_mismatch" | "missing_fingerprint";
|
|
66
66
|
statusAtCheck?: "indexed" | "indexing" | "indexfailed" | "sync_completed" | "requires_reindex" | "not_found";
|
|
67
67
|
}
|
|
68
|
+
export interface SearchNoiseMitigationHint {
|
|
69
|
+
reason: "top_results_noise_dominant";
|
|
70
|
+
topK: number;
|
|
71
|
+
ratios: Record<SearchNoiseCategory, number>;
|
|
72
|
+
recommendedScope: "runtime";
|
|
73
|
+
suggestedIgnorePatterns: string[];
|
|
74
|
+
debounceMs: number;
|
|
75
|
+
nextStep: string;
|
|
76
|
+
}
|
|
77
|
+
export interface SearchResponseHints extends Record<string, unknown> {
|
|
78
|
+
version?: 1;
|
|
79
|
+
noiseMitigation?: SearchNoiseMitigationHint;
|
|
80
|
+
}
|
|
68
81
|
interface SearchBaseResponseEnvelope {
|
|
69
82
|
status: "ok" | "requires_reindex" | "not_indexed";
|
|
70
83
|
path: string;
|
|
@@ -77,7 +90,7 @@ interface SearchBaseResponseEnvelope {
|
|
|
77
90
|
} | null;
|
|
78
91
|
warnings?: string[];
|
|
79
92
|
message?: string;
|
|
80
|
-
hints?:
|
|
93
|
+
hints?: SearchResponseHints;
|
|
81
94
|
compatibility?: FingerprintCompatibilityDiagnostics;
|
|
82
95
|
}
|
|
83
96
|
export interface SearchGroupedResponseEnvelope extends SearchBaseResponseEnvelope {
|
|
@@ -104,8 +117,11 @@ export interface FileOutlineInput {
|
|
|
104
117
|
start_line?: number;
|
|
105
118
|
end_line?: number;
|
|
106
119
|
limitSymbols?: number;
|
|
120
|
+
resolveMode?: "outline" | "exact";
|
|
121
|
+
symbolIdExact?: string;
|
|
122
|
+
symbolLabelExact?: string;
|
|
107
123
|
}
|
|
108
|
-
export type FileOutlineStatus = "ok" | "not_found" | "requires_reindex" | "unsupported";
|
|
124
|
+
export type FileOutlineStatus = "ok" | "not_found" | "requires_reindex" | "unsupported" | "ambiguous";
|
|
109
125
|
export interface FileOutlineSymbolResult {
|
|
110
126
|
symbolId: string;
|
|
111
127
|
symbolLabel: string;
|
package/dist/core/snapshot.d.ts
CHANGED
|
@@ -49,6 +49,11 @@ export declare class SnapshotManager {
|
|
|
49
49
|
}, indexFingerprint?: IndexFingerprint, fingerprintSource?: FingerprintSource): void;
|
|
50
50
|
setCodebaseRequiresReindex(codebasePath: string, reason: 'legacy_unverified_fingerprint' | 'fingerprint_mismatch' | 'missing_fingerprint', message?: string): void;
|
|
51
51
|
setCodebaseCallGraphSidecar(codebasePath: string, sidecar: CallGraphSidecarInfo): void;
|
|
52
|
+
setCodebaseIndexManifest(codebasePath: string, indexedPaths: string[]): void;
|
|
53
|
+
getCodebaseIndexedPaths(codebasePath: string): string[];
|
|
54
|
+
setCodebaseIgnoreRulesVersion(codebasePath: string, version: number): void;
|
|
55
|
+
getCodebaseIgnoreControlSignature(codebasePath: string): string | undefined;
|
|
56
|
+
setCodebaseIgnoreControlSignature(codebasePath: string, signature: string): void;
|
|
52
57
|
getCodebaseCallGraphSidecar(codebasePath: string): CallGraphSidecarInfo | undefined;
|
|
53
58
|
removeCodebaseCompletely(codebasePath: string): void;
|
|
54
59
|
removeIndexedCodebase(codebasePath: string): void;
|