@lon-ask/dockit 0.1.1 → 0.1.4

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.
Files changed (140) hide show
  1. package/LICENSE +21 -674
  2. package/README.md +618 -328
  3. package/SKILL.md +61 -110
  4. package/apps/client/dist/assets/{index-CqOXxsEZ.js → index-DzadxeQH.js} +2 -2
  5. package/apps/client/dist/index.html +1 -1
  6. package/apps/client/index.html +12 -0
  7. package/apps/client/package.json +26 -0
  8. package/apps/client/src/App.tsx +18 -0
  9. package/apps/client/src/api/client.ts +54 -0
  10. package/apps/client/src/components/BuildPanel.tsx +77 -0
  11. package/apps/client/src/components/DocViewer.tsx +76 -0
  12. package/apps/client/src/components/EntryDetail.tsx +322 -0
  13. package/apps/client/src/components/EntryForm.tsx +117 -0
  14. package/apps/client/src/components/EntryList.tsx +165 -0
  15. package/apps/client/src/components/GlobalSearchBar.tsx +166 -0
  16. package/apps/client/src/components/Layout.tsx +57 -0
  17. package/apps/client/src/components/SearchBar.tsx +103 -0
  18. package/apps/client/src/components/SourceForm.tsx +497 -0
  19. package/apps/client/src/hooks/useTheme.ts +19 -0
  20. package/apps/client/src/index.css +77 -0
  21. package/apps/client/src/main.tsx +13 -0
  22. package/apps/client/src/types.ts +105 -0
  23. package/apps/client/vite.config.ts +13 -0
  24. package/apps/server/dist/core/domain/entry.js +20 -0
  25. package/apps/server/dist/core/domain/entry.js.map +1 -0
  26. package/apps/server/dist/core/domain/errors.js +33 -0
  27. package/apps/server/dist/core/domain/errors.js.map +1 -0
  28. package/apps/server/dist/core/domain/knowledge-graph.js +2 -0
  29. package/apps/server/dist/core/domain/knowledge-graph.js.map +1 -0
  30. package/apps/server/dist/core/domain/types.js +2 -0
  31. package/apps/server/dist/core/domain/types.js.map +1 -0
  32. package/apps/server/dist/core/ports/IBuildRepository.js +2 -0
  33. package/apps/server/dist/core/ports/IBuildRepository.js.map +1 -0
  34. package/apps/server/dist/core/ports/IDocumentNormalizer.js +2 -0
  35. package/apps/server/dist/core/ports/IDocumentNormalizer.js.map +1 -0
  36. package/apps/server/dist/core/ports/IDocumentStore.js +2 -0
  37. package/apps/server/dist/core/ports/IDocumentStore.js.map +1 -0
  38. package/apps/server/dist/core/ports/IEntryReadModel.js +2 -0
  39. package/apps/server/dist/core/ports/IEntryReadModel.js.map +1 -0
  40. package/apps/server/dist/core/ports/IEntryRepository.js +2 -0
  41. package/apps/server/dist/core/ports/IEntryRepository.js.map +1 -0
  42. package/apps/server/dist/core/ports/IKnowledgeGraph.js +2 -0
  43. package/apps/server/dist/core/ports/IKnowledgeGraph.js.map +1 -0
  44. package/apps/server/dist/core/ports/IPathResolver.js +2 -0
  45. package/apps/server/dist/core/ports/IPathResolver.js.map +1 -0
  46. package/apps/server/dist/core/ports/ISearchEngine.js +2 -0
  47. package/apps/server/dist/core/ports/ISearchEngine.js.map +1 -0
  48. package/apps/server/dist/core/ports/ISourceProcessor.js +2 -0
  49. package/apps/server/dist/core/ports/ISourceProcessor.js.map +1 -0
  50. package/apps/server/dist/core/ports/ISourceRepository.js +2 -0
  51. package/apps/server/dist/core/ports/ISourceRepository.js.map +1 -0
  52. package/apps/server/dist/core/usecases/BuildUseCase.js +76 -0
  53. package/apps/server/dist/core/usecases/BuildUseCase.js.map +1 -0
  54. package/apps/server/dist/core/usecases/ConfigUseCase.js +62 -0
  55. package/apps/server/dist/core/usecases/ConfigUseCase.js.map +1 -0
  56. package/apps/server/dist/core/usecases/SearchUseCase.js +17 -0
  57. package/apps/server/dist/core/usecases/SearchUseCase.js.map +1 -0
  58. package/apps/server/dist/index.js +86 -0
  59. package/apps/server/dist/index.js.map +1 -0
  60. package/apps/server/dist/infrastructure/filesystem/FileSystemDocumentStore.js +25 -0
  61. package/apps/server/dist/infrastructure/filesystem/FileSystemDocumentStore.js.map +1 -0
  62. package/apps/server/dist/infrastructure/graph/GraphSearchDecorator.js +42 -0
  63. package/apps/server/dist/infrastructure/graph/GraphSearchDecorator.js.map +1 -0
  64. package/apps/server/dist/infrastructure/graph/GraphifyKnowledgeGraph.js +145 -0
  65. package/apps/server/dist/infrastructure/graph/GraphifyKnowledgeGraph.js.map +1 -0
  66. package/apps/server/dist/infrastructure/graph/index.js +3 -0
  67. package/apps/server/dist/infrastructure/graph/index.js.map +1 -0
  68. package/apps/server/dist/infrastructure/persistence/sqlite/SqliteBuildRepository.js +21 -0
  69. package/apps/server/dist/infrastructure/persistence/sqlite/SqliteBuildRepository.js.map +1 -0
  70. package/apps/server/dist/infrastructure/persistence/sqlite/SqliteEntryReadModel.js +11 -0
  71. package/apps/server/dist/infrastructure/persistence/sqlite/SqliteEntryReadModel.js.map +1 -0
  72. package/apps/server/dist/infrastructure/persistence/sqlite/SqliteEntryRepository.js +59 -0
  73. package/apps/server/dist/infrastructure/persistence/sqlite/SqliteEntryRepository.js.map +1 -0
  74. package/apps/server/dist/infrastructure/persistence/sqlite/SqliteSourceRepository.js +47 -0
  75. package/apps/server/dist/infrastructure/persistence/sqlite/SqliteSourceRepository.js.map +1 -0
  76. package/apps/server/dist/infrastructure/persistence/sqlite/connection.js +50 -0
  77. package/apps/server/dist/infrastructure/persistence/sqlite/connection.js.map +1 -0
  78. package/apps/server/dist/infrastructure/search/SearchEngineFactory.js +32 -0
  79. package/apps/server/dist/infrastructure/search/SearchEngineFactory.js.map +1 -0
  80. package/apps/server/dist/infrastructure/search/json/JsonSearchEngine.js +147 -0
  81. package/apps/server/dist/infrastructure/search/json/JsonSearchEngine.js.map +1 -0
  82. package/apps/server/dist/infrastructure/search/vector/EmbeddingService.js +23 -0
  83. package/apps/server/dist/infrastructure/search/vector/EmbeddingService.js.map +1 -0
  84. package/apps/server/dist/infrastructure/search/vector/VectorSearchEngine.js +378 -0
  85. package/apps/server/dist/infrastructure/search/vector/VectorSearchEngine.js.map +1 -0
  86. package/apps/server/dist/infrastructure/source-processors/AntoraSourceProcessor.js +11 -0
  87. package/apps/server/dist/infrastructure/source-processors/AntoraSourceProcessor.js.map +1 -0
  88. package/apps/server/dist/infrastructure/source-processors/AsciidocSourceProcessor.js +9 -0
  89. package/apps/server/dist/infrastructure/source-processors/AsciidocSourceProcessor.js.map +1 -0
  90. package/apps/server/dist/infrastructure/source-processors/DocumentNormalizer.js +11 -0
  91. package/apps/server/dist/infrastructure/source-processors/DocumentNormalizer.js.map +1 -0
  92. package/apps/server/dist/infrastructure/source-processors/GithubMarkdownSourceProcessor.js +9 -0
  93. package/apps/server/dist/infrastructure/source-processors/GithubMarkdownSourceProcessor.js.map +1 -0
  94. package/apps/server/dist/infrastructure/source-processors/MavenSourceProcessor.js +9 -0
  95. package/apps/server/dist/infrastructure/source-processors/MavenSourceProcessor.js.map +1 -0
  96. package/apps/server/dist/infrastructure/source-processors/PathResolver.js +5 -0
  97. package/apps/server/dist/infrastructure/source-processors/PathResolver.js.map +1 -0
  98. package/apps/server/dist/infrastructure/source-processors/SourceCodeSourceProcessor.js +269 -0
  99. package/apps/server/dist/infrastructure/source-processors/SourceCodeSourceProcessor.js.map +1 -0
  100. package/apps/server/dist/infrastructure/source-processors/ZipSourceProcessor.js +9 -0
  101. package/apps/server/dist/infrastructure/source-processors/ZipSourceProcessor.js.map +1 -0
  102. package/apps/server/dist/mcp-http.js +93 -0
  103. package/apps/server/dist/mcp-http.js.map +1 -0
  104. package/apps/server/dist/mcp.js +339 -0
  105. package/apps/server/dist/mcp.js.map +1 -0
  106. package/apps/server/dist/routes/build.js +89 -0
  107. package/apps/server/dist/routes/build.js.map +1 -0
  108. package/apps/server/dist/routes/entries.js +52 -0
  109. package/apps/server/dist/routes/entries.js.map +1 -0
  110. package/apps/server/dist/routes/graph.js +58 -0
  111. package/apps/server/dist/routes/graph.js.map +1 -0
  112. package/apps/server/dist/routes/search.js +24 -0
  113. package/apps/server/dist/routes/search.js.map +1 -0
  114. package/apps/server/dist/routes/sources.js +100 -0
  115. package/apps/server/dist/routes/sources.js.map +1 -0
  116. package/apps/server/dist/routes/viewer.js +22 -0
  117. package/apps/server/dist/routes/viewer.js.map +1 -0
  118. package/apps/server/dist/services/antora.js +222 -0
  119. package/apps/server/dist/services/antora.js.map +1 -0
  120. package/apps/server/dist/services/asciidoc.js +206 -0
  121. package/apps/server/dist/services/asciidoc.js.map +1 -0
  122. package/apps/server/dist/services/configLoader.js +150 -0
  123. package/apps/server/dist/services/configLoader.js.map +1 -0
  124. package/apps/server/dist/services/githubMarkdown.js +221 -0
  125. package/apps/server/dist/services/githubMarkdown.js.map +1 -0
  126. package/apps/server/dist/services/maven.js +148 -0
  127. package/apps/server/dist/services/maven.js.map +1 -0
  128. package/apps/server/dist/services/normalizer.js +42 -0
  129. package/apps/server/dist/services/normalizer.js.map +1 -0
  130. package/apps/server/dist/services/paths.js +5 -0
  131. package/apps/server/dist/services/paths.js.map +1 -0
  132. package/apps/server/dist/services/textExtractor.js +46 -0
  133. package/apps/server/dist/services/textExtractor.js.map +1 -0
  134. package/apps/server/dist/services/zip.js +63 -0
  135. package/apps/server/dist/services/zip.js.map +1 -0
  136. package/apps/server/package.json +38 -0
  137. package/apps/server/src/infrastructure/source-processors/SourceCodeSourceProcessor.ts +9 -2
  138. package/bin/commands/dev.ts +2 -2
  139. package/bin/commands/serve.ts +2 -2
  140. package/package.json +22 -4
@@ -0,0 +1,339 @@
1
+ import { McpServer, StdioServerTransport, fromJsonSchema } from '@modelcontextprotocol/server';
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ import { loadConfig, syncConfigToDb } from './services/configLoader.js';
5
+ import { getDb } from './infrastructure/persistence/sqlite/connection.js';
6
+ import { SqliteEntryRepository } from './infrastructure/persistence/sqlite/SqliteEntryRepository.js';
7
+ import { SqliteSourceRepository } from './infrastructure/persistence/sqlite/SqliteSourceRepository.js';
8
+ import { SqliteBuildRepository } from './infrastructure/persistence/sqlite/SqliteBuildRepository.js';
9
+ import { SqliteEntryReadModel } from './infrastructure/persistence/sqlite/SqliteEntryReadModel.js';
10
+ import { createSearchEngine } from './infrastructure/search/SearchEngineFactory.js';
11
+ import { SearchUseCase } from './core/usecases/SearchUseCase.js';
12
+ import { BuildUseCase } from './core/usecases/BuildUseCase.js';
13
+ import { ConfigUseCase } from './core/usecases/ConfigUseCase.js';
14
+ import { FileSystemDocumentStore } from './infrastructure/filesystem/FileSystemDocumentStore.js';
15
+ import { extractTextFromHtml } from './services/textExtractor.js';
16
+ import { ZipSourceProcessor } from './infrastructure/source-processors/ZipSourceProcessor.js';
17
+ import { AntoraSourceProcessor } from './infrastructure/source-processors/AntoraSourceProcessor.js';
18
+ import { AsciidocSourceProcessor } from './infrastructure/source-processors/AsciidocSourceProcessor.js';
19
+ import { MavenSourceProcessor } from './infrastructure/source-processors/MavenSourceProcessor.js';
20
+ import { GithubMarkdownSourceProcessor } from './infrastructure/source-processors/GithubMarkdownSourceProcessor.js';
21
+ import { SourceCodeSourceProcessor } from './infrastructure/source-processors/SourceCodeSourceProcessor.js';
22
+ import { DocumentNormalizer } from './infrastructure/source-processors/DocumentNormalizer.js';
23
+ import { PathResolver } from './infrastructure/source-processors/PathResolver.js';
24
+ import { GraphifyKnowledgeGraph } from './infrastructure/graph/GraphifyKnowledgeGraph.js';
25
+ import { DATA_ROOT } from './services/paths.js';
26
+ let configPath = path.join(DATA_ROOT, 'dockit.yaml');
27
+ if (!fs.existsSync(configPath)) {
28
+ configPath = path.join(process.cwd(), 'dockit.yaml');
29
+ }
30
+ const config = loadConfig(configPath);
31
+ const toolPrefix = config.mcp?.toolPrefix || 'dockit_';
32
+ const maxResults = config.mcp?.maxSearchResults || 10;
33
+ async function main() {
34
+ const db = getDb();
35
+ const entryRepo = new SqliteEntryRepository(db);
36
+ const sourceRepo = new SqliteSourceRepository(db);
37
+ const buildRepo = new SqliteBuildRepository(db);
38
+ await syncConfigToDb(config, entryRepo, sourceRepo);
39
+ const entryReadModel = new SqliteEntryReadModel(db);
40
+ const searchEngine = await createSearchEngine(entryReadModel, config.search?.engine);
41
+ const configUseCase = new ConfigUseCase(entryRepo, sourceRepo);
42
+ const searchUseCase = new SearchUseCase(searchEngine);
43
+ const processors = [
44
+ new ZipSourceProcessor(),
45
+ new AntoraSourceProcessor(),
46
+ new AsciidocSourceProcessor(),
47
+ new MavenSourceProcessor(),
48
+ new GithubMarkdownSourceProcessor(),
49
+ new SourceCodeSourceProcessor(),
50
+ ];
51
+ const documentNormalizer = new DocumentNormalizer();
52
+ const pathResolver = new PathResolver();
53
+ const buildUseCase = new BuildUseCase(buildRepo, sourceRepo, entryRepo, searchEngine, processors, documentNormalizer, pathResolver);
54
+ const docStore = new FileSystemDocumentStore();
55
+ if (config.mcp?.autoBuild) {
56
+ console.error('[dockit] Auto-building all entries...');
57
+ for (const entryConfig of config.entries) {
58
+ try {
59
+ const result = await buildUseCase.build(entryConfig.id);
60
+ console.error(`[dockit] ${entryConfig.id}: ${result.status}`);
61
+ }
62
+ catch (err) {
63
+ console.error(`[dockit] ${entryConfig.id}: build error - ${err.message}`);
64
+ }
65
+ }
66
+ }
67
+ const server = new McpServer({
68
+ name: 'dockit',
69
+ version: '1.0.0',
70
+ });
71
+ server.registerTool(`${toolPrefix}list_entries`, {
72
+ description: 'List all available documentation entries with their status and source count.',
73
+ }, async () => {
74
+ const entries = await configUseCase.listEntries();
75
+ return {
76
+ content: [{ type: 'text', text: JSON.stringify(entries, null, 2) }],
77
+ };
78
+ });
79
+ server.registerTool(`${toolPrefix}search`, {
80
+ description: 'Search through built documentation for a specific entry. Returns document paths, titles, and text snippets matching the query. Use this to find relevant documents before fetching full content.',
81
+ inputSchema: fromJsonSchema({
82
+ type: 'object',
83
+ properties: {
84
+ entry: { type: 'string', description: 'Entry ID to search (use dockit_list_entries to discover available IDs)' },
85
+ query: { type: 'string', description: 'Search query string. Case-insensitive keyword matching across titles, headings, and body text.' },
86
+ maxResults: { type: 'number', description: `Maximum number of results to return (1-20, default ${maxResults})` },
87
+ },
88
+ required: ['entry', 'query'],
89
+ }),
90
+ }, async ({ entry, query, maxResults: limit }) => {
91
+ const entryStr = entry;
92
+ const queryStr = query;
93
+ const resultLimit = Math.min(Math.max(1, limit || maxResults), 20);
94
+ if (!entryStr || !queryStr) {
95
+ return {
96
+ content: [{ type: 'text', text: 'Error: entry and query are required' }],
97
+ isError: true,
98
+ };
99
+ }
100
+ const results = await searchUseCase.searchEntry(entryStr, queryStr, resultLimit);
101
+ return {
102
+ content: [{ type: 'text', text: JSON.stringify(results, null, 2) }],
103
+ };
104
+ });
105
+ server.registerTool(`${toolPrefix}get_doc`, {
106
+ description: 'Retrieve the full text content of a specific documentation file. Returns plain text extracted from the built HTML. Use this after dockit_search to get the complete content of relevant documents.',
107
+ inputSchema: fromJsonSchema({
108
+ type: 'object',
109
+ properties: {
110
+ entry: { type: 'string', description: 'Entry ID that owns the document' },
111
+ path: { type: 'string', description: 'Document path as returned by dockit_search (e.g. "asciidoc/rest-json.html")' },
112
+ },
113
+ required: ['entry', 'path'],
114
+ }),
115
+ }, async ({ entry, path: docPath }) => {
116
+ const entryStr = entry;
117
+ const docPathStr = docPath;
118
+ if (!entryStr || !docPathStr) {
119
+ return {
120
+ content: [{ type: 'text', text: 'Error: entry and path are required' }],
121
+ isError: true,
122
+ };
123
+ }
124
+ const exists = await docStore.documentExists(entryStr, docPathStr);
125
+ if (!exists) {
126
+ return {
127
+ content: [{ type: 'text', text: `Document not found: ${docPathStr}. Has the entry been built?` }],
128
+ isError: true,
129
+ };
130
+ }
131
+ const html = await docStore.getDocument(entryStr, docPathStr);
132
+ const text = extractTextFromHtml(html);
133
+ return {
134
+ content: [{ type: 'text', text }],
135
+ };
136
+ });
137
+ server.registerTool(`${toolPrefix}build`, {
138
+ description: 'Build or rebuild documentation for an entry. This clones repos, downloads artifacts, and converts sources to HTML. Build status can be checked with dockit_build_status.',
139
+ inputSchema: fromJsonSchema({
140
+ type: 'object',
141
+ properties: {
142
+ entry: { type: 'string', description: 'Entry ID to build' },
143
+ },
144
+ required: ['entry'],
145
+ }),
146
+ }, async ({ entry }) => {
147
+ const entryStr = entry;
148
+ if (!entryStr) {
149
+ return {
150
+ content: [{ type: 'text', text: 'Error: entry is required' }],
151
+ isError: true,
152
+ };
153
+ }
154
+ const entryRecord = await configUseCase.getEntry(entryStr);
155
+ if (!entryRecord) {
156
+ return {
157
+ content: [{ type: 'text', text: `Entry not found: ${entryStr}` }],
158
+ isError: true,
159
+ };
160
+ }
161
+ if (entryRecord.status === 'building') {
162
+ return {
163
+ content: [{ type: 'text', text: `Build already in progress for ${entryStr}` }],
164
+ };
165
+ }
166
+ buildUseCase.build(entryStr).then((result) => {
167
+ console.error(`[dockit] Build ${entryStr}: ${result.status}`);
168
+ });
169
+ return {
170
+ content: [{ type: 'text', text: JSON.stringify({ entry: entryStr, status: 'building', message: 'Build started. Check status with dockit_build_status.' }) }],
171
+ };
172
+ });
173
+ server.registerTool(`${toolPrefix}build_status`, {
174
+ description: 'Check the build status of an entry. Returns status (pending/building/ready/error) and the build log.',
175
+ inputSchema: fromJsonSchema({
176
+ type: 'object',
177
+ properties: {
178
+ entry: { type: 'string', description: 'Entry ID to check' },
179
+ },
180
+ required: ['entry'],
181
+ }),
182
+ }, async ({ entry }) => {
183
+ const entryStr = entry;
184
+ if (!entryStr) {
185
+ return {
186
+ content: [{ type: 'text', text: 'Error: entry is required' }],
187
+ isError: true,
188
+ };
189
+ }
190
+ const build = await buildRepo.findLatest(entryStr);
191
+ if (!build) {
192
+ return {
193
+ content: [{ type: 'text', text: JSON.stringify({ status: 'none', message: 'No builds found for this entry' }) }],
194
+ };
195
+ }
196
+ return {
197
+ content: [{ type: 'text', text: JSON.stringify({
198
+ status: build.status,
199
+ startedAt: build.started_at,
200
+ finishedAt: build.finished_at,
201
+ log: build.log.slice(-2000),
202
+ }, null, 2) }],
203
+ };
204
+ });
205
+ server.registerTool(`${toolPrefix}find_entry`, {
206
+ description: 'Find documentation entries by name or description. Returns matching entries with their IDs and status. Use this when you do not know the entry ID.',
207
+ inputSchema: fromJsonSchema({
208
+ type: 'object',
209
+ properties: {
210
+ query: { type: 'string', description: 'Search query to match against entry name or description (case-insensitive substring match)' },
211
+ },
212
+ required: ['query'],
213
+ }),
214
+ }, async ({ query }) => {
215
+ const queryStr = query.toLowerCase();
216
+ const entries = await entryRepo.findAll();
217
+ const filtered = entries.filter((e) => e.name.toLowerCase().includes(queryStr) ||
218
+ (e.description || '').toLowerCase().includes(queryStr));
219
+ return {
220
+ content: [{ type: 'text', text: JSON.stringify(filtered, null, 2) }],
221
+ };
222
+ });
223
+ server.registerTool(`${toolPrefix}global_search`, {
224
+ description: 'Search across ALL built documentation entries at once. No entry ID required. Returns aggregated results from every ready entry. Use this for broad discovery when you do not know which entry contains the answer.',
225
+ inputSchema: fromJsonSchema({
226
+ type: 'object',
227
+ properties: {
228
+ query: { type: 'string', description: 'Search query string. Case-insensitive keyword matching across titles, headings, and body text of ALL entries.' },
229
+ maxResults: { type: 'number', description: `Maximum total results to return across all entries (1-50, default ${maxResults * 2})` },
230
+ },
231
+ required: ['query'],
232
+ }),
233
+ }, async ({ query, maxResults: limit }) => {
234
+ const queryStr = query;
235
+ const resultLimit = Math.min(Math.max(1, limit || maxResults * 2), 50);
236
+ if (!queryStr) {
237
+ return {
238
+ content: [{ type: 'text', text: 'Error: query is required' }],
239
+ isError: true,
240
+ };
241
+ }
242
+ const results = await searchUseCase.globalSearch(queryStr, resultLimit);
243
+ return {
244
+ content: [{ type: 'text', text: JSON.stringify(results, null, 2) }],
245
+ };
246
+ });
247
+ function getKnowledgeGraph(entryId) {
248
+ return new GraphifyKnowledgeGraph(path.join(DATA_ROOT, entryId));
249
+ }
250
+ server.registerTool(`${toolPrefix}graph_query`, {
251
+ description: 'Search the knowledge graph for an entry. Returns nodes and edges matching the query. Use this instead of dockit_search for source-code-only entries.',
252
+ inputSchema: fromJsonSchema({
253
+ type: 'object',
254
+ properties: {
255
+ entry: { type: 'string', description: 'Entry ID with a built knowledge graph' },
256
+ query: { type: 'string', description: 'Text to match against node names, file paths, or types' },
257
+ limit: { type: 'number', description: 'Maximum nodes to return (default 20)' },
258
+ },
259
+ required: ['entry', 'query'],
260
+ }),
261
+ }, async ({ entry, query, limit: max }) => {
262
+ const kg = getKnowledgeGraph(entry);
263
+ if (!kg.exists()) {
264
+ return { content: [{ type: 'text', text: 'No knowledge graph found. Build the entry first.' }], isError: true };
265
+ }
266
+ const result = kg.query(query, max || 20);
267
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
268
+ });
269
+ server.registerTool(`${toolPrefix}graph_path`, {
270
+ description: 'Find the shortest dependency path between two nodes in the knowledge graph.',
271
+ inputSchema: fromJsonSchema({
272
+ type: 'object',
273
+ properties: {
274
+ entry: { type: 'string', description: 'Entry ID with a built knowledge graph' },
275
+ from: { type: 'string', description: 'Starting node name or ID' },
276
+ to: { type: 'string', description: 'Target node name or ID' },
277
+ },
278
+ required: ['entry', 'from', 'to'],
279
+ }),
280
+ }, async ({ entry, from, to }) => {
281
+ const kg = getKnowledgeGraph(entry);
282
+ if (!kg.exists()) {
283
+ return { content: [{ type: 'text', text: 'No knowledge graph found. Build the entry first.' }], isError: true };
284
+ }
285
+ const result = kg.findPath(from, to);
286
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
287
+ });
288
+ server.registerTool(`${toolPrefix}graph_explain`, {
289
+ description: 'Get details about a specific node in the knowledge graph, including its edges and connections.',
290
+ inputSchema: fromJsonSchema({
291
+ type: 'object',
292
+ properties: {
293
+ entry: { type: 'string', description: 'Entry ID with a built knowledge graph' },
294
+ node: { type: 'string', description: 'Node name or ID' },
295
+ },
296
+ required: ['entry', 'node'],
297
+ }),
298
+ }, async ({ entry, node }) => {
299
+ const kg = getKnowledgeGraph(entry);
300
+ if (!kg.exists()) {
301
+ return { content: [{ type: 'text', text: 'No knowledge graph found. Build the entry first.' }], isError: true };
302
+ }
303
+ const queryResult = kg.query(node);
304
+ const result = {
305
+ node: queryResult.nodes[0] || null,
306
+ connectedNodes: queryResult.nodes.slice(1),
307
+ edges: queryResult.edges,
308
+ totalConnections: queryResult.totalEdges,
309
+ };
310
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
311
+ });
312
+ server.registerTool(`${toolPrefix}graph_gods`, {
313
+ description: 'List the most connected nodes (God Nodes) in the knowledge graph. These are the most important classes or modules.',
314
+ inputSchema: fromJsonSchema({
315
+ type: 'object',
316
+ properties: {
317
+ entry: { type: 'string', description: 'Entry ID with a built knowledge graph' },
318
+ limit: { type: 'number', description: 'Number of god nodes to return (default 10)' },
319
+ },
320
+ required: ['entry'],
321
+ }),
322
+ }, async ({ entry, limit: max }) => {
323
+ const kg = getKnowledgeGraph(entry);
324
+ if (!kg.exists()) {
325
+ return { content: [{ type: 'text', text: 'No knowledge graph found. Build the entry first.' }], isError: true };
326
+ }
327
+ const nodes = kg.findGodNodes(max || 10);
328
+ const meta = kg.getMetadata();
329
+ return { content: [{ type: 'text', text: JSON.stringify({ nodes, metadata: meta }, null, 2) }] };
330
+ });
331
+ const transport = new StdioServerTransport();
332
+ await server.connect(transport);
333
+ console.error('[dockit] MCP server ready');
334
+ }
335
+ main().catch((err) => {
336
+ console.error('Failed to start MCP server:', err);
337
+ process.exit(1);
338
+ });
339
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import { Router } from 'express';
2
+ export function createBuildRoutes(buildUseCase, configUseCase, buildRepo) {
3
+ const router = Router();
4
+ router.post('/entries/:id/build', async (req, res) => {
5
+ const entryId = req.params.id;
6
+ const entry = await configUseCase.getEntry(entryId);
7
+ if (!entry) {
8
+ res.status(404).json({ error: 'Entry not found' });
9
+ return;
10
+ }
11
+ const entryWithSources = await configUseCase.getEntryWithSources(entryId);
12
+ if (!entryWithSources || entryWithSources.sources.length === 0) {
13
+ res.status(400).json({ error: 'Entry has no sources' });
14
+ return;
15
+ }
16
+ res.status(202).json({ buildId: 'pending', status: 'building' });
17
+ buildUseCase.build(entryId).catch((err) => {
18
+ console.error('Build error:', err);
19
+ });
20
+ });
21
+ router.get('/entries/:id/build-status', async (req, res) => {
22
+ const entryId = req.params.id;
23
+ const build = await buildRepo.findLatest(entryId);
24
+ if (!build) {
25
+ res.json({ status: 'none', log: '' });
26
+ return;
27
+ }
28
+ res.json({ status: build.status, log: build.log, startedAt: build.started_at, finishedAt: build.finished_at });
29
+ });
30
+ router.get('/entries/:id/cli-script', async (req, res) => {
31
+ const entryId = req.params.id;
32
+ const entry = await configUseCase.getEntry(entryId);
33
+ if (!entry) {
34
+ res.status(404).json({ error: 'Entry not found' });
35
+ return;
36
+ }
37
+ const entryWithSources = await configUseCase.getEntryWithSources(entryId);
38
+ const sources = entryWithSources?.sources ?? [];
39
+ let script = `#!/bin/bash\n# Dockit build script for entry: ${entry.name} ${entry.version}\n# Generated: ${new Date().toISOString()}\nset -e\n\nAPI_URL="http://localhost:3001"\nENTRY_ID="${entry.id}"\n\necho "Building documentation for ${entry.name} ${entry.version}"\necho ""\n\n`;
40
+ let stepNum = 1;
41
+ for (const source of sources) {
42
+ script += `# Step ${stepNum}: Process source "${source.label}" [${source.type}]\n`;
43
+ switch (source.type) {
44
+ case 'zip': {
45
+ const config = source.config;
46
+ script += `echo " Downloading ZIP from ${config.url}..."\n`;
47
+ script += `curl -o /tmp/dockit-source-${source.id}.zip "${config.url}"\n\n`;
48
+ break;
49
+ }
50
+ case 'maven': {
51
+ const config = source.config;
52
+ const groupPath = config.groupId.replace(/\./g, '/');
53
+ const classifier = config.classifier || 'javadoc';
54
+ const mavenUrl = `https://repo1.maven.org/maven2/${groupPath}/${config.artifactId}/${config.version}/${config.artifactId}-${config.version}-${classifier}.jar`;
55
+ script += `echo " Downloading Maven artifact: ${config.groupId}:${config.artifactId}:${config.version}"\n`;
56
+ script += `curl -o /tmp/dockit-source-${source.id}.jar "${mavenUrl}"\n\n`;
57
+ break;
58
+ }
59
+ case 'antora': {
60
+ const config = source.config;
61
+ if (config.repoUrl) {
62
+ script += `echo " Cloning repository: ${config.repoUrl}"\n`;
63
+ script += `git clone --depth 1 "${config.repoUrl}" /tmp/dockit-antora-${source.id}\n`;
64
+ script += `pushd /tmp/dockit-antora-${source.id}\n`;
65
+ script += `npx antora --to-dir /tmp/dockit-antora-output-${source.id} playbook.yml 2>&1 || echo "Note: run 'npx antora generate-playbook' first if needed"\n`;
66
+ script += `popd\n\n`;
67
+ }
68
+ break;
69
+ }
70
+ case 'asciidoc': {
71
+ const config = source.config;
72
+ if (config.repoUrl) {
73
+ script += `echo " Cloning repository: ${config.repoUrl}"\n`;
74
+ script += `git clone --depth 1 "${config.repoUrl}" /tmp/dockit-asciidoc-${source.id}\n`;
75
+ script += `npx asciidoctor -R /tmp/dockit-asciidoc-${source.id} $(find /tmp/dockit-asciidoc-${source.id} -name '*.adoc') 2>&1 || echo "Note: requires asciidoctor js"\n\n`;
76
+ }
77
+ break;
78
+ }
79
+ }
80
+ stepNum++;
81
+ }
82
+ script += `echo ""\necho "To trigger server-side build, run:"\necho " curl -X POST \\"$API_URL/api/entries/$ENTRY_ID/build\\""\n`;
83
+ res.setHeader('Content-Type', 'text/plain; charset=utf-8');
84
+ res.setHeader('Content-Disposition', `attachment; filename="dockit-build-${entry.name.toLowerCase().replace(/[^a-z0-9]+/g, '-')}.sh"`);
85
+ res.send(script);
86
+ });
87
+ return router;
88
+ }
89
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/routes/build.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAMpD,MAAM,UAAU,iBAAiB,CAAC,YAA0B,EAAE,aAA4B,EAAE,SAA2B;IACrH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACtE,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,EAAY,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,aAAa,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC1E,IAAI,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QAEjE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACxC,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC5E,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,EAAY,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IACjH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC1E,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,EAAY,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,aAAa,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,gBAAgB,EAAE,OAAO,IAAI,EAAE,CAAC;QAEhD,IAAI,MAAM,GAAG,iDAAiD,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,kBAAkB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,0DAA0D,KAAK,CAAC,EAAE,yCAAyC,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,gBAAgB,CAAC;QAE1R,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,IAAI,UAAU,OAAO,qBAAqB,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,IAAI,KAAK,CAAC;YACnF,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;gBACpB,KAAK,KAAK,CAAC,CAAC,CAAC;oBACX,MAAM,MAAM,GAAG,MAAM,CAAC,MAAyB,CAAC;oBAChD,MAAM,IAAI,gCAAgC,MAAM,CAAC,GAAG,QAAQ,CAAC;oBAC7D,MAAM,IAAI,8BAA8B,MAAM,CAAC,EAAE,SAAS,MAAM,CAAC,GAAG,OAAO,CAAC;oBAC5E,MAAM;gBACR,CAAC;gBACD,KAAK,OAAO,CAAC,CAAC,CAAC;oBACb,MAAM,MAAM,GAAG,MAAM,CAAC,MAA2B,CAAC;oBAClD,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;oBACrD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,SAAS,CAAC;oBAClD,MAAM,QAAQ,GAAG,kCAAkC,SAAS,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,OAAO,IAAI,UAAU,MAAM,CAAC;oBAC/J,MAAM,IAAI,uCAAuC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,OAAO,KAAK,CAAC;oBAC5G,MAAM,IAAI,8BAA8B,MAAM,CAAC,EAAE,SAAS,QAAQ,OAAO,CAAC;oBAC1E,MAAM;gBACR,CAAC;gBACD,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,MAAM,MAAM,GAAG,MAAM,CAAC,MAA4B,CAAC;oBACnD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACnB,MAAM,IAAI,+BAA+B,MAAM,CAAC,OAAO,KAAK,CAAC;wBAC7D,MAAM,IAAI,wBAAwB,MAAM,CAAC,OAAO,wBAAwB,MAAM,CAAC,EAAE,IAAI,CAAC;wBACtF,MAAM,IAAI,4BAA4B,MAAM,CAAC,EAAE,IAAI,CAAC;wBACpD,MAAM,IAAI,iDAAiD,MAAM,CAAC,EAAE,yFAAyF,CAAC;wBAC9J,MAAM,IAAI,UAAU,CAAC;oBACvB,CAAC;oBACD,MAAM;gBACR,CAAC;gBACD,KAAK,UAAU,CAAC,CAAC,CAAC;oBAChB,MAAM,MAAM,GAAG,MAAM,CAAC,MAA8B,CAAC;oBACrD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACnB,MAAM,IAAI,+BAA+B,MAAM,CAAC,OAAO,KAAK,CAAC;wBAC7D,MAAM,IAAI,wBAAwB,MAAM,CAAC,OAAO,0BAA0B,MAAM,CAAC,EAAE,IAAI,CAAC;wBACxF,MAAM,IAAI,2CAA2C,MAAM,CAAC,EAAE,gCAAgC,MAAM,CAAC,EAAE,mEAAmE,CAAC;oBAC7K,CAAC;oBACD,MAAM;gBACR,CAAC;YACH,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,IAAI,wHAAwH,CAAC;QAEnI,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,2BAA2B,CAAC,CAAC;QAC3D,GAAG,CAAC,SAAS,CAAC,qBAAqB,EAAE,sCAAsC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACvI,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { Router } from 'express';
2
+ export function createEntryRoutes(configUseCase) {
3
+ const router = Router();
4
+ router.get('/', async (_req, res) => {
5
+ const entries = await configUseCase.listEntries();
6
+ res.json(entries);
7
+ });
8
+ router.get('/:id', async (req, res) => {
9
+ const id = req.params.id;
10
+ const entry = await configUseCase.getEntryWithSources(id);
11
+ if (!entry) {
12
+ res.status(404).json({ error: 'Entry not found' });
13
+ return;
14
+ }
15
+ const db = (await import('../infrastructure/persistence/sqlite/connection.js')).getDb();
16
+ const latestBuild = db.prepare('SELECT * FROM builds WHERE entry_id = ? ORDER BY started_at DESC LIMIT 1').get(id);
17
+ res.json({ ...entry, latestBuild });
18
+ });
19
+ router.post('/', async (req, res) => {
20
+ const { name, version, description } = req.body;
21
+ if (!name || !version) {
22
+ res.status(400).json({ error: 'name and version are required' });
23
+ return;
24
+ }
25
+ const entry = await configUseCase.createEntry({ name, version, description });
26
+ res.status(201).json(entry);
27
+ });
28
+ router.put('/:id', async (req, res) => {
29
+ const id = req.params.id;
30
+ const existing = await configUseCase.getEntry(id);
31
+ if (!existing) {
32
+ res.status(404).json({ error: 'Entry not found' });
33
+ return;
34
+ }
35
+ const input = req.body;
36
+ await configUseCase.updateEntry(id, input);
37
+ const entry = await configUseCase.getEntry(id);
38
+ res.json(entry);
39
+ });
40
+ router.delete('/:id', async (req, res) => {
41
+ const id = req.params.id;
42
+ const existing = await configUseCase.getEntry(id);
43
+ if (!existing) {
44
+ res.status(404).json({ error: 'Entry not found' });
45
+ return;
46
+ }
47
+ await configUseCase.deleteEntry(id);
48
+ res.json({ success: true });
49
+ });
50
+ return router;
51
+ }
52
+ //# sourceMappingURL=entries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entries.js","sourceRoot":"","sources":["../../src/routes/entries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { Router } from 'express';
2
+ import { GraphifyKnowledgeGraph } from '../infrastructure/graph/GraphifyKnowledgeGraph.js';
3
+ import { DATA_ROOT } from '../services/paths.js';
4
+ import path from 'node:path';
5
+ export function createGraphRoutes(buildRepo, configUseCase) {
6
+ const router = Router();
7
+ router.get('/graph/:entry/query', async (req, res) => {
8
+ try {
9
+ const { entry } = req.params;
10
+ const q = req.query.q;
11
+ const limit = parseInt(req.query.limit, 10) || 20;
12
+ if (!q)
13
+ return res.status(400).json({ error: 'query parameter "q" is required' });
14
+ const kg = new GraphifyKnowledgeGraph(path.join(DATA_ROOT, entry));
15
+ if (!kg.exists())
16
+ return res.status(404).json({ error: 'No knowledge graph found. Build the entry first.' });
17
+ const result = kg.query(q, limit);
18
+ res.json(result);
19
+ }
20
+ catch (err) {
21
+ res.status(500).json({ error: err.message });
22
+ }
23
+ });
24
+ router.get('/graph/:entry/path', async (req, res) => {
25
+ try {
26
+ const { entry } = req.params;
27
+ const from = req.query.from;
28
+ const to = req.query.to;
29
+ if (!from || !to)
30
+ return res.status(400).json({ error: '"from" and "to" query parameters are required' });
31
+ const kg = new GraphifyKnowledgeGraph(path.join(DATA_ROOT, entry));
32
+ if (!kg.exists())
33
+ return res.status(404).json({ error: 'No knowledge graph found. Build the entry first.' });
34
+ const result = kg.findPath(from, to);
35
+ res.json(result);
36
+ }
37
+ catch (err) {
38
+ res.status(500).json({ error: err.message });
39
+ }
40
+ });
41
+ router.get('/graph/:entry/gods', async (req, res) => {
42
+ try {
43
+ const { entry } = req.params;
44
+ const limit = parseInt(req.query.limit, 10) || 10;
45
+ const kg = new GraphifyKnowledgeGraph(path.join(DATA_ROOT, entry));
46
+ if (!kg.exists())
47
+ return res.status(404).json({ error: 'No knowledge graph found. Build the entry first.' });
48
+ const nodes = kg.findGodNodes(limit);
49
+ const meta = kg.getMetadata();
50
+ res.json({ nodes, metadata: meta });
51
+ }
52
+ catch (err) {
53
+ res.status(500).json({ error: err.message });
54
+ }
55
+ });
56
+ return router;
57
+ }
58
+ //# sourceMappingURL=graph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/routes/graph.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,mDAAmD,CAAC;AAC3F,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,UAAU,iBAAiB,CAC/B,SAAc,EACd,aAAkB;IAElB,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACnD,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;YAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAW,CAAC;YAChC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAe,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;YAC5D,IAAI,CAAC,CAAC;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;YAClF,MAAM,EAAE,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC,CAAC;YAC7G,MAAM,MAAM,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAClD,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;YAC7B,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAc,CAAC;YACtC,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,EAAY,CAAC;YAClC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+CAA+C,EAAE,CAAC,CAAC;YAC1G,MAAM,EAAE,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC,CAAC;YAC7G,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACrC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QAClD,IAAI,CAAC;YACH,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC;YAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAe,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;YAC5D,MAAM,EAAE,GAAG,IAAI,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;gBAAE,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC,CAAC;YAC7G,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YACrC,MAAM,IAAI,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { Router } from 'express';
2
+ export function createSearchRoutes(searchUseCase) {
3
+ const router = Router();
4
+ router.get('/entries/:id/search', async (req, res) => {
5
+ const q = req.query.q || '';
6
+ if (!q) {
7
+ res.json([]);
8
+ return;
9
+ }
10
+ const results = await searchUseCase.searchEntry(req.params.id, q, 20);
11
+ res.json(results);
12
+ });
13
+ router.get('/search', async (req, res) => {
14
+ const q = req.query.q || '';
15
+ if (!q) {
16
+ res.json([]);
17
+ return;
18
+ }
19
+ const results = await searchUseCase.globalSearch(q, 30);
20
+ res.json(results);
21
+ });
22
+ return router;
23
+ }
24
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/routes/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAqB,MAAM,SAAS,CAAC;AAGpD,MAAM,UAAU,kBAAkB,CAAC,aAA4B;IAC7D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;IAExB,MAAM,CAAC,GAAG,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QACtE,MAAM,CAAC,GAAI,GAAG,CAAC,KAAK,CAAC,CAAY,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAY,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;QAChF,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,EAAE;QAC1D,MAAM,CAAC,GAAI,GAAG,CAAC,KAAK,CAAC,CAAY,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACb,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,YAAY,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACxD,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}