@code-rag/mcp-server 0.1.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,110 @@
1
+ import { z } from 'zod';
2
+ import { TokenBudgetOptimizer, } from '@code-rag/core';
3
+ export const contextInputSchema = z.object({
4
+ file_path: z.string().min(1, 'file_path must not be empty').refine((s) => !s.includes('..'), 'file_path must not contain path traversal'),
5
+ include_tests: z.boolean().optional().default(true),
6
+ include_interfaces: z.boolean().optional().default(true),
7
+ max_tokens: z.number().int().positive().max(128000).optional().default(8000),
8
+ });
9
+ export async function handleContext(args, hybridSearch, contextExpander) {
10
+ const parsed = contextInputSchema.safeParse(args);
11
+ if (!parsed.success) {
12
+ return {
13
+ content: [
14
+ {
15
+ type: 'text',
16
+ text: JSON.stringify({
17
+ error: 'Invalid input',
18
+ details: parsed.error.issues,
19
+ }),
20
+ },
21
+ ],
22
+ };
23
+ }
24
+ if (!hybridSearch || !contextExpander) {
25
+ return {
26
+ content: [
27
+ {
28
+ type: 'text',
29
+ text: JSON.stringify({
30
+ context: '',
31
+ message: 'Services not initialized. Run indexing first.',
32
+ }),
33
+ },
34
+ ],
35
+ };
36
+ }
37
+ const { file_path, max_tokens } = parsed.data;
38
+ try {
39
+ // Step 1: Search for chunks matching the file_path
40
+ const searchResult = await hybridSearch.search(file_path, { topK: 20 });
41
+ if (searchResult.isErr()) {
42
+ return {
43
+ content: [
44
+ {
45
+ type: 'text',
46
+ text: JSON.stringify({
47
+ error: 'Search failed',
48
+ message: searchResult.error.message,
49
+ }),
50
+ },
51
+ ],
52
+ };
53
+ }
54
+ // Filter to results that match the file path
55
+ let results = searchResult.value.filter((r) => r.chunk?.filePath?.includes(file_path));
56
+ // Apply optional filters for tests and interfaces
57
+ if (!parsed.data.include_tests) {
58
+ results = results.filter((r) => !r.chunk?.filePath?.includes('.test.') &&
59
+ !r.chunk?.filePath?.includes('.spec.') &&
60
+ !r.chunk?.filePath?.includes('__tests__'));
61
+ }
62
+ if (!parsed.data.include_interfaces) {
63
+ results = results.filter((r) => r.metadata?.chunkType !== 'interface' &&
64
+ r.metadata?.chunkType !== 'type_alias');
65
+ }
66
+ if (results.length === 0) {
67
+ return {
68
+ content: [
69
+ {
70
+ type: 'text',
71
+ text: JSON.stringify({
72
+ context: '',
73
+ message: `No chunks found for file: ${file_path}`,
74
+ }),
75
+ },
76
+ ],
77
+ };
78
+ }
79
+ // Step 2: Expand context via dependency graph
80
+ const expanded = contextExpander.expand(results);
81
+ // Step 3: Assemble within token budget (use caller's max_tokens)
82
+ const optimizer = new TokenBudgetOptimizer({ maxTokens: max_tokens });
83
+ const assembled = optimizer.assemble(expanded);
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: JSON.stringify({
89
+ context: assembled.content,
90
+ token_count: assembled.tokenCount,
91
+ truncated: assembled.truncated,
92
+ primary_chunks: assembled.primaryChunks.length,
93
+ related_chunks: assembled.relatedChunks.length,
94
+ }),
95
+ },
96
+ ],
97
+ };
98
+ }
99
+ catch (error) {
100
+ const message = error instanceof Error ? error.message : 'Unknown error';
101
+ return {
102
+ content: [
103
+ {
104
+ type: 'text',
105
+ text: JSON.stringify({ error: 'Context assembly failed', message }),
106
+ },
107
+ ],
108
+ };
109
+ }
110
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tools/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+ import type { HybridSearch, ReRanker } from '@code-rag/core';
3
+ export declare const docsInputSchema: z.ZodObject<{
4
+ query: z.ZodString;
5
+ source: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
6
+ markdown: "markdown";
7
+ confluence: "confluence";
8
+ all: "all";
9
+ }>>>;
10
+ file_path: z.ZodOptional<z.ZodString>;
11
+ top_k: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
12
+ }, z.core.$strip>;
13
+ export type DocsInput = z.infer<typeof docsInputSchema>;
14
+ export interface DocsToolResult {
15
+ file_path: string;
16
+ heading: string;
17
+ content: string;
18
+ nl_summary: string;
19
+ score: number;
20
+ source: 'markdown' | 'confluence' | 'unknown';
21
+ }
22
+ export declare function handleDocs(args: Record<string, unknown>, hybridSearch: HybridSearch | null, reranker?: ReRanker | null): Promise<{
23
+ content: Array<{
24
+ type: 'text';
25
+ text: string;
26
+ }>;
27
+ }>;
@@ -0,0 +1,111 @@
1
+ import { z } from 'zod';
2
+ export const docsInputSchema = z.object({
3
+ query: z.string().min(1, 'query must not be empty'),
4
+ source: z.enum(['markdown', 'confluence', 'all']).optional().default('all'),
5
+ file_path: z.string().refine((s) => !s.includes('..'), 'file_path must not contain path traversal').optional(),
6
+ top_k: z.number().int().positive().max(100).optional().default(10),
7
+ });
8
+ function inferSource(filePath) {
9
+ if (filePath.endsWith('.md') || filePath.endsWith('.mdx')) {
10
+ return 'markdown';
11
+ }
12
+ if (filePath.startsWith('confluence://') || filePath.includes('/confluence/')) {
13
+ return 'confluence';
14
+ }
15
+ return 'unknown';
16
+ }
17
+ function formatDocResult(result) {
18
+ const filePath = result.chunk?.filePath ?? '';
19
+ return {
20
+ file_path: filePath,
21
+ heading: result.metadata?.docTitle ?? result.metadata?.name ?? '',
22
+ content: result.content,
23
+ nl_summary: result.nlSummary,
24
+ score: result.score,
25
+ source: inferSource(filePath),
26
+ };
27
+ }
28
+ export async function handleDocs(args, hybridSearch, reranker = null) {
29
+ const parsed = docsInputSchema.safeParse(args);
30
+ if (!parsed.success) {
31
+ return {
32
+ content: [
33
+ {
34
+ type: 'text',
35
+ text: JSON.stringify({
36
+ error: 'Invalid input',
37
+ details: parsed.error.issues,
38
+ }),
39
+ },
40
+ ],
41
+ };
42
+ }
43
+ if (!hybridSearch) {
44
+ return {
45
+ content: [
46
+ {
47
+ type: 'text',
48
+ text: JSON.stringify({
49
+ results: [],
50
+ message: 'Search index not initialized. Run indexing first.',
51
+ }),
52
+ },
53
+ ],
54
+ };
55
+ }
56
+ const { query, source, file_path, top_k } = parsed.data;
57
+ try {
58
+ const searchResult = await hybridSearch.search(query, { topK: top_k });
59
+ if (searchResult.isErr()) {
60
+ return {
61
+ content: [
62
+ {
63
+ type: 'text',
64
+ text: JSON.stringify({
65
+ error: 'Search failed',
66
+ message: searchResult.error.message,
67
+ }),
68
+ },
69
+ ],
70
+ };
71
+ }
72
+ let results = searchResult.value;
73
+ // Filter to doc chunks only
74
+ results = results.filter((r) => r.metadata?.chunkType === 'doc');
75
+ // Filter by source type
76
+ if (source !== 'all') {
77
+ results = results.filter((r) => {
78
+ const filePath = r.chunk?.filePath ?? '';
79
+ const detectedSource = inferSource(filePath);
80
+ return detectedSource === source;
81
+ });
82
+ }
83
+ // Filter by file path
84
+ if (file_path) {
85
+ results = results.filter((r) => r.chunk?.filePath?.includes(file_path));
86
+ }
87
+ // Re-rank results if reranker is available
88
+ if (reranker && results.length > 0) {
89
+ const rerankResult = await reranker.rerank(query, results);
90
+ if (rerankResult.isOk()) {
91
+ results = rerankResult.value;
92
+ }
93
+ // If reranking fails, fall back to original results (don't fail the search)
94
+ }
95
+ const formatted = results.map(formatDocResult);
96
+ return {
97
+ content: [{ type: 'text', text: JSON.stringify({ results: formatted }) }],
98
+ };
99
+ }
100
+ catch (error) {
101
+ const message = error instanceof Error ? error.message : 'Unknown error';
102
+ return {
103
+ content: [
104
+ {
105
+ type: 'text',
106
+ text: JSON.stringify({ error: 'Docs search failed', message }),
107
+ },
108
+ ],
109
+ };
110
+ }
111
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/tools/docs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,yBAAyB,CAAC;IACnD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAC1B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EACxB,2CAA2C,CAC5C,CAAC,QAAQ,EAAE;IACZ,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;CACnE,CAAC,CAAC;AAaH,SAAS,WAAW,CAAC,QAAgB;IACnC,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QAC9E,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,MAAoB;IAC3C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC;IAC9C,OAAO;QACL,SAAS,EAAE,QAAQ;QACnB,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,IAAI,MAAM,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE;QACjE,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,SAAS;QAC5B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAA6B,EAC7B,YAAiC,EACjC,WAA4B,IAAI;IAEhC,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK,EAAE,eAAe;wBACtB,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM;qBAC7B,CAAC;iBACH;aACF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,OAAO,EAAE,EAAE;wBACX,OAAO,EAAE,mDAAmD;qBAC7D,CAAC;iBACH;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAExD,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAEvE,IAAI,YAAY,CAAC,KAAK,EAAE,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,KAAK,EAAE,eAAe;4BACtB,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,OAAO;yBACpC,CAAC;qBACH;iBACF;aACF,CAAC;QACJ,CAAC;QAED,IAAI,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC;QAEjC,4BAA4B;QAC5B,OAAO,GAAG,OAAO,CAAC,MAAM,CACtB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,KAAK,KAAK,CACvC,CAAC;QAEF,wBAAwB;QACxB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC7B,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,EAAE,QAAQ,IAAI,EAAE,CAAC;gBACzC,MAAM,cAAc,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC7C,OAAO,cAAc,KAAK,MAAM,CAAC;YACnC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,sBAAsB;QACtB,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,GAAG,OAAO,CAAC,MAAM,CACtB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,CAC9C,CAAC;QACJ,CAAC;QAED,2CAA2C;QAC3C,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnC,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC3D,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;gBACxB,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC;YAC/B,CAAC;YACD,4EAA4E;QAC9E,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAE/C,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;SAC1E,CAAC;IACJ,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,CAAC;iBAC/D;aACF;SACF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,357 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { ok, err } from 'neverthrow';
3
+ import { handleDocs, docsInputSchema } from './docs.js';
4
+ import { EmbedError } from '@coderag/core';
5
+ // --- Helpers ---
6
+ function makeDocResult(overrides = {}) {
7
+ return {
8
+ chunkId: 'doc-chunk-1',
9
+ content: '## Getting Started\n\nInstall with `pnpm install`.',
10
+ nlSummary: 'Instructions for getting started with the project',
11
+ score: 0.9,
12
+ method: 'hybrid',
13
+ metadata: {
14
+ chunkType: 'doc',
15
+ name: 'Getting Started',
16
+ declarations: [],
17
+ imports: [],
18
+ exports: [],
19
+ docTitle: 'Getting Started',
20
+ },
21
+ chunk: {
22
+ id: 'doc-chunk-1',
23
+ content: '## Getting Started\n\nInstall with `pnpm install`.',
24
+ nlSummary: 'Instructions for getting started with the project',
25
+ filePath: 'docs/README.md',
26
+ startLine: 1,
27
+ endLine: 5,
28
+ language: 'markdown',
29
+ metadata: {
30
+ chunkType: 'doc',
31
+ name: 'Getting Started',
32
+ declarations: [],
33
+ imports: [],
34
+ exports: [],
35
+ docTitle: 'Getting Started',
36
+ },
37
+ },
38
+ ...overrides,
39
+ };
40
+ }
41
+ function makeConfluenceResult(overrides = {}) {
42
+ return {
43
+ chunkId: 'confluence-chunk-1',
44
+ content: '# API Reference\n\nEndpoint documentation.',
45
+ nlSummary: 'API reference documentation from Confluence',
46
+ score: 0.85,
47
+ method: 'hybrid',
48
+ metadata: {
49
+ chunkType: 'doc',
50
+ name: 'API Reference',
51
+ declarations: [],
52
+ imports: [],
53
+ exports: [],
54
+ docTitle: 'API Reference',
55
+ },
56
+ chunk: {
57
+ id: 'confluence-chunk-1',
58
+ content: '# API Reference\n\nEndpoint documentation.',
59
+ nlSummary: 'API reference documentation from Confluence',
60
+ filePath: 'confluence://spaces/DEV/pages/12345',
61
+ startLine: 1,
62
+ endLine: 3,
63
+ language: 'markdown',
64
+ metadata: {
65
+ chunkType: 'doc',
66
+ name: 'API Reference',
67
+ declarations: [],
68
+ imports: [],
69
+ exports: [],
70
+ docTitle: 'API Reference',
71
+ },
72
+ },
73
+ ...overrides,
74
+ };
75
+ }
76
+ function makeCodeResult() {
77
+ return {
78
+ chunkId: 'code-chunk-1',
79
+ content: 'function hello() {}',
80
+ nlSummary: 'A greeting function',
81
+ score: 0.8,
82
+ method: 'hybrid',
83
+ metadata: {
84
+ chunkType: 'function',
85
+ name: 'hello',
86
+ declarations: [],
87
+ imports: [],
88
+ exports: [],
89
+ },
90
+ chunk: {
91
+ id: 'code-chunk-1',
92
+ content: 'function hello() {}',
93
+ nlSummary: 'A greeting function',
94
+ filePath: 'src/hello.ts',
95
+ startLine: 1,
96
+ endLine: 1,
97
+ language: 'typescript',
98
+ metadata: {
99
+ chunkType: 'function',
100
+ name: 'hello',
101
+ declarations: [],
102
+ imports: [],
103
+ exports: [],
104
+ },
105
+ },
106
+ };
107
+ }
108
+ function parseResponse(response) {
109
+ return JSON.parse(response.content[0].text);
110
+ }
111
+ // --- Input Schema Validation ---
112
+ describe('docsInputSchema', () => {
113
+ it('should accept valid input with just query', () => {
114
+ const result = docsInputSchema.safeParse({ query: 'getting started' });
115
+ expect(result.success).toBe(true);
116
+ });
117
+ it('should reject empty query', () => {
118
+ const result = docsInputSchema.safeParse({ query: '' });
119
+ expect(result.success).toBe(false);
120
+ });
121
+ it('should reject missing query', () => {
122
+ const result = docsInputSchema.safeParse({});
123
+ expect(result.success).toBe(false);
124
+ });
125
+ it('should apply default source of all', () => {
126
+ const result = docsInputSchema.parse({ query: 'test' });
127
+ expect(result.source).toBe('all');
128
+ });
129
+ it('should accept markdown source', () => {
130
+ const result = docsInputSchema.parse({ query: 'test', source: 'markdown' });
131
+ expect(result.source).toBe('markdown');
132
+ });
133
+ it('should accept confluence source', () => {
134
+ const result = docsInputSchema.parse({ query: 'test', source: 'confluence' });
135
+ expect(result.source).toBe('confluence');
136
+ });
137
+ it('should reject invalid source', () => {
138
+ const result = docsInputSchema.safeParse({ query: 'test', source: 'wiki' });
139
+ expect(result.success).toBe(false);
140
+ });
141
+ it('should reject file_path with path traversal', () => {
142
+ const result = docsInputSchema.safeParse({ query: 'test', file_path: '../../etc/passwd' });
143
+ expect(result.success).toBe(false);
144
+ });
145
+ it('should accept valid file_path', () => {
146
+ const result = docsInputSchema.safeParse({ query: 'test', file_path: 'docs/guide.md' });
147
+ expect(result.success).toBe(true);
148
+ });
149
+ it('should apply default top_k of 10', () => {
150
+ const result = docsInputSchema.parse({ query: 'test' });
151
+ expect(result.top_k).toBe(10);
152
+ });
153
+ it('should reject top_k greater than 100', () => {
154
+ const result = docsInputSchema.safeParse({ query: 'test', top_k: 101 });
155
+ expect(result.success).toBe(false);
156
+ });
157
+ it('should reject non-positive top_k', () => {
158
+ const result = docsInputSchema.safeParse({ query: 'test', top_k: 0 });
159
+ expect(result.success).toBe(false);
160
+ });
161
+ });
162
+ // --- Handler Tests ---
163
+ describe('handleDocs', () => {
164
+ let mockHybridSearch;
165
+ let mockReranker;
166
+ beforeEach(() => {
167
+ mockHybridSearch = {
168
+ search: vi.fn(),
169
+ };
170
+ mockReranker = {
171
+ rerank: vi.fn(),
172
+ };
173
+ });
174
+ it('should return validation error for invalid input', async () => {
175
+ const response = await handleDocs({}, mockHybridSearch, mockReranker);
176
+ const parsed = parseResponse(response);
177
+ expect(parsed.error).toBe('Invalid input');
178
+ });
179
+ it('should return graceful message when search engine is null', async () => {
180
+ const response = await handleDocs({ query: 'test' }, null, null);
181
+ const parsed = parseResponse(response);
182
+ expect(parsed.results).toEqual([]);
183
+ expect(parsed.message).toContain('not initialized');
184
+ });
185
+ it('should search and return only doc type chunks', async () => {
186
+ const docResult = makeDocResult();
187
+ const codeResult = makeCodeResult();
188
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([docResult, codeResult]));
189
+ const response = await handleDocs({ query: 'getting started' }, mockHybridSearch, null);
190
+ const parsed = parseResponse(response);
191
+ expect(mockHybridSearch.search).toHaveBeenCalledWith('getting started', { topK: 10 });
192
+ expect(parsed.results).toHaveLength(1);
193
+ expect(parsed.results[0].file_path).toBe('docs/README.md');
194
+ });
195
+ it('should filter by markdown source', async () => {
196
+ const mdResult = makeDocResult();
197
+ const confluenceResult = makeConfluenceResult();
198
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([mdResult, confluenceResult]));
199
+ const response = await handleDocs({ query: 'docs', source: 'markdown' }, mockHybridSearch, null);
200
+ const parsed = parseResponse(response);
201
+ expect(parsed.results).toHaveLength(1);
202
+ expect(parsed.results[0].source).toBe('markdown');
203
+ });
204
+ it('should filter by confluence source', async () => {
205
+ const mdResult = makeDocResult();
206
+ const confluenceResult = makeConfluenceResult();
207
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([mdResult, confluenceResult]));
208
+ const response = await handleDocs({ query: 'api', source: 'confluence' }, mockHybridSearch, null);
209
+ const parsed = parseResponse(response);
210
+ expect(parsed.results).toHaveLength(1);
211
+ expect(parsed.results[0].source).toBe('confluence');
212
+ });
213
+ it('should return all sources when source is all', async () => {
214
+ const mdResult = makeDocResult();
215
+ const confluenceResult = makeConfluenceResult();
216
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([mdResult, confluenceResult]));
217
+ const response = await handleDocs({ query: 'docs', source: 'all' }, mockHybridSearch, null);
218
+ const parsed = parseResponse(response);
219
+ expect(parsed.results).toHaveLength(2);
220
+ });
221
+ it('should filter by file_path', async () => {
222
+ const guideResult = makeDocResult({
223
+ chunk: {
224
+ id: 'doc-guide',
225
+ content: 'Guide content',
226
+ nlSummary: 'A guide',
227
+ filePath: 'docs/guide.md',
228
+ startLine: 1,
229
+ endLine: 3,
230
+ language: 'markdown',
231
+ metadata: {
232
+ chunkType: 'doc',
233
+ name: 'Guide',
234
+ declarations: [],
235
+ imports: [],
236
+ exports: [],
237
+ },
238
+ },
239
+ });
240
+ const readmeResult = makeDocResult();
241
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([guideResult, readmeResult]));
242
+ const response = await handleDocs({ query: 'docs', file_path: 'guide.md' }, mockHybridSearch, null);
243
+ const parsed = parseResponse(response);
244
+ expect(parsed.results).toHaveLength(1);
245
+ expect(parsed.results[0].file_path).toBe('docs/guide.md');
246
+ });
247
+ it('should return empty results when no docs match', async () => {
248
+ const codeResult = makeCodeResult();
249
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([codeResult]));
250
+ const response = await handleDocs({ query: 'test' }, mockHybridSearch, null);
251
+ const parsed = parseResponse(response);
252
+ expect(parsed.results).toHaveLength(0);
253
+ });
254
+ it('should handle search API errors gracefully', async () => {
255
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(err(new EmbedError('Connection refused')));
256
+ const response = await handleDocs({ query: 'test' }, mockHybridSearch, null);
257
+ const parsed = parseResponse(response);
258
+ expect(parsed.error).toBe('Search failed');
259
+ expect(parsed.message).toContain('Connection refused');
260
+ });
261
+ it('should handle thrown exceptions', async () => {
262
+ vi.mocked(mockHybridSearch.search).mockRejectedValue(new Error('Unexpected'));
263
+ const response = await handleDocs({ query: 'test' }, mockHybridSearch, null);
264
+ const parsed = parseResponse(response);
265
+ expect(parsed.error).toBe('Docs search failed');
266
+ expect(parsed.message).toBe('Unexpected');
267
+ });
268
+ it('should format doc results with heading and source', async () => {
269
+ const docResult = makeDocResult();
270
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([docResult]));
271
+ const response = await handleDocs({ query: 'getting started' }, mockHybridSearch, null);
272
+ const parsed = parseResponse(response);
273
+ expect(parsed.results[0].file_path).toBe('docs/README.md');
274
+ expect(parsed.results[0].heading).toBe('Getting Started');
275
+ expect(parsed.results[0].content).toContain('pnpm install');
276
+ expect(parsed.results[0].nl_summary).toContain('getting started');
277
+ expect(parsed.results[0].score).toBe(0.9);
278
+ expect(parsed.results[0].source).toBe('markdown');
279
+ });
280
+ it('should apply custom top_k', async () => {
281
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([]));
282
+ await handleDocs({ query: 'test', top_k: 5 }, mockHybridSearch, null);
283
+ expect(mockHybridSearch.search).toHaveBeenCalledWith('test', { topK: 5 });
284
+ });
285
+ it('should re-rank results when reranker is available', async () => {
286
+ const docResult1 = makeDocResult({ score: 0.7 });
287
+ const docResult2 = makeDocResult({
288
+ chunkId: 'doc-chunk-2',
289
+ score: 0.9,
290
+ content: '## Advanced\n\nAdvanced usage.',
291
+ metadata: {
292
+ chunkType: 'doc',
293
+ name: 'Advanced',
294
+ declarations: [],
295
+ imports: [],
296
+ exports: [],
297
+ docTitle: 'Advanced',
298
+ },
299
+ chunk: {
300
+ id: 'doc-chunk-2',
301
+ content: '## Advanced\n\nAdvanced usage.',
302
+ nlSummary: 'Advanced usage guide',
303
+ filePath: 'docs/advanced.md',
304
+ startLine: 1,
305
+ endLine: 3,
306
+ language: 'markdown',
307
+ metadata: {
308
+ chunkType: 'doc',
309
+ name: 'Advanced',
310
+ declarations: [],
311
+ imports: [],
312
+ exports: [],
313
+ docTitle: 'Advanced',
314
+ },
315
+ },
316
+ });
317
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([docResult1, docResult2]));
318
+ // Reranker reverses order
319
+ vi.mocked(mockReranker.rerank).mockResolvedValue(ok([docResult2, docResult1]));
320
+ const response = await handleDocs({ query: 'advanced' }, mockHybridSearch, mockReranker);
321
+ const parsed = parseResponse(response);
322
+ expect(mockReranker.rerank).toHaveBeenCalled();
323
+ expect(parsed.results[0].heading).toBe('Advanced');
324
+ });
325
+ it('should fall back to original results when reranking fails', async () => {
326
+ const docResult = makeDocResult();
327
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([docResult]));
328
+ vi.mocked(mockReranker.rerank).mockResolvedValue(err(new EmbedError('Rerank failed')));
329
+ const response = await handleDocs({ query: 'test' }, mockHybridSearch, mockReranker);
330
+ const parsed = parseResponse(response);
331
+ expect(parsed.results).toHaveLength(1);
332
+ expect(parsed.results[0].file_path).toBe('docs/README.md');
333
+ });
334
+ it('should not invoke reranker when no doc results remain after filtering', async () => {
335
+ const codeResult = makeCodeResult();
336
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([codeResult]));
337
+ await handleDocs({ query: 'test' }, mockHybridSearch, mockReranker);
338
+ expect(mockReranker.rerank).not.toHaveBeenCalled();
339
+ });
340
+ it('should use name as heading fallback when docTitle is missing', async () => {
341
+ const docResult = makeDocResult({
342
+ metadata: {
343
+ chunkType: 'doc',
344
+ name: 'Section Name',
345
+ declarations: [],
346
+ imports: [],
347
+ exports: [],
348
+ // No docTitle
349
+ },
350
+ });
351
+ vi.mocked(mockHybridSearch.search).mockResolvedValue(ok([docResult]));
352
+ const response = await handleDocs({ query: 'test' }, mockHybridSearch, null);
353
+ const parsed = parseResponse(response);
354
+ expect(parsed.results[0].heading).toBe('Section Name');
355
+ });
356
+ });
357
+ //# sourceMappingURL=docs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docs.test.js","sourceRoot":"","sources":["../../src/tools/docs.test.ts"],"names":[],"mappings":"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"}