bluera-knowledge 0.9.31 → 0.9.34
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/.claude/commands/code-review.md +15 -0
- package/.claude/hooks/post-edit-check.sh +5 -3
- package/.claude/skills/atomic-commits/SKILL.md +3 -1
- package/.claude/skills/code-review-repo/skill.md +62 -0
- package/.husky/pre-commit +3 -2
- package/.prettierrc +9 -0
- package/.versionrc.json +1 -1
- package/CHANGELOG.md +35 -0
- package/CLAUDE.md +6 -0
- package/README.md +25 -13
- package/bun.lock +277 -33
- package/dist/{chunk-L2YVNC63.js → chunk-6FHWC36B.js} +9 -1
- package/dist/chunk-6FHWC36B.js.map +1 -0
- package/dist/{chunk-2SJHNRXD.js → chunk-DC7CGSGT.js} +288 -241
- package/dist/chunk-DC7CGSGT.js.map +1 -0
- package/dist/{chunk-RWSXP3PQ.js → chunk-WFNPNAAP.js} +3194 -3024
- package/dist/chunk-WFNPNAAP.js.map +1 -0
- package/dist/{chunk-OGEY66FZ.js → chunk-Z2KKVH45.js} +548 -482
- package/dist/chunk-Z2KKVH45.js.map +1 -0
- package/dist/index.js +871 -754
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.js +3 -3
- package/dist/watch.service-BJV3TI3F.js +7 -0
- package/dist/workers/background-worker-cli.js +46 -45
- package/dist/workers/background-worker-cli.js.map +1 -1
- package/eslint.config.js +43 -1
- package/package.json +18 -11
- package/plugin.json +8 -0
- package/python/requirements.txt +1 -1
- package/src/analysis/ast-parser.test.ts +12 -11
- package/src/analysis/ast-parser.ts +28 -22
- package/src/analysis/code-graph.test.ts +52 -62
- package/src/analysis/code-graph.ts +9 -13
- package/src/analysis/dependency-usage-analyzer.test.ts +91 -271
- package/src/analysis/dependency-usage-analyzer.ts +52 -24
- package/src/analysis/go-ast-parser.test.ts +22 -22
- package/src/analysis/go-ast-parser.ts +18 -25
- package/src/analysis/parser-factory.test.ts +9 -9
- package/src/analysis/parser-factory.ts +3 -3
- package/src/analysis/python-ast-parser.test.ts +27 -27
- package/src/analysis/python-ast-parser.ts +2 -2
- package/src/analysis/repo-url-resolver.test.ts +82 -82
- package/src/analysis/rust-ast-parser.test.ts +19 -19
- package/src/analysis/rust-ast-parser.ts +17 -27
- package/src/analysis/tree-sitter-parser.test.ts +3 -3
- package/src/analysis/tree-sitter-parser.ts +10 -16
- package/src/cli/commands/crawl.test.ts +40 -24
- package/src/cli/commands/crawl.ts +186 -161
- package/src/cli/commands/index-cmd.test.ts +90 -90
- package/src/cli/commands/index-cmd.ts +52 -36
- package/src/cli/commands/mcp.test.ts +6 -6
- package/src/cli/commands/mcp.ts +2 -2
- package/src/cli/commands/plugin-api.test.ts +16 -18
- package/src/cli/commands/plugin-api.ts +9 -6
- package/src/cli/commands/search.test.ts +16 -7
- package/src/cli/commands/search.ts +124 -87
- package/src/cli/commands/serve.test.ts +67 -25
- package/src/cli/commands/serve.ts +18 -3
- package/src/cli/commands/setup.test.ts +176 -101
- package/src/cli/commands/setup.ts +140 -117
- package/src/cli/commands/store.test.ts +82 -53
- package/src/cli/commands/store.ts +56 -37
- package/src/cli/program.ts +2 -2
- package/src/crawl/article-converter.test.ts +4 -1
- package/src/crawl/article-converter.ts +46 -31
- package/src/crawl/bridge.test.ts +240 -132
- package/src/crawl/bridge.ts +87 -30
- package/src/crawl/claude-client.test.ts +124 -56
- package/src/crawl/claude-client.ts +7 -15
- package/src/crawl/intelligent-crawler.test.ts +65 -22
- package/src/crawl/intelligent-crawler.ts +86 -53
- package/src/crawl/markdown-utils.ts +1 -4
- package/src/db/embeddings.ts +4 -6
- package/src/db/lance.test.ts +63 -4
- package/src/db/lance.ts +31 -12
- package/src/index.ts +26 -17
- package/src/logging/index.ts +1 -5
- package/src/logging/logger.ts +3 -5
- package/src/logging/payload.test.ts +1 -1
- package/src/logging/payload.ts +3 -5
- package/src/mcp/commands/index.ts +2 -2
- package/src/mcp/commands/job.commands.ts +12 -18
- package/src/mcp/commands/meta.commands.ts +13 -13
- package/src/mcp/commands/registry.ts +5 -8
- package/src/mcp/commands/store.commands.ts +19 -19
- package/src/mcp/handlers/execute.handler.test.ts +10 -10
- package/src/mcp/handlers/execute.handler.ts +4 -5
- package/src/mcp/handlers/index.ts +10 -14
- package/src/mcp/handlers/job.handler.test.ts +10 -10
- package/src/mcp/handlers/job.handler.ts +22 -25
- package/src/mcp/handlers/search.handler.test.ts +36 -65
- package/src/mcp/handlers/search.handler.ts +135 -104
- package/src/mcp/handlers/store.handler.test.ts +41 -52
- package/src/mcp/handlers/store.handler.ts +108 -88
- package/src/mcp/schemas/index.test.ts +73 -68
- package/src/mcp/schemas/index.ts +18 -12
- package/src/mcp/server.test.ts +1 -1
- package/src/mcp/server.ts +59 -46
- package/src/plugin/commands.test.ts +230 -95
- package/src/plugin/commands.ts +24 -25
- package/src/plugin/dependency-analyzer.test.ts +52 -52
- package/src/plugin/dependency-analyzer.ts +85 -22
- package/src/plugin/git-clone.test.ts +24 -13
- package/src/plugin/git-clone.ts +3 -7
- package/src/server/app.test.ts +109 -109
- package/src/server/app.ts +32 -23
- package/src/server/index.test.ts +64 -66
- package/src/services/chunking.service.test.ts +32 -32
- package/src/services/chunking.service.ts +16 -9
- package/src/services/code-graph.service.test.ts +30 -36
- package/src/services/code-graph.service.ts +24 -10
- package/src/services/code-unit.service.test.ts +55 -11
- package/src/services/code-unit.service.ts +85 -11
- package/src/services/config.service.test.ts +37 -18
- package/src/services/config.service.ts +30 -7
- package/src/services/index.service.test.ts +49 -18
- package/src/services/index.service.ts +98 -48
- package/src/services/index.ts +8 -10
- package/src/services/job.service.test.ts +22 -22
- package/src/services/job.service.ts +18 -18
- package/src/services/project-root.service.test.ts +1 -3
- package/src/services/search.service.test.ts +248 -120
- package/src/services/search.service.ts +286 -156
- package/src/services/services.test.ts +36 -0
- package/src/services/snippet.service.test.ts +14 -6
- package/src/services/snippet.service.ts +7 -5
- package/src/services/store.service.test.ts +68 -29
- package/src/services/store.service.ts +41 -12
- package/src/services/watch.service.test.ts +34 -14
- package/src/services/watch.service.ts +11 -1
- package/src/types/brands.test.ts +3 -1
- package/src/types/index.ts +2 -13
- package/src/types/search.ts +10 -8
- package/src/utils/type-guards.test.ts +20 -15
- package/src/utils/type-guards.ts +1 -1
- package/src/workers/background-worker-cli.ts +2 -2
- package/src/workers/background-worker.test.ts +54 -40
- package/src/workers/background-worker.ts +76 -60
- package/src/workers/spawn-worker.test.ts +22 -10
- package/src/workers/spawn-worker.ts +6 -6
- package/tests/analysis/ast-parser.test.ts +3 -3
- package/tests/analysis/code-graph.test.ts +5 -5
- package/tests/fixtures/code-snippets/api/error-handling.ts +4 -15
- package/tests/fixtures/code-snippets/api/rest-controller.ts +3 -9
- package/tests/fixtures/code-snippets/auth/jwt-auth.ts +5 -21
- package/tests/fixtures/code-snippets/auth/oauth-flow.ts +4 -4
- package/tests/fixtures/code-snippets/database/repository-pattern.ts +11 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/adapter/aws-lambda/handler.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-pages/handler.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/adapter/cloudflare-workers/serve-static.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/client/client.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/client/types.ts +22 -20
- package/tests/fixtures/corpus/oss-repos/hono/src/context.ts +13 -10
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/accepts/accepts.ts +10 -7
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/adapter/index.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/css/index.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/factory/index.ts +16 -16
- package/tests/fixtures/corpus/oss-repos/hono/src/helper/ssg/ssg.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/hono-base.ts +3 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/hono.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/css.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/intrinsic-element/components.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/dom/render.ts +7 -7
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/hooks/index.ts +3 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/intrinsic-element/components.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/jsx/utils.ts +6 -6
- package/tests/fixtures/corpus/oss-repos/hono/src/middleware/jsx-renderer/index.ts +3 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/middleware/serve-static/index.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/preset/quick.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/preset/tiny.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/router/pattern-router/router.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/node.ts +4 -4
- package/tests/fixtures/corpus/oss-repos/hono/src/router/reg-exp-router/router.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/router/trie-router/node.ts +1 -1
- package/tests/fixtures/corpus/oss-repos/hono/src/types.ts +166 -169
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/body.ts +8 -8
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/color.ts +3 -3
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/cookie.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/encode.ts +2 -2
- package/tests/fixtures/corpus/oss-repos/hono/src/utils/types.ts +30 -33
- package/tests/fixtures/corpus/oss-repos/hono/src/validator/validator.ts +2 -2
- package/tests/fixtures/test-server.ts +3 -2
- package/tests/helpers/performance-metrics.ts +8 -25
- package/tests/helpers/search-relevance.ts +14 -69
- package/tests/integration/cli-consistency.test.ts +5 -4
- package/tests/integration/e2e-workflow.test.ts +2 -0
- package/tests/integration/python-bridge.test.ts +13 -3
- package/tests/mcp/server.test.ts +1 -1
- package/tests/services/code-unit.service.test.ts +48 -0
- package/tests/services/job.service.test.ts +124 -0
- package/tests/services/search.progressive-context.test.ts +2 -2
- package/.claude-plugin/plugin.json +0 -13
- package/BUGS-FOUND.md +0 -71
- package/dist/chunk-2SJHNRXD.js.map +0 -1
- package/dist/chunk-L2YVNC63.js.map +0 -1
- package/dist/chunk-OGEY66FZ.js.map +0 -1
- package/dist/chunk-RWSXP3PQ.js.map +0 -1
- package/dist/watch.service-YAIKKDCF.js +0 -7
- package/skills/atomic-commits/SKILL.md +0 -77
- /package/dist/{watch.service-YAIKKDCF.js.map → watch.service-BJV3TI3F.js.map} +0 -0
package/src/server/app.ts
CHANGED
|
@@ -1,30 +1,38 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import { cors } from 'hono/cors';
|
|
3
3
|
import { z } from 'zod';
|
|
4
|
+
import { createStoreId } from '../types/brands.js';
|
|
4
5
|
import type { ServiceContainer } from '../services/index.js';
|
|
5
6
|
import type { SearchQuery } from '../types/search.js';
|
|
6
|
-
import { createStoreId } from '../types/brands.js';
|
|
7
7
|
|
|
8
8
|
// HTTP API validation schemas (consistent with MCP schemas)
|
|
9
|
-
const CreateStoreBodySchema = z
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
9
|
+
const CreateStoreBodySchema = z
|
|
10
|
+
.object({
|
|
11
|
+
name: z.string().min(1, 'Store name must be a non-empty string'),
|
|
12
|
+
type: z.enum(['file', 'repo', 'web']),
|
|
13
|
+
path: z.string().min(1).optional(),
|
|
14
|
+
url: z.string().min(1).optional(),
|
|
15
|
+
description: z.string().optional(),
|
|
16
|
+
tags: z.array(z.string()).optional(),
|
|
17
|
+
branch: z.string().optional(),
|
|
18
|
+
depth: z.number().int().positive().optional(),
|
|
19
|
+
})
|
|
20
|
+
.refine(
|
|
21
|
+
(data) => {
|
|
22
|
+
switch (data.type) {
|
|
23
|
+
case 'file':
|
|
24
|
+
return data.path !== undefined;
|
|
25
|
+
case 'web':
|
|
26
|
+
return data.url !== undefined;
|
|
27
|
+
case 'repo':
|
|
28
|
+
return data.path !== undefined || data.url !== undefined;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
message:
|
|
33
|
+
'Missing required field: file stores need path, web stores need url, repo stores need path or url',
|
|
24
34
|
}
|
|
25
|
-
|
|
26
|
-
{ message: 'Missing required field: file stores need path, web stores need url, repo stores need path or url' }
|
|
27
|
-
);
|
|
35
|
+
);
|
|
28
36
|
|
|
29
37
|
const SearchBodySchema = z.object({
|
|
30
38
|
query: z.string().min(1, 'Query must be a non-empty string'),
|
|
@@ -82,16 +90,17 @@ export function createApp(services: ServiceContainer): Hono {
|
|
|
82
90
|
return c.json({ error: parseResult.error.issues[0]?.message ?? 'Invalid request body' }, 400);
|
|
83
91
|
}
|
|
84
92
|
|
|
85
|
-
const storeIds = (await services.store.list()).map(s => s.id);
|
|
93
|
+
const storeIds = (await services.store.list()).map((s) => s.id);
|
|
86
94
|
|
|
87
95
|
for (const id of storeIds) {
|
|
88
96
|
await services.lance.initialize(id);
|
|
89
97
|
}
|
|
90
98
|
|
|
91
99
|
// Convert user-provided store strings to StoreIds, or use all stores
|
|
92
|
-
const requestedStores =
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
const requestedStores =
|
|
101
|
+
parseResult.data.stores !== undefined
|
|
102
|
+
? parseResult.data.stores.map((s) => createStoreId(s))
|
|
103
|
+
: storeIds;
|
|
95
104
|
|
|
96
105
|
const query: SearchQuery = {
|
|
97
106
|
query: parseResult.data.query,
|
package/src/server/index.test.ts
CHANGED
|
@@ -13,17 +13,17 @@ describe('Server Integration - Full App Creation', () => {
|
|
|
13
13
|
list: vi.fn(),
|
|
14
14
|
getByIdOrName: vi.fn(),
|
|
15
15
|
create: vi.fn(),
|
|
16
|
-
delete: vi.fn()
|
|
16
|
+
delete: vi.fn(),
|
|
17
17
|
},
|
|
18
18
|
lance: {
|
|
19
|
-
initialize: vi.fn()
|
|
19
|
+
initialize: vi.fn(),
|
|
20
20
|
},
|
|
21
21
|
search: {
|
|
22
|
-
search: vi.fn()
|
|
22
|
+
search: vi.fn(),
|
|
23
23
|
},
|
|
24
24
|
index: {
|
|
25
|
-
indexStore: vi.fn()
|
|
26
|
-
}
|
|
25
|
+
indexStore: vi.fn(),
|
|
26
|
+
},
|
|
27
27
|
} as unknown as ServiceContainer;
|
|
28
28
|
});
|
|
29
29
|
|
|
@@ -62,17 +62,17 @@ describe('Server Integration - Store CRUD Flow', () => {
|
|
|
62
62
|
list: vi.fn(),
|
|
63
63
|
getByIdOrName: vi.fn(),
|
|
64
64
|
create: vi.fn(),
|
|
65
|
-
delete: vi.fn()
|
|
65
|
+
delete: vi.fn(),
|
|
66
66
|
},
|
|
67
67
|
lance: {
|
|
68
|
-
initialize: vi.fn()
|
|
68
|
+
initialize: vi.fn(),
|
|
69
69
|
},
|
|
70
70
|
search: {
|
|
71
|
-
search: vi.fn()
|
|
71
|
+
search: vi.fn(),
|
|
72
72
|
},
|
|
73
73
|
index: {
|
|
74
|
-
indexStore: vi.fn()
|
|
75
|
-
}
|
|
74
|
+
indexStore: vi.fn(),
|
|
75
|
+
},
|
|
76
76
|
} as unknown as ServiceContainer;
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -93,12 +93,12 @@ describe('Server Integration - Store CRUD Flow', () => {
|
|
|
93
93
|
type: 'file',
|
|
94
94
|
path: '/tmp/test',
|
|
95
95
|
createdAt: new Date(),
|
|
96
|
-
updatedAt: new Date()
|
|
96
|
+
updatedAt: new Date(),
|
|
97
97
|
};
|
|
98
98
|
|
|
99
99
|
vi.mocked(mockServices.store.create).mockResolvedValue({
|
|
100
100
|
success: true,
|
|
101
|
-
data: newStore
|
|
101
|
+
data: newStore,
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
res = await app.request('/api/stores', {
|
|
@@ -107,8 +107,8 @@ describe('Server Integration - Store CRUD Flow', () => {
|
|
|
107
107
|
body: JSON.stringify({
|
|
108
108
|
name: 'test-store',
|
|
109
109
|
type: 'file',
|
|
110
|
-
path: '/tmp/test'
|
|
111
|
-
})
|
|
110
|
+
path: '/tmp/test',
|
|
111
|
+
}),
|
|
112
112
|
});
|
|
113
113
|
|
|
114
114
|
expect(res.status).toBe(201);
|
|
@@ -123,11 +123,11 @@ describe('Server Integration - Store CRUD Flow', () => {
|
|
|
123
123
|
// 4. Delete store
|
|
124
124
|
vi.mocked(mockServices.store.delete).mockResolvedValue({
|
|
125
125
|
success: true,
|
|
126
|
-
data: undefined
|
|
126
|
+
data: undefined,
|
|
127
127
|
});
|
|
128
128
|
|
|
129
129
|
res = await app.request('/api/stores/new-store', {
|
|
130
|
-
method: 'DELETE'
|
|
130
|
+
method: 'DELETE',
|
|
131
131
|
});
|
|
132
132
|
|
|
133
133
|
expect(res.status).toBe(200);
|
|
@@ -140,14 +140,14 @@ describe('Server Integration - Search Flow', () => {
|
|
|
140
140
|
beforeEach(() => {
|
|
141
141
|
mockServices = {
|
|
142
142
|
store: {
|
|
143
|
-
list: vi.fn()
|
|
143
|
+
list: vi.fn(),
|
|
144
144
|
},
|
|
145
145
|
lance: {
|
|
146
|
-
initialize: vi.fn()
|
|
146
|
+
initialize: vi.fn(),
|
|
147
147
|
},
|
|
148
148
|
search: {
|
|
149
|
-
search: vi.fn()
|
|
150
|
-
}
|
|
149
|
+
search: vi.fn(),
|
|
150
|
+
},
|
|
151
151
|
} as unknown as ServiceContainer;
|
|
152
152
|
});
|
|
153
153
|
|
|
@@ -161,7 +161,7 @@ describe('Server Integration - Search Flow', () => {
|
|
|
161
161
|
type: 'file',
|
|
162
162
|
path: '/tmp/1',
|
|
163
163
|
createdAt: new Date(),
|
|
164
|
-
updatedAt: new Date()
|
|
164
|
+
updatedAt: new Date(),
|
|
165
165
|
},
|
|
166
166
|
{
|
|
167
167
|
id: createStoreId('store-2'),
|
|
@@ -169,22 +169,20 @@ describe('Server Integration - Search Flow', () => {
|
|
|
169
169
|
type: 'file',
|
|
170
170
|
path: '/tmp/2',
|
|
171
171
|
createdAt: new Date(),
|
|
172
|
-
updatedAt: new Date()
|
|
173
|
-
}
|
|
172
|
+
updatedAt: new Date(),
|
|
173
|
+
},
|
|
174
174
|
];
|
|
175
175
|
|
|
176
176
|
vi.mocked(mockServices.store.list).mockResolvedValue(stores);
|
|
177
177
|
vi.mocked(mockServices.search.search).mockResolvedValue({
|
|
178
|
-
results: [
|
|
179
|
-
|
|
180
|
-
],
|
|
181
|
-
totalResults: 1
|
|
178
|
+
results: [{ score: 0.9, summary: { location: 'file1.ts', purpose: 'Test' } }],
|
|
179
|
+
totalResults: 1,
|
|
182
180
|
});
|
|
183
181
|
|
|
184
182
|
const res = await app.request('/api/search', {
|
|
185
183
|
method: 'POST',
|
|
186
184
|
headers: { 'Content-Type': 'application/json' },
|
|
187
|
-
body: JSON.stringify({ query: 'test query' })
|
|
185
|
+
body: JSON.stringify({ query: 'test query' }),
|
|
188
186
|
});
|
|
189
187
|
|
|
190
188
|
expect(res.status).toBe(200);
|
|
@@ -199,14 +197,14 @@ describe('Server Integration - Index Flow', () => {
|
|
|
199
197
|
beforeEach(() => {
|
|
200
198
|
mockServices = {
|
|
201
199
|
store: {
|
|
202
|
-
getByIdOrName: vi.fn()
|
|
200
|
+
getByIdOrName: vi.fn(),
|
|
203
201
|
},
|
|
204
202
|
lance: {
|
|
205
|
-
initialize: vi.fn()
|
|
203
|
+
initialize: vi.fn(),
|
|
206
204
|
},
|
|
207
205
|
index: {
|
|
208
|
-
indexStore: vi.fn()
|
|
209
|
-
}
|
|
206
|
+
indexStore: vi.fn(),
|
|
207
|
+
},
|
|
210
208
|
} as unknown as ServiceContainer;
|
|
211
209
|
});
|
|
212
210
|
|
|
@@ -219,7 +217,7 @@ describe('Server Integration - Index Flow', () => {
|
|
|
219
217
|
type: 'file',
|
|
220
218
|
path: '/tmp/test',
|
|
221
219
|
createdAt: new Date(),
|
|
222
|
-
updatedAt: new Date()
|
|
220
|
+
updatedAt: new Date(),
|
|
223
221
|
};
|
|
224
222
|
|
|
225
223
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(store);
|
|
@@ -228,12 +226,12 @@ describe('Server Integration - Index Flow', () => {
|
|
|
228
226
|
data: {
|
|
229
227
|
documentsIndexed: 5,
|
|
230
228
|
chunksCreated: 25,
|
|
231
|
-
timeMs: 500
|
|
232
|
-
}
|
|
229
|
+
timeMs: 500,
|
|
230
|
+
},
|
|
233
231
|
});
|
|
234
232
|
|
|
235
233
|
const res = await app.request('/api/stores/store-1/index', {
|
|
236
|
-
method: 'POST'
|
|
234
|
+
method: 'POST',
|
|
237
235
|
});
|
|
238
236
|
|
|
239
237
|
expect(res.status).toBe(200);
|
|
@@ -250,14 +248,14 @@ describe('Server Integration - Error Handling', () => {
|
|
|
250
248
|
store: {
|
|
251
249
|
create: vi.fn(),
|
|
252
250
|
getByIdOrName: vi.fn(),
|
|
253
|
-
delete: vi.fn()
|
|
251
|
+
delete: vi.fn(),
|
|
254
252
|
},
|
|
255
253
|
index: {
|
|
256
|
-
indexStore: vi.fn()
|
|
254
|
+
indexStore: vi.fn(),
|
|
257
255
|
},
|
|
258
256
|
lance: {
|
|
259
|
-
initialize: vi.fn()
|
|
260
|
-
}
|
|
257
|
+
initialize: vi.fn(),
|
|
258
|
+
},
|
|
261
259
|
} as unknown as ServiceContainer;
|
|
262
260
|
});
|
|
263
261
|
|
|
@@ -266,7 +264,7 @@ describe('Server Integration - Error Handling', () => {
|
|
|
266
264
|
|
|
267
265
|
vi.mocked(mockServices.store.create).mockResolvedValue({
|
|
268
266
|
success: false,
|
|
269
|
-
error: new Error('Service error')
|
|
267
|
+
error: new Error('Service error'),
|
|
270
268
|
});
|
|
271
269
|
|
|
272
270
|
const res = await app.request('/api/stores', {
|
|
@@ -275,8 +273,8 @@ describe('Server Integration - Error Handling', () => {
|
|
|
275
273
|
body: JSON.stringify({
|
|
276
274
|
name: 'test',
|
|
277
275
|
type: 'file',
|
|
278
|
-
path: '/tmp/test'
|
|
279
|
-
})
|
|
276
|
+
path: '/tmp/test',
|
|
277
|
+
}),
|
|
280
278
|
});
|
|
281
279
|
|
|
282
280
|
expect(res.status).toBe(400);
|
|
@@ -301,14 +299,14 @@ describe('Server Integration - Content Negotiation', () => {
|
|
|
301
299
|
beforeEach(() => {
|
|
302
300
|
mockServices = {
|
|
303
301
|
store: {
|
|
304
|
-
list: vi.fn()
|
|
302
|
+
list: vi.fn(),
|
|
305
303
|
},
|
|
306
304
|
lance: {
|
|
307
|
-
initialize: vi.fn()
|
|
305
|
+
initialize: vi.fn(),
|
|
308
306
|
},
|
|
309
307
|
search: {
|
|
310
|
-
search: vi.fn()
|
|
311
|
-
}
|
|
308
|
+
search: vi.fn(),
|
|
309
|
+
},
|
|
312
310
|
} as unknown as ServiceContainer;
|
|
313
311
|
});
|
|
314
312
|
|
|
@@ -328,13 +326,13 @@ describe('Server Integration - Content Negotiation', () => {
|
|
|
328
326
|
vi.mocked(mockServices.store.list).mockResolvedValue([]);
|
|
329
327
|
vi.mocked(mockServices.search.search).mockResolvedValue({
|
|
330
328
|
results: [],
|
|
331
|
-
totalResults: 0
|
|
329
|
+
totalResults: 0,
|
|
332
330
|
});
|
|
333
331
|
|
|
334
332
|
const res = await app.request('/api/search', {
|
|
335
333
|
method: 'POST',
|
|
336
334
|
headers: { 'Content-Type': 'application/json' },
|
|
337
|
-
body: JSON.stringify({ query: 'test' })
|
|
335
|
+
body: JSON.stringify({ query: 'test' }),
|
|
338
336
|
});
|
|
339
337
|
|
|
340
338
|
expect(res.status).toBe(200);
|
|
@@ -347,14 +345,14 @@ describe('Server Integration - Route Parameters', () => {
|
|
|
347
345
|
beforeEach(() => {
|
|
348
346
|
mockServices = {
|
|
349
347
|
store: {
|
|
350
|
-
getByIdOrName: vi.fn()
|
|
348
|
+
getByIdOrName: vi.fn(),
|
|
351
349
|
},
|
|
352
350
|
lance: {
|
|
353
|
-
initialize: vi.fn()
|
|
351
|
+
initialize: vi.fn(),
|
|
354
352
|
},
|
|
355
353
|
index: {
|
|
356
|
-
indexStore: vi.fn()
|
|
357
|
-
}
|
|
354
|
+
indexStore: vi.fn(),
|
|
355
|
+
},
|
|
358
356
|
} as unknown as ServiceContainer;
|
|
359
357
|
});
|
|
360
358
|
|
|
@@ -367,7 +365,7 @@ describe('Server Integration - Route Parameters', () => {
|
|
|
367
365
|
type: 'file',
|
|
368
366
|
path: '/tmp/test',
|
|
369
367
|
createdAt: new Date(),
|
|
370
|
-
updatedAt: new Date()
|
|
368
|
+
updatedAt: new Date(),
|
|
371
369
|
};
|
|
372
370
|
|
|
373
371
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(store);
|
|
@@ -386,7 +384,7 @@ describe('Server Integration - Route Parameters', () => {
|
|
|
386
384
|
type: 'file',
|
|
387
385
|
path: '/tmp/test',
|
|
388
386
|
createdAt: new Date(),
|
|
389
|
-
updatedAt: new Date()
|
|
387
|
+
updatedAt: new Date(),
|
|
390
388
|
};
|
|
391
389
|
|
|
392
390
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(store);
|
|
@@ -406,17 +404,17 @@ describe('Server Integration - HTTP Methods', () => {
|
|
|
406
404
|
list: vi.fn(),
|
|
407
405
|
getByIdOrName: vi.fn(),
|
|
408
406
|
create: vi.fn(),
|
|
409
|
-
delete: vi.fn()
|
|
407
|
+
delete: vi.fn(),
|
|
410
408
|
},
|
|
411
409
|
lance: {
|
|
412
|
-
initialize: vi.fn()
|
|
410
|
+
initialize: vi.fn(),
|
|
413
411
|
},
|
|
414
412
|
search: {
|
|
415
|
-
search: vi.fn()
|
|
413
|
+
search: vi.fn(),
|
|
416
414
|
},
|
|
417
415
|
index: {
|
|
418
|
-
indexStore: vi.fn()
|
|
419
|
-
}
|
|
416
|
+
indexStore: vi.fn(),
|
|
417
|
+
},
|
|
420
418
|
} as unknown as ServiceContainer;
|
|
421
419
|
});
|
|
422
420
|
|
|
@@ -426,7 +424,7 @@ describe('Server Integration - HTTP Methods', () => {
|
|
|
426
424
|
vi.mocked(mockServices.store.list).mockResolvedValue([]);
|
|
427
425
|
|
|
428
426
|
const res = await app.request('/api/stores', {
|
|
429
|
-
method: 'GET'
|
|
427
|
+
method: 'GET',
|
|
430
428
|
});
|
|
431
429
|
|
|
432
430
|
expect(res.status).toBe(200);
|
|
@@ -438,13 +436,13 @@ describe('Server Integration - HTTP Methods', () => {
|
|
|
438
436
|
vi.mocked(mockServices.store.list).mockResolvedValue([]);
|
|
439
437
|
vi.mocked(mockServices.search.search).mockResolvedValue({
|
|
440
438
|
results: [],
|
|
441
|
-
totalResults: 0
|
|
439
|
+
totalResults: 0,
|
|
442
440
|
});
|
|
443
441
|
|
|
444
442
|
const res = await app.request('/api/search', {
|
|
445
443
|
method: 'POST',
|
|
446
444
|
headers: { 'Content-Type': 'application/json' },
|
|
447
|
-
body: JSON.stringify({ query: 'test' })
|
|
445
|
+
body: JSON.stringify({ query: 'test' }),
|
|
448
446
|
});
|
|
449
447
|
|
|
450
448
|
expect(res.status).toBe(200);
|
|
@@ -459,17 +457,17 @@ describe('Server Integration - HTTP Methods', () => {
|
|
|
459
457
|
type: 'file',
|
|
460
458
|
path: '/tmp/test',
|
|
461
459
|
createdAt: new Date(),
|
|
462
|
-
updatedAt: new Date()
|
|
460
|
+
updatedAt: new Date(),
|
|
463
461
|
};
|
|
464
462
|
|
|
465
463
|
vi.mocked(mockServices.store.getByIdOrName).mockResolvedValue(store);
|
|
466
464
|
vi.mocked(mockServices.store.delete).mockResolvedValue({
|
|
467
465
|
success: true,
|
|
468
|
-
data: undefined
|
|
466
|
+
data: undefined,
|
|
469
467
|
});
|
|
470
468
|
|
|
471
469
|
const res = await app.request('/api/stores/store-1', {
|
|
472
|
-
method: 'DELETE'
|
|
470
|
+
method: 'DELETE',
|
|
473
471
|
});
|
|
474
472
|
|
|
475
473
|
expect(res.status).toBe(200);
|
|
@@ -9,7 +9,7 @@ describe('ChunkingService', () => {
|
|
|
9
9
|
const text = 'A'.repeat(250);
|
|
10
10
|
const chunks = chunker.chunk(text);
|
|
11
11
|
expect(chunks.length).toBeGreaterThan(1);
|
|
12
|
-
expect(chunks.every(c => c.content.length <= 100)).toBe(true);
|
|
12
|
+
expect(chunks.every((c) => c.content.length <= 100)).toBe(true);
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
it('preserves overlap between chunks', () => {
|
|
@@ -34,7 +34,7 @@ describe('ChunkingService', () => {
|
|
|
34
34
|
const chunks = chunker.chunk(text);
|
|
35
35
|
expect(chunks[0]!.chunkIndex).toBe(0);
|
|
36
36
|
expect(chunks[1]!.chunkIndex).toBe(1);
|
|
37
|
-
expect(chunks.every(c => c.totalChunks === chunks.length)).toBe(true);
|
|
37
|
+
expect(chunks.every((c) => c.totalChunks === chunks.length)).toBe(true);
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
it('handles empty text', () => {
|
|
@@ -66,9 +66,9 @@ Content for section 3`;
|
|
|
66
66
|
|
|
67
67
|
const chunks = chunker.chunk(markdown, 'test.md');
|
|
68
68
|
expect(chunks.length).toBeGreaterThan(0);
|
|
69
|
-
expect(chunks.some(c => c.sectionHeader === 'Header 1')).toBe(true);
|
|
70
|
-
expect(chunks.some(c => c.sectionHeader === 'Header 2')).toBe(true);
|
|
71
|
-
expect(chunks.some(c => c.sectionHeader === 'Header 3')).toBe(true);
|
|
69
|
+
expect(chunks.some((c) => c.sectionHeader === 'Header 1')).toBe(true);
|
|
70
|
+
expect(chunks.some((c) => c.sectionHeader === 'Header 2')).toBe(true);
|
|
71
|
+
expect(chunks.some((c) => c.sectionHeader === 'Header 3')).toBe(true);
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
it('handles markdown with no headers', () => {
|
|
@@ -91,7 +91,7 @@ Content for section 3`;
|
|
|
91
91
|
const chunks = chunker.chunk(markdown, 'test.md');
|
|
92
92
|
// Large section should be split
|
|
93
93
|
expect(chunks.length).toBeGreaterThan(2);
|
|
94
|
-
expect(chunks.filter(c => c.sectionHeader === 'Header 1').length).toBeGreaterThan(1);
|
|
94
|
+
expect(chunks.filter((c) => c.sectionHeader === 'Header 1').length).toBeGreaterThan(1);
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
it('preserves markdown section headers in metadata', () => {
|
|
@@ -121,9 +121,9 @@ Content 3
|
|
|
121
121
|
Content 2`;
|
|
122
122
|
|
|
123
123
|
const chunks = chunker.chunk(markdown, 'test.md');
|
|
124
|
-
expect(chunks.some(c => c.sectionHeader === 'H1')).toBe(true);
|
|
125
|
-
expect(chunks.some(c => c.sectionHeader === 'H3')).toBe(true);
|
|
126
|
-
expect(chunks.some(c => c.sectionHeader === 'H2')).toBe(true);
|
|
124
|
+
expect(chunks.some((c) => c.sectionHeader === 'H1')).toBe(true);
|
|
125
|
+
expect(chunks.some((c) => c.sectionHeader === 'H3')).toBe(true);
|
|
126
|
+
expect(chunks.some((c) => c.sectionHeader === 'H2')).toBe(true);
|
|
127
127
|
});
|
|
128
128
|
});
|
|
129
129
|
|
|
@@ -139,8 +139,8 @@ function bar() {
|
|
|
139
139
|
|
|
140
140
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
141
141
|
expect(chunks.length).toBeGreaterThan(0);
|
|
142
|
-
expect(chunks.some(c => c.functionName === 'foo')).toBe(true);
|
|
143
|
-
expect(chunks.some(c => c.functionName === 'bar')).toBe(true);
|
|
142
|
+
expect(chunks.some((c) => c.functionName === 'foo')).toBe(true);
|
|
143
|
+
expect(chunks.some((c) => c.functionName === 'bar')).toBe(true);
|
|
144
144
|
});
|
|
145
145
|
|
|
146
146
|
it('handles class declarations', () => {
|
|
@@ -153,8 +153,8 @@ class AnotherClass {
|
|
|
153
153
|
}`;
|
|
154
154
|
|
|
155
155
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
156
|
-
expect(chunks.some(c => c.functionName === 'MyClass')).toBe(true);
|
|
157
|
-
expect(chunks.some(c => c.functionName === 'AnotherClass')).toBe(true);
|
|
156
|
+
expect(chunks.some((c) => c.functionName === 'MyClass')).toBe(true);
|
|
157
|
+
expect(chunks.some((c) => c.functionName === 'AnotherClass')).toBe(true);
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
it('handles exported declarations', () => {
|
|
@@ -165,8 +165,8 @@ class AnotherClass {
|
|
|
165
165
|
export class ExportedClass {}`;
|
|
166
166
|
|
|
167
167
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
168
|
-
expect(chunks.some(c => c.functionName === 'exportedFn')).toBe(true);
|
|
169
|
-
expect(chunks.some(c => c.functionName === 'ExportedClass')).toBe(true);
|
|
168
|
+
expect(chunks.some((c) => c.functionName === 'exportedFn')).toBe(true);
|
|
169
|
+
expect(chunks.some((c) => c.functionName === 'ExportedClass')).toBe(true);
|
|
170
170
|
});
|
|
171
171
|
|
|
172
172
|
it('handles async functions', () => {
|
|
@@ -175,7 +175,7 @@ export class ExportedClass {}`;
|
|
|
175
175
|
}`;
|
|
176
176
|
|
|
177
177
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
178
|
-
expect(chunks.some(c => c.functionName === 'asyncFn')).toBe(true);
|
|
178
|
+
expect(chunks.some((c) => c.functionName === 'asyncFn')).toBe(true);
|
|
179
179
|
});
|
|
180
180
|
|
|
181
181
|
it('handles const/let/var declarations', () => {
|
|
@@ -186,9 +186,9 @@ let myLet = 'test';
|
|
|
186
186
|
var myVar = true;`;
|
|
187
187
|
|
|
188
188
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
189
|
-
expect(chunks.some(c => c.functionName === 'myConst')).toBe(true);
|
|
190
|
-
expect(chunks.some(c => c.functionName === 'myLet')).toBe(true);
|
|
191
|
-
expect(chunks.some(c => c.functionName === 'myVar')).toBe(true);
|
|
189
|
+
expect(chunks.some((c) => c.functionName === 'myConst')).toBe(true);
|
|
190
|
+
expect(chunks.some((c) => c.functionName === 'myLet')).toBe(true);
|
|
191
|
+
expect(chunks.some((c) => c.functionName === 'myVar')).toBe(true);
|
|
192
192
|
});
|
|
193
193
|
|
|
194
194
|
it('handles interface and type declarations', () => {
|
|
@@ -201,8 +201,8 @@ type MyType = {
|
|
|
201
201
|
}`;
|
|
202
202
|
|
|
203
203
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
204
|
-
expect(chunks.some(c => c.functionName === 'MyInterface')).toBe(true);
|
|
205
|
-
expect(chunks.some(c => c.functionName === 'MyType')).toBe(true);
|
|
204
|
+
expect(chunks.some((c) => c.functionName === 'MyInterface')).toBe(true);
|
|
205
|
+
expect(chunks.some((c) => c.functionName === 'MyType')).toBe(true);
|
|
206
206
|
});
|
|
207
207
|
|
|
208
208
|
it('handles enum declarations', () => {
|
|
@@ -213,7 +213,7 @@ type MyType = {
|
|
|
213
213
|
}`;
|
|
214
214
|
|
|
215
215
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
216
|
-
expect(chunks.some(c => c.functionName === 'Color')).toBe(true);
|
|
216
|
+
expect(chunks.some((c) => c.functionName === 'Color')).toBe(true);
|
|
217
217
|
});
|
|
218
218
|
|
|
219
219
|
it('handles code with no declarations', () => {
|
|
@@ -252,7 +252,7 @@ function smallFn() {
|
|
|
252
252
|
}`;
|
|
253
253
|
|
|
254
254
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
255
|
-
expect(chunks.some(c => c.functionName === 'withNested')).toBe(true);
|
|
255
|
+
expect(chunks.some((c) => c.functionName === 'withNested')).toBe(true);
|
|
256
256
|
});
|
|
257
257
|
|
|
258
258
|
it('exposes brace counting bug - braces in strings', () => {
|
|
@@ -269,8 +269,8 @@ function nextFn() {
|
|
|
269
269
|
}`;
|
|
270
270
|
|
|
271
271
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
272
|
-
expect(chunks.some(c => c.functionName === 'withString')).toBe(true);
|
|
273
|
-
expect(chunks.some(c => c.functionName === 'nextFn')).toBe(true);
|
|
272
|
+
expect(chunks.some((c) => c.functionName === 'withString')).toBe(true);
|
|
273
|
+
expect(chunks.some((c) => c.functionName === 'nextFn')).toBe(true);
|
|
274
274
|
// The bug: braces in strings should be ignored for boundary detection
|
|
275
275
|
});
|
|
276
276
|
|
|
@@ -290,8 +290,8 @@ function nextFn() {
|
|
|
290
290
|
}`;
|
|
291
291
|
|
|
292
292
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
293
|
-
expect(chunks.some(c => c.functionName === 'withComments')).toBe(true);
|
|
294
|
-
expect(chunks.some(c => c.functionName === 'nextFn')).toBe(true);
|
|
293
|
+
expect(chunks.some((c) => c.functionName === 'withComments')).toBe(true);
|
|
294
|
+
expect(chunks.some((c) => c.functionName === 'nextFn')).toBe(true);
|
|
295
295
|
// The bug: braces in comments should be ignored for boundary detection
|
|
296
296
|
});
|
|
297
297
|
|
|
@@ -305,7 +305,7 @@ function myFn() {
|
|
|
305
305
|
}`;
|
|
306
306
|
|
|
307
307
|
const chunks = chunker.chunk(code, 'test.ts');
|
|
308
|
-
expect(chunks.some(c => c.functionName === 'myFn')).toBe(true);
|
|
308
|
+
expect(chunks.some((c) => c.functionName === 'myFn')).toBe(true);
|
|
309
309
|
expect(chunks[0]!.content).toContain('Documentation');
|
|
310
310
|
});
|
|
311
311
|
});
|
|
@@ -326,25 +326,25 @@ function myFn() {
|
|
|
326
326
|
it('uses code chunking for .ts files', () => {
|
|
327
327
|
const code = 'function test() {}\nfunction test2() {}';
|
|
328
328
|
const chunks = chunker.chunk(code, 'file.ts');
|
|
329
|
-
expect(chunks.some(c => c.functionName === 'test')).toBe(true);
|
|
329
|
+
expect(chunks.some((c) => c.functionName === 'test')).toBe(true);
|
|
330
330
|
});
|
|
331
331
|
|
|
332
332
|
it('uses code chunking for .tsx files', () => {
|
|
333
333
|
const code = 'function Component() {}\nfunction Other() {}';
|
|
334
334
|
const chunks = chunker.chunk(code, 'component.tsx');
|
|
335
|
-
expect(chunks.some(c => c.functionName === 'Component')).toBe(true);
|
|
335
|
+
expect(chunks.some((c) => c.functionName === 'Component')).toBe(true);
|
|
336
336
|
});
|
|
337
337
|
|
|
338
338
|
it('uses code chunking for .js files', () => {
|
|
339
339
|
const code = 'function test() {}\nfunction test2() {}';
|
|
340
340
|
const chunks = chunker.chunk(code, 'file.js');
|
|
341
|
-
expect(chunks.some(c => c.functionName === 'test')).toBe(true);
|
|
341
|
+
expect(chunks.some((c) => c.functionName === 'test')).toBe(true);
|
|
342
342
|
});
|
|
343
343
|
|
|
344
344
|
it('uses code chunking for .jsx files', () => {
|
|
345
345
|
const code = 'function Component() {}\nfunction Other() {}';
|
|
346
346
|
const chunks = chunker.chunk(code, 'component.jsx');
|
|
347
|
-
expect(chunks.some(c => c.functionName === 'Component')).toBe(true);
|
|
347
|
+
expect(chunks.some((c) => c.functionName === 'Component')).toBe(true);
|
|
348
348
|
});
|
|
349
349
|
|
|
350
350
|
it('uses sliding window for unknown file types', () => {
|
|
@@ -154,7 +154,8 @@ export class ChunkingService {
|
|
|
154
154
|
*/
|
|
155
155
|
private chunkCode(text: string): Chunk[] {
|
|
156
156
|
// Match top-level declarations with optional JSDoc/comments before them
|
|
157
|
-
const declarationRegex =
|
|
157
|
+
const declarationRegex =
|
|
158
|
+
/^(?:\/\*\*[\s\S]*?\*\/\s*)?(?:export\s+)?(?:async\s+)?(?:function|class|interface|type|const|let|var|enum)\s+(\w+)/gm;
|
|
158
159
|
const declarations: Array<{ startOffset: number; endOffset: number; name?: string }> = [];
|
|
159
160
|
|
|
160
161
|
let match: RegExpExecArray | null;
|
|
@@ -184,7 +185,11 @@ export class ChunkingService {
|
|
|
184
185
|
// For declarations that likely have braces (functions, classes, enums)
|
|
185
186
|
// use smart boundary detection
|
|
186
187
|
const declText = text.slice(currentDecl.startOffset);
|
|
187
|
-
if (
|
|
188
|
+
if (
|
|
189
|
+
/^(?:\/\*\*[\s\S]*?\*\/\s*)?(?:export\s+)?(?:async\s+)?(?:function|class|enum)\s+/m.test(
|
|
190
|
+
declText
|
|
191
|
+
)
|
|
192
|
+
) {
|
|
188
193
|
const boundary = this.findDeclarationEnd(declText);
|
|
189
194
|
if (boundary > 0) {
|
|
190
195
|
currentDecl.endOffset = currentDecl.startOffset + boundary;
|
|
@@ -337,13 +342,15 @@ export class ChunkingService {
|
|
|
337
342
|
*/
|
|
338
343
|
private chunkSlidingWindow(text: string): Chunk[] {
|
|
339
344
|
if (text.length <= this.chunkSize) {
|
|
340
|
-
return [
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
345
|
+
return [
|
|
346
|
+
{
|
|
347
|
+
content: text,
|
|
348
|
+
chunkIndex: 0,
|
|
349
|
+
totalChunks: 1,
|
|
350
|
+
startOffset: 0,
|
|
351
|
+
endOffset: text.length,
|
|
352
|
+
},
|
|
353
|
+
];
|
|
347
354
|
}
|
|
348
355
|
|
|
349
356
|
const chunks: Chunk[] = [];
|