dsh-code-index 0.8.0 → 0.9.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.
@@ -0,0 +1,634 @@
1
+ import * as _deepseek_ai_dsh_tools from '@deepseek-ai/dsh-tools';
2
+ import Schema from '@deepseek-ai/schemastery';
3
+
4
+ /** Shared data model for dsh-code-index. */
5
+ /** On-disk cache layout version. Bump when persisted graph/symbol shapes change. */
6
+ declare const REPO_INDEX_SCHEMA_VERSION: 2;
7
+ type SymbolKind = 'function' | 'method' | 'class' | 'interface' | 'type' | 'enum' | 'variable' | 'field' | 'import' | 'module';
8
+ /** Stable, file-qualified symbol identity: `sym:v1:<file>#<scope>/<segment>`. */
9
+ type SymbolId = string;
10
+ /** Vocabulary for one scope segment in a qualified symbol id. */
11
+ type ScopeKind = 'module' | 'namespace' | 'class' | 'interface' | 'trait' | 'impl' | 'function' | 'method' | 'owner';
12
+ interface SymbolScopePart {
13
+ kind: ScopeKind;
14
+ name: string;
15
+ /** 1-based among sibling scope owners with the same kind and name. */
16
+ ordinal: number;
17
+ }
18
+ interface SymbolInfo {
19
+ /** Stable qualified id; unique within a RepoIndex. */
20
+ id: SymbolId;
21
+ /** Symbol name (identifier / type id / member name). */
22
+ name: string;
23
+ kind: SymbolKind;
24
+ /** Repo-relative path of the containing file, always forward-slash. */
25
+ file: string;
26
+ /** 1-based start line. */
27
+ line: number;
28
+ /** 1-based end line (inclusive). */
29
+ endLine: number;
30
+ /** True when the symbol is exported at module level (export .. / export default). */
31
+ exported: boolean;
32
+ /** Short human-readable signature, e.g. `greet(name: string)` — empty when n/a. */
33
+ signature: string;
34
+ /** Owners only; excludes the symbol itself. Empty at module level. */
35
+ scope: SymbolScopePart[];
36
+ /** 1-based among symbols with the same scope, kind, and name. */
37
+ ordinal: number;
38
+ }
39
+ /** One name bound by an import statement, with its local alias. */
40
+ interface ImportBinding {
41
+ /** Imported name: "foo" | "default" | "*" | null (namespace/package). */
42
+ imported: string | null;
43
+ /** Name visible in this file (alias when renamed). */
44
+ local: string;
45
+ kind: 'named' | 'default' | 'namespace' | 'package' | 'static' | 'glob';
46
+ }
47
+ /** Structured form of one import/include/use site. */
48
+ interface ImportInfo {
49
+ specifier: string;
50
+ line: number;
51
+ kind: 'import' | 'reexport' | 'include' | 'use';
52
+ bindings: ImportBinding[];
53
+ }
54
+ /** One call site: callee name, line, and enclosing function ('' = module level). */
55
+ interface CallInfo {
56
+ /** Callee name as written (identifier, member/property, or qualified tail). */
57
+ name: string;
58
+ /** 1-based line of the call expression. */
59
+ line: number;
60
+ /** Enclosing function/method name, or '' for a module-level call. */
61
+ from: string;
62
+ /** Structural owner from AST containment; null at module level. */
63
+ fromId: SymbolId | null;
64
+ /** Receiver/namespace text when available: `ns.foo()` -> "ns"; bare -> null. */
65
+ qualifier: string | null;
66
+ }
67
+ interface IndexedFile {
68
+ /** Repo-relative path (forward-slash). */
69
+ path: string;
70
+ lang: string;
71
+ /** fs mtime of the source file at index time (milliseconds). */
72
+ mtimeMs: number;
73
+ symbols: SymbolInfo[];
74
+ /** Derived compatibility view of {@link importDetails} specifiers. */
75
+ imports?: string[];
76
+ /** Structured import/include/use sites with their name bindings. */
77
+ importDetails?: ImportInfo[];
78
+ /** Call sites found in this file (callee + line + enclosing function).
79
+ * Optional because caches written before call-graph support lack it. */
80
+ calls?: CallInfo[];
81
+ }
82
+ interface RepoIndex {
83
+ /** Persisted layout version; see {@link REPO_INDEX_SCHEMA_VERSION}. */
84
+ schemaVersion: typeof REPO_INDEX_SCHEMA_VERSION;
85
+ /** Absolute source root this index describes. */
86
+ root: string;
87
+ /** Unix ms when the index was generated. */
88
+ generatedAt: number;
89
+ files: IndexedFile[];
90
+ excludedDirs: string[];
91
+ }
92
+ declare function symbolCount(index: RepoIndex): number;
93
+ /** Optional config consumed by the index build pipeline. */
94
+ interface IndexOptions {
95
+ /** Extra directories to exclude, appended to the defaults. */
96
+ excludeDirs?: string[];
97
+ /** Minimum mtime delta (ms) that forces a re-extract in refresh mode. */
98
+ staleToleranceMs?: number;
99
+ }
100
+
101
+ /** Build a RepoIndex for a workspace: scan -> extract -> persist. */
102
+
103
+ /**
104
+ * Full build: scan + extract every supported file. Existing per-file
105
+ * extraction is reused when `previous` holds an identical mtime for the
106
+ * same rel path (incremental refresh), so touched files alone re-parse.
107
+ */
108
+ declare function buildIndex(root: string, options?: IndexOptions, previous?: RepoIndex | null, forcePaths?: ReadonlySet<string>): Promise<RepoIndex>;
109
+ /** Convenience wrapper: evolve an on-disk cache if `root` exists. */
110
+ declare function buildIndexWithCache(root: string, options?: IndexOptions, cacheDir?: string, forcePaths?: ReadonlySet<string>): Promise<RepoIndex>;
111
+ /**
112
+ * Locate the git repo root for a path by walking up to the nearest `.git`
113
+ * directory. Bounded walk (max `maxLevels` levels); returns `null` when no
114
+ * repo marker is found — callers must NOT index an untagged directory
115
+ * (the fs root is the classic footgun: indexing `C:\` by accident).
116
+ */
117
+ declare function findRepoRoot(startDir: string, maxLevels?: number): Promise<string | null>;
118
+
119
+ /**
120
+ * tree-sitter symbol extraction.
121
+ *
122
+ * Parses a source text with a per-language grammar (web-tree-sitter WASM,
123
+ * static grammars from tree-sitter-wasms) and returns flat SymbolInfo rows.
124
+ *
125
+ * NOTE on the dependency pin: web-tree-sitter must stay at ^0.20.x — newer
126
+ * releases expect dylinked grammar wasm, while tree-sitter-wasms ships
127
+ * static builds. Verified working pair: web-tree-sitter@0.20.8 + tree-sitter-wasms@0.1.13.
128
+ */
129
+
130
+ type LanguageId = 'typescript' | 'javascript' | 'python' | 'go' | 'rust' | 'java' | 'cpp' | 'c';
131
+ declare function languageForFile(filePath: string): LanguageId | null;
132
+ interface ExtractedFile {
133
+ symbols: SymbolInfo[];
134
+ /** Derived compatibility view of {@link importDetails} specifiers. */
135
+ imports: string[];
136
+ /** Structured import/include/use sites with name bindings. */
137
+ importDetails: ImportInfo[];
138
+ /** Call sites, ordered by line: callee name + enclosing function. */
139
+ calls: CallInfo[];
140
+ }
141
+ declare function extractAll(code: string, id: LanguageId, file?: string): Promise<ExtractedFile>;
142
+ /** Symbols only — see extractAll for the combined parse. */
143
+ declare function extractSymbols(code: string, id: LanguageId): Promise<SymbolInfo[]>;
144
+ /** Compile a symbol query for a code sample (used by tests). */
145
+ declare function parseFileToSymbols(filePath: string, repoRoot: string, code?: string): Promise<SymbolInfo[]>;
146
+
147
+ /** Workspace file discovery with dir exclusions and mtime tracking. */
148
+
149
+ declare const DEFAULT_EXCLUDED_DIRS: string[];
150
+ /** Language-agnostic source extensions we index. */
151
+ declare const SUPPORTED_EXTS: Set<string>;
152
+ interface ScannedFile {
153
+ /** Absolute path on disk. */
154
+ abs: string;
155
+ /** Repo-relative path (forward-slash). */
156
+ rel: string;
157
+ mtimeMs: number;
158
+ }
159
+ /**
160
+ * Recursively walk `root` and return indexed files, skipping excluded dir
161
+ * components at any depth. Uses readdir with `withFileTypes` so we never
162
+ * stat every entry; mtime comes from a targeted stat per candidate file.
163
+ */
164
+ declare function scanRepo(root: string, options?: IndexOptions): Promise<ScannedFile[]>;
165
+
166
+ /** On-disk JSON cache for RepoIndex, keyed by repo root. */
167
+
168
+ declare const CACHE_DIR_NAME = ".dsh-code-index";
169
+ /** Default cache location: `<repoRoot>/.dsh-code-index/index.json`. */
170
+ declare function defaultCachePath(root: string, cacheDir?: string): string;
171
+ declare function loadIndex(cachePath: string): Promise<RepoIndex | null>;
172
+ declare function saveIndex(cachePath: string, index: RepoIndex): Promise<void>;
173
+
174
+ /** Pure search / filter logic over a RepoIndex — unit-testable, no IO. */
175
+
176
+ interface SymbolFilter {
177
+ query?: string;
178
+ file?: string;
179
+ kind?: SymbolKind;
180
+ exportedOnly?: boolean;
181
+ }
182
+ interface RankedHit extends SymbolInfo {
183
+ /** 0..1 relevance. 1 = exact name match; lower = fuzzier. */
184
+ score: number;
185
+ }
186
+ /** Filter symbols by file/kind/export, then score by name against query (if any). */
187
+ declare function searchSymbols(index: RepoIndex, filter: SymbolFilter, limit?: number, refs?: Map<string, number>): RankedHit[];
188
+ /** Neat one-line rendering of a hit for terminal/chat output. */
189
+ declare function renderHit(hit: RankedHit): string;
190
+
191
+ /**
192
+ * Bounded, ranked repo map generation — the "aider-style" overview the model
193
+ * can turn to before browsing files. Pure logic, no IO.
194
+ */
195
+
196
+ interface RepoMapOptions {
197
+ /** Max files to include (default 24). */
198
+ topFiles?: number;
199
+ /** Max symbols per file (default 18). */
200
+ symbolsPerFile?: number;
201
+ /** Hard cap on rendered characters (default 3200). */
202
+ maxChars?: number;
203
+ }
204
+ interface RepoMapEntry {
205
+ path: string;
206
+ score: number;
207
+ symbols: Array<{
208
+ name: string;
209
+ kind: SymbolKind;
210
+ line: number;
211
+ signature: string;
212
+ }>;
213
+ }
214
+ /** Density-aware file score: weighted symbols minus bloat; test paths damped. */
215
+ declare function scoreFile(file: IndexedFile): number;
216
+ /** Rank files, take the top slice, cap per-file symbols. */
217
+ declare function rankRepoMap(index: RepoIndex, options?: RepoMapOptions): RepoMapEntry[];
218
+ /** Render the ranked map as markdown, hard-truncated to maxChars. */
219
+ declare function renderRepoMap(entries: RepoMapEntry[], options?: RepoMapOptions): string;
220
+
221
+ /** Function-level call graph built from the cached index — pure, no IO. */
222
+
223
+ /** name -> definitions; several when same-named symbols live in different files. */
224
+ declare function buildSymbolTable(index: RepoIndex): Map<string, SymbolInfo[]>;
225
+ /** One call site that invokes the queried symbol. */
226
+ interface CallerHit {
227
+ file: string;
228
+ line: number;
229
+ from: string;
230
+ }
231
+ /** One distinct symbol the queried function calls, with its first call line. */
232
+ interface CalleeHit {
233
+ name: string;
234
+ line: number;
235
+ /** In-repo definitions matched by the callee name. */
236
+ targets: SymbolInfo[];
237
+ }
238
+ interface SymbolRefs {
239
+ /** Definitions of the queried symbol (empty when only call sites exist). */
240
+ defs: SymbolInfo[];
241
+ callers: CallerHit[];
242
+ callees: CalleeHit[];
243
+ }
244
+ /** How many call sites reference each name — used to rank search hits. */
245
+ declare function callerCounts(index: RepoIndex): Map<string, number>;
246
+ /**
247
+ * Resolve one symbol to its callers (call sites invoking it anywhere) and its
248
+ * callees (calls made inside the definition, attributed by the extracted
249
+ * enclosing-function name). Name-based, so it is a best-effort view: like-named
250
+ * symbols are reported as candidates rather than guessed apart.
251
+ */
252
+ declare function symbolRefs(index: RepoIndex, symbol: string, limit?: number): SymbolRefs;
253
+ /**
254
+ * How sure the graph is about one resolved edge. Deliberately coarse: the
255
+ * index has no type checker, so `exact` only ever means "one structurally
256
+ * unambiguous target under this index's model".
257
+ */
258
+ type ResolutionLabel = 'exact' | 'import-scoped' | 'name-only';
259
+ /** Which resolution tier produced an edge — the *why* behind its label. */
260
+ type ResolutionProvenance = 'structural-owner' | 'local-unique' | 'explicit-import-binding' | 'namespace-import' | 'resolved-import-module' | 'global-name';
261
+
262
+ /** Import-graph health checks: circular dependencies and orphan modules. */
263
+
264
+ interface ModuleGraph {
265
+ nodes: string[];
266
+ edges: Map<string, Set<string>>;
267
+ }
268
+ /** Nodes are indexed files; an edge A -> B means A imports B (self-edges dropped). */
269
+ declare function buildModuleGraph(index: RepoIndex): ModuleGraph;
270
+ /** Tarjan strongly-connected components of size > 1 — i.e. import cycles. */
271
+ declare function findCycles(index: RepoIndex): string[][];
272
+ /**
273
+ * Symbol-bearing files that neither import nor are imported by any other file,
274
+ * excluding conventional entry points and tests (which are legitimately
275
+ * unreferenced). A cheap, low-false-positive stand-in for dead-code detection.
276
+ */
277
+ declare function findOrphanModules(index: RepoIndex): string[];
278
+
279
+ /**
280
+ * Unified-diff parsing and a thin `git` adapter.
281
+ *
282
+ * `parseUnifiedDiff` is pure (no IO) so it is unit-testable in isolation; the
283
+ * two readers shell out to `git` exclusively through `execFile` with an argv
284
+ * array — a ref or path is never interpolated into a shell string.
285
+ */
286
+ /** One `@@` hunk header; a missing count means 1 (git omits `,1`). */
287
+ interface DiffHunk {
288
+ oldStart: number;
289
+ oldLines: number;
290
+ newStart: number;
291
+ newLines: number;
292
+ }
293
+ /** One file's entry in a unified diff. */
294
+ interface FileChange {
295
+ /** Repo-relative path on the base side, or null for an added file. */
296
+ oldPath: string | null;
297
+ /** Repo-relative path on the current side, or null for a deleted file. */
298
+ newPath: string | null;
299
+ status: 'added' | 'modified' | 'deleted' | 'renamed';
300
+ hunks: DiffHunk[];
301
+ }
302
+ /**
303
+ * Parse `git diff` / `diff -u` output into per-file changes. Handles
304
+ * `diff --git`, `new file mode`, `deleted file mode`, `rename from/to`,
305
+ * `---`/`+++` (including `/dev/null`), and `@@` headers with omitted counts.
306
+ */
307
+ declare function parseUnifiedDiff(text: string): FileChange[];
308
+ /**
309
+ * Working-tree diff against `baseRef`, rename-aware and hunk-minimal.
310
+ * Includes non-ignored untracked files and reliable exact-content renames.
311
+ */
312
+ declare function readWorkingTreeDiff(root: string, baseRef: string): Promise<string>;
313
+ /** Read one repo-relative file at a ref; null when the path/ref is absent. */
314
+ declare function readGitFileAtRef(root: string, ref: string, repoRelativePath: string): Promise<string | null>;
315
+
316
+ /**
317
+ * Change-aware context (design §3): map a git/working-tree diff (or an explicit
318
+ * file/symbol selection) onto indexed symbols, then walk the provenance-labeled
319
+ * reference graph to surface callers, import dependents, transitive impact,
320
+ * entry-point paths, and likely affected tests.
321
+ *
322
+ * Every relation keeps the reference graph's honest label (`exact` /
323
+ * `import-scoped` / `name-only`); a diff hunk intersecting a symbol's declared
324
+ * line range is the only thing treated as `exact`.
325
+ */
326
+
327
+ type ChangeKind = 'added' | 'modified' | 'deleted' | 'renamed' | 'unclassified';
328
+ interface ChangedSymbol {
329
+ symbol: SymbolInfo;
330
+ change: ChangeKind;
331
+ side: 'current' | 'base';
332
+ /** A hunk range intersecting the declaration is structural, not inferred. */
333
+ resolution: 'exact';
334
+ /** First intersecting changed line, used for large-declaration windows. */
335
+ focusLine?: number;
336
+ }
337
+ interface UnmappedChange {
338
+ file: string;
339
+ side: 'current' | 'base';
340
+ ranges: Array<{
341
+ startLine: number;
342
+ endLine: number;
343
+ }>;
344
+ reason: 'outside-symbol' | 'base-content-unavailable';
345
+ }
346
+ interface ImpactHop {
347
+ fromId: SymbolId | null;
348
+ toId: SymbolId;
349
+ callSite: {
350
+ file: string;
351
+ line: number;
352
+ };
353
+ resolution: ResolutionLabel;
354
+ reason: ResolutionProvenance;
355
+ }
356
+ interface ImpactRow {
357
+ symbol: SymbolInfo;
358
+ depth: number;
359
+ via: ImpactHop;
360
+ resolution: ResolutionLabel;
361
+ }
362
+ interface SymbolPath {
363
+ entry: SymbolInfo;
364
+ changed: SymbolInfo;
365
+ hops: ImpactHop[];
366
+ resolution: ResolutionLabel;
367
+ }
368
+ interface ImportDependent {
369
+ file: string;
370
+ changedFile: string;
371
+ specifier: string;
372
+ resolution: 'import-scoped';
373
+ }
374
+ interface AffectedTest {
375
+ file: string;
376
+ resolution: ResolutionLabel;
377
+ reason: 'changed-test' | 'imports-changed-file' | 'imports-impact-file' | 'references-symbol-name' | 'path-convention';
378
+ distance?: number;
379
+ }
380
+ interface ChangeContextResult {
381
+ root: string;
382
+ source: 'git' | 'diff' | 'files' | 'symbols';
383
+ baseRef?: string;
384
+ changed: ChangedSymbol[];
385
+ unmapped: UnmappedChange[];
386
+ directCallers: ImpactRow[];
387
+ importDependents: ImportDependent[];
388
+ paths: SymbolPath[];
389
+ impact: ImpactRow[];
390
+ tests: AffectedTest[];
391
+ warnings: string[];
392
+ truncated: {
393
+ callers: boolean;
394
+ dependents: boolean;
395
+ paths: boolean;
396
+ impact: boolean;
397
+ tests: boolean;
398
+ };
399
+ }
400
+ interface CodeChangeContextArgs {
401
+ repoRoot?: string;
402
+ diff?: string;
403
+ baseRef?: string;
404
+ files?: string[];
405
+ symbols?: SymbolId[];
406
+ maxDepth?: number;
407
+ maxImpact?: number;
408
+ maxPaths?: number;
409
+ maxTests?: number;
410
+ }
411
+ interface ChangeContextOptions {
412
+ maxDepth?: number;
413
+ maxImpact?: number;
414
+ maxPaths?: number;
415
+ maxTests?: number;
416
+ }
417
+ /** Normalized input: exactly one selection mode. */
418
+ type ChangeContextInput = {
419
+ kind: 'git';
420
+ root: string;
421
+ baseRef: string;
422
+ } | {
423
+ kind: 'diff';
424
+ root: string;
425
+ text: string;
426
+ baseRef?: string;
427
+ } | {
428
+ kind: 'files';
429
+ files: string[];
430
+ } | {
431
+ kind: 'symbols';
432
+ symbolIds: SymbolId[];
433
+ };
434
+ /** Validate flat tool args and normalize them into one input mode. */
435
+ declare function changeContextInputFromArgs(args: Pick<CodeChangeContextArgs, 'diff' | 'baseRef' | 'files' | 'symbols'>, root: string): ChangeContextInput;
436
+ declare function buildChangeContext(index: RepoIndex, input: ChangeContextInput, options?: ChangeContextOptions): Promise<ChangeContextResult>;
437
+ /**
438
+ * Render the result as fixed skeleton sections. Section headers and warnings
439
+ * are always kept; rows are trimmed to the final character cap, which then
440
+ * appends an explicit truncation line.
441
+ */
442
+ declare function renderChangeContext(result: ChangeContextResult, maxChars?: number): string;
443
+
444
+ interface SourceExcerpt {
445
+ file: string;
446
+ startLine: number;
447
+ endLine: number;
448
+ side: 'current' | 'base';
449
+ ref?: string;
450
+ mode: 'complete' | 'window' | 'signature';
451
+ code?: string;
452
+ signature?: string;
453
+ }
454
+
455
+ interface ContextPackItem extends Partial<SourceExcerpt> {
456
+ kind: 'primary' | 'caller' | 'callee' | 'import' | 'test' | 'change' | 'file' | 'relationship';
457
+ name?: string;
458
+ reason: string;
459
+ resolution?: ResolutionLabel;
460
+ provenance?: string;
461
+ change?: string;
462
+ text?: string;
463
+ }
464
+ /** The only final presentation DTO. Items here have already passed selection. */
465
+ interface ContextPack {
466
+ version: 1;
467
+ root: string;
468
+ task: string;
469
+ route: TaskContextResult['route']['kind'];
470
+ items: ContextPackItem[];
471
+ gaps: string[];
472
+ budget: {
473
+ budgetChars: number;
474
+ usedChars: number;
475
+ packChars: number;
476
+ truncated: boolean;
477
+ };
478
+ }
479
+ declare function renderContextPack(pack: ContextPack): string;
480
+
481
+ /**
482
+ * Task-aware structural context orchestration.
483
+ *
484
+ * This module deliberately contains no parser, search index, graph, or git
485
+ * implementation of its own. It ranks the existing primitives into a compact
486
+ * package that answers the question: which code matters for this task?
487
+ */
488
+
489
+ type ContextTaskKind = 'change' | 'symbol' | 'architecture' | 'test' | 'exploration' | 'ambiguous';
490
+ interface ContextRoute {
491
+ kind: ContextTaskKind;
492
+ queries: string[];
493
+ mentionedFiles: string[];
494
+ exactSymbolNames: string[];
495
+ sources: string[];
496
+ includeChangeContext: boolean;
497
+ includeRelationships: boolean;
498
+ }
499
+ interface ContextOptions {
500
+ budgetChars?: number;
501
+ maxFiles?: number;
502
+ maxSymbols?: number;
503
+ }
504
+ interface ContextSymbol {
505
+ symbol: SymbolInfo;
506
+ score: number;
507
+ provenance: 'exact' | 'lexical';
508
+ reason: string;
509
+ }
510
+ interface ContextFile {
511
+ path: string;
512
+ score: number;
513
+ reason: string;
514
+ }
515
+ interface ContextRelationship {
516
+ text: string;
517
+ resolution: ResolutionLabel;
518
+ priority: number;
519
+ key: string;
520
+ provenance: string;
521
+ }
522
+ interface ContextConfidence {
523
+ exact: number;
524
+ 'import-scoped': number;
525
+ 'name-only': number;
526
+ }
527
+ interface TaskContextResult {
528
+ pack: ContextPack;
529
+ root: string;
530
+ task: string;
531
+ route: ContextRoute;
532
+ primarySymbols: ContextSymbol[];
533
+ relevantFiles: ContextFile[];
534
+ relationships: ContextRelationship[];
535
+ changeContext: ChangeContextResult | null;
536
+ tests: string[];
537
+ testEvidence: AffectedTest[];
538
+ confidence: ContextConfidence;
539
+ warnings: string[];
540
+ budget: {
541
+ usedChars: number;
542
+ budgetChars: number;
543
+ truncated: boolean;
544
+ };
545
+ }
546
+ /** Classify a task and decide which existing primitives should be composed. */
547
+ declare function routeTask(task: string, index?: RepoIndex): ContextRoute;
548
+ /** Build a deterministic, bounded context package from the current task. */
549
+ declare function buildTaskContext(index: RepoIndex, task: string, options?: ContextOptions): Promise<TaskContextResult>;
550
+ /** Text always renders the final selected pack. */
551
+ declare function renderTaskContext(result: TaskContextResult): string;
552
+
553
+ declare const tools: _deepseek_ai_dsh_tools.ToolDefinition[];
554
+
555
+ /** Plugin configuration: merged once at apply time, read wherever needed. */
556
+
557
+ /** DSH 0.1.7+ renders fields marked volatile in its per-plugin config forms. */
558
+ declare const Config: Schema<Schemastery.ObjectS<NoInfer<{
559
+ excludeDirs: Schema<NoInfer<string[]>, NoInfer<string[]>, "volatile-defined">;
560
+ mapTopFiles: Schema<number, number, "volatile-defined">;
561
+ mapMaxChars: Schema<number, number, "volatile-defined">;
562
+ mapTtlMs: Schema<number, number, "volatile-defined">;
563
+ autoInject: Schema<boolean, boolean, "volatile-defined">;
564
+ codeHealth: Schema<boolean, boolean, "volatile-defined">;
565
+ toolSurface: Schema<string, string, "volatile-defined">;
566
+ externalWatch: Schema<boolean, boolean, "volatile-defined">;
567
+ watchDebounceMs: Schema<number, number, "volatile-defined">;
568
+ }>>, Schemastery.ObjectT<NoInfer<{
569
+ excludeDirs: Schema<NoInfer<string[]>, NoInfer<string[]>, "volatile-defined">;
570
+ mapTopFiles: Schema<number, number, "volatile-defined">;
571
+ mapMaxChars: Schema<number, number, "volatile-defined">;
572
+ mapTtlMs: Schema<number, number, "volatile-defined">;
573
+ autoInject: Schema<boolean, boolean, "volatile-defined">;
574
+ codeHealth: Schema<boolean, boolean, "volatile-defined">;
575
+ toolSurface: Schema<string, string, "volatile-defined">;
576
+ externalWatch: Schema<boolean, boolean, "volatile-defined">;
577
+ watchDebounceMs: Schema<number, number, "volatile-defined">;
578
+ }>>, "plain">;
579
+ interface PluginConfig {
580
+ /** Extra directories to exclude from indexing (appended to defaults). */
581
+ excludeDirs?: string[];
582
+ /** Max files in the ranked repo map (code_map / auto section). */
583
+ mapTopFiles?: number;
584
+ /** Hard char cap for rendered maps. */
585
+ mapMaxChars?: number;
586
+ /** Refresh interval for the auto-injected map (ms, min 1000). */
587
+ mapTtlMs?: number;
588
+ /** Set false to disable the auto-injected system section. */
589
+ autoInject?: boolean;
590
+ /** Register the code_health tool (circles / orphans). Off by default. */
591
+ codeHealth?: boolean;
592
+ /** Experimental tool surface; full preserves the complete v0.6 API. */
593
+ toolSurface?: 'full' | 'compact';
594
+ /** Observe source changes made by editors and external tools. */
595
+ externalWatch?: boolean;
596
+ /** Coalesce filesystem events before refreshing affected files. */
597
+ watchDebounceMs?: number;
598
+ }
599
+
600
+ /**
601
+ * dsh-code-index — DeepSeek Harness bundle entry.
602
+ *
603
+ * Registers model-visible tools (code_index / code_symbols / code_search /
604
+ * code_map / code_refs / code_change_context / code_context) plus an opt-in code_health
605
+ * (config.codeHealth) backed by a tree-sitter symbol + call-graph index,
606
+ * and injects a bounded auto-updating repo map for the default workspace
607
+ * into the system prompt.
608
+ */
609
+ type Disposer = void | (() => void);
610
+ /** Minimal structural Context; the real @deepseek-ai/cordis type is a
611
+ * runtime dependency we intentionally do not import in the bundle entry. */
612
+ interface MinimalContext {
613
+ effect(fn: () => Disposer): void;
614
+ tools: {
615
+ register(t: unknown): () => void;
616
+ };
617
+ get?(name: string): unknown;
618
+ inject?(deps: string[], run: (ctx: MinimalContext) => void): unknown;
619
+ on?(event: string, listener: () => void): () => void;
620
+ fiber?: unknown;
621
+ systemPrompt: {
622
+ section(section: {
623
+ name: string;
624
+ order: number;
625
+ text: string | ((context: unknown) => string);
626
+ }): () => void;
627
+ };
628
+ }
629
+ declare const name = "dsh-code-index";
630
+
631
+ declare const inject: readonly ["tools", "systemPrompt"];
632
+ declare function apply(ctx: MinimalContext, pluginConfig?: PluginConfig): void;
633
+
634
+ export { type AffectedTest, CACHE_DIR_NAME, type ChangeContextInput, type ChangeContextOptions, type ChangeContextResult, type ChangeKind, type ChangedSymbol, type CodeChangeContextArgs, Config, type ContextFile, type ContextOptions, type ContextPack, type ContextPackItem, type ContextRelationship, type ContextRoute, type ContextSymbol, type ContextTaskKind, DEFAULT_EXCLUDED_DIRS, type DiffHunk, type FileChange, type ImpactHop, type ImpactRow, type ImportDependent, type IndexOptions, type IndexedFile, type RepoIndex, SUPPORTED_EXTS, type SymbolInfo, type SymbolKind, type SymbolPath, type TaskContextResult, type UnmappedChange, apply, buildChangeContext, buildIndex, buildIndexWithCache, buildModuleGraph, buildSymbolTable, buildTaskContext, callerCounts, changeContextInputFromArgs, defaultCachePath, extractAll, extractSymbols, findCycles, findOrphanModules, findRepoRoot, inject, languageForFile, loadIndex, name, parseFileToSymbols, parseUnifiedDiff, rankRepoMap, readGitFileAtRef, readWorkingTreeDiff, renderChangeContext, renderContextPack, renderHit, renderRepoMap, renderTaskContext, routeTask, saveIndex, scanRepo, scoreFile, searchSymbols, symbolCount, symbolRefs, tools };