hoolix 0.0.1-beta.19
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/LICENSE +21 -0
- package/README.md +337 -0
- package/STABILITY.md +109 -0
- package/bin/hoolix.js +50 -0
- package/bin/mcp-portal.js +12 -0
- package/bin/postinstall.js +61 -0
- package/dist/app/contracts.d.ts +105 -0
- package/dist/app/contracts.d.ts.map +1 -0
- package/dist/app/contracts.js +2 -0
- package/dist/app/contracts.js.map +1 -0
- package/dist/app/events.d.ts +13 -0
- package/dist/app/events.d.ts.map +1 -0
- package/dist/app/events.js +13 -0
- package/dist/app/events.js.map +1 -0
- package/dist/app/services/analytics.d.ts +42 -0
- package/dist/app/services/analytics.d.ts.map +1 -0
- package/dist/app/services/analytics.js +106 -0
- package/dist/app/services/analytics.js.map +1 -0
- package/dist/app/services/catalog.d.ts +14 -0
- package/dist/app/services/catalog.d.ts.map +1 -0
- package/dist/app/services/catalog.js +26 -0
- package/dist/app/services/catalog.js.map +1 -0
- package/dist/app/services/credentials.d.ts +42 -0
- package/dist/app/services/credentials.d.ts.map +1 -0
- package/dist/app/services/credentials.js +143 -0
- package/dist/app/services/credentials.js.map +1 -0
- package/dist/app/services/servers.d.ts +15 -0
- package/dist/app/services/servers.d.ts.map +1 -0
- package/dist/app/services/servers.js +445 -0
- package/dist/app/services/servers.js.map +1 -0
- package/dist/catalog/community.d.ts +19 -0
- package/dist/catalog/community.d.ts.map +1 -0
- package/dist/catalog/community.js +53 -0
- package/dist/catalog/community.js.map +1 -0
- package/dist/catalog/templates.d.ts +436 -0
- package/dist/catalog/templates.d.ts.map +1 -0
- package/dist/catalog/templates.js +489 -0
- package/dist/catalog/templates.js.map +1 -0
- package/dist/commands/audit.d.ts +2 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +122 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/bundle.d.ts +11 -0
- package/dist/commands/bundle.d.ts.map +1 -0
- package/dist/commands/bundle.js +299 -0
- package/dist/commands/bundle.js.map +1 -0
- package/dist/commands/clients.d.ts +6 -0
- package/dist/commands/clients.d.ts.map +1 -0
- package/dist/commands/clients.js +242 -0
- package/dist/commands/clients.js.map +1 -0
- package/dist/commands/completion.d.ts +18 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +495 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/connect.d.ts +10 -0
- package/dist/commands/connect.d.ts.map +1 -0
- package/dist/commands/connect.js +463 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/create.d.ts +2 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +607 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/delete.d.ts +2 -0
- package/dist/commands/delete.d.ts.map +1 -0
- package/dist/commands/delete.js +44 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +259 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/export.d.ts +2 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +93 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/gui.d.ts +2 -0
- package/dist/commands/gui.d.ts.map +1 -0
- package/dist/commands/gui.js +19 -0
- package/dist/commands/gui.js.map +1 -0
- package/dist/commands/import.d.ts +2 -0
- package/dist/commands/import.d.ts.map +1 -0
- package/dist/commands/import.js +102 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/info.d.ts +2 -0
- package/dist/commands/info.d.ts.map +1 -0
- package/dist/commands/info.js +151 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +90 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/reindex.d.ts +2 -0
- package/dist/commands/reindex.d.ts.map +1 -0
- package/dist/commands/reindex.js +186 -0
- package/dist/commands/reindex.js.map +1 -0
- package/dist/commands/rotate.d.ts +2 -0
- package/dist/commands/rotate.d.ts.map +1 -0
- package/dist/commands/rotate.js +67 -0
- package/dist/commands/rotate.js.map +1 -0
- package/dist/commands/secrets.d.ts +10 -0
- package/dist/commands/secrets.d.ts.map +1 -0
- package/dist/commands/secrets.js +293 -0
- package/dist/commands/secrets.js.map +1 -0
- package/dist/commands/start.d.ts +2 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +234 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/stats.d.ts +2 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +220 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/stop.d.ts +2 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +24 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/templates.d.ts +2 -0
- package/dist/commands/templates.d.ts.map +1 -0
- package/dist/commands/templates.js +168 -0
- package/dist/commands/templates.js.map +1 -0
- package/dist/commands/trial.d.ts +2 -0
- package/dist/commands/trial.d.ts.map +1 -0
- package/dist/commands/trial.js +61 -0
- package/dist/commands/trial.js.map +1 -0
- package/dist/commands/uninstall.d.ts +2 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +114 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +2 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +104 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/verify.d.ts +2 -0
- package/dist/commands/verify.d.ts.map +1 -0
- package/dist/commands/verify.js +301 -0
- package/dist/commands/verify.js.map +1 -0
- package/dist/core/config.d.ts +25 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +54 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/errors.d.ts +25 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +53 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/logger.d.ts +3 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +12 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/paths.d.ts +15 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +51 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/registry.d.ts +474 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +186 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/updater.d.ts +16 -0
- package/dist/core/updater.d.ts.map +1 -0
- package/dist/core/updater.js +317 -0
- package/dist/core/updater.js.map +1 -0
- package/dist/core/version.d.ts +2 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +3 -0
- package/dist/core/version.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +270 -0
- package/dist/index.js.map +1 -0
- package/dist/ingestion/chunker.d.ts +13 -0
- package/dist/ingestion/chunker.d.ts.map +1 -0
- package/dist/ingestion/chunker.js +107 -0
- package/dist/ingestion/chunker.js.map +1 -0
- package/dist/ingestion/cleaners.d.ts +10 -0
- package/dist/ingestion/cleaners.d.ts.map +1 -0
- package/dist/ingestion/cleaners.js +61 -0
- package/dist/ingestion/cleaners.js.map +1 -0
- package/dist/ingestion/detectors.d.ts +5 -0
- package/dist/ingestion/detectors.d.ts.map +1 -0
- package/dist/ingestion/detectors.js +25 -0
- package/dist/ingestion/detectors.js.map +1 -0
- package/dist/ingestion/fetchers.d.ts +38 -0
- package/dist/ingestion/fetchers.d.ts.map +1 -0
- package/dist/ingestion/fetchers.js +296 -0
- package/dist/ingestion/fetchers.js.map +1 -0
- package/dist/ingestion/github.d.ts +60 -0
- package/dist/ingestion/github.d.ts.map +1 -0
- package/dist/ingestion/github.js +314 -0
- package/dist/ingestion/github.js.map +1 -0
- package/dist/ingestion/pipeline.d.ts +3 -0
- package/dist/ingestion/pipeline.d.ts.map +1 -0
- package/dist/ingestion/pipeline.js +160 -0
- package/dist/ingestion/pipeline.js.map +1 -0
- package/dist/ingestion/types.d.ts +51 -0
- package/dist/ingestion/types.d.ts.map +1 -0
- package/dist/ingestion/types.js +2 -0
- package/dist/ingestion/types.js.map +1 -0
- package/dist/lib/auth.d.ts +2 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +6 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/embedding.d.ts +10 -0
- package/dist/lib/embedding.d.ts.map +1 -0
- package/dist/lib/embedding.js +21 -0
- package/dist/lib/embedding.js.map +1 -0
- package/dist/mcp/host.d.ts +16 -0
- package/dist/mcp/host.d.ts.map +1 -0
- package/dist/mcp/host.js +307 -0
- package/dist/mcp/host.js.map +1 -0
- package/dist/mcp/proxy-host.d.ts +25 -0
- package/dist/mcp/proxy-host.d.ts.map +1 -0
- package/dist/mcp/proxy-host.js +393 -0
- package/dist/mcp/proxy-host.js.map +1 -0
- package/dist/mcp/stdio-host.d.ts +19 -0
- package/dist/mcp/stdio-host.d.ts.map +1 -0
- package/dist/mcp/stdio-host.js +175 -0
- package/dist/mcp/stdio-host.js.map +1 -0
- package/dist/process/manager.d.ts +74 -0
- package/dist/process/manager.d.ts.map +1 -0
- package/dist/process/manager.js +322 -0
- package/dist/process/manager.js.map +1 -0
- package/dist/rag/models.d.ts +30 -0
- package/dist/rag/models.d.ts.map +1 -0
- package/dist/rag/models.js +30 -0
- package/dist/rag/models.js.map +1 -0
- package/dist/rag/store.d.ts +63 -0
- package/dist/rag/store.d.ts.map +1 -0
- package/dist/rag/store.js +505 -0
- package/dist/rag/store.js.map +1 -0
- package/dist/rag/types.d.ts +56 -0
- package/dist/rag/types.d.ts.map +1 -0
- package/dist/rag/types.js +2 -0
- package/dist/rag/types.js.map +1 -0
- package/dist/sources/plugins.d.ts +25 -0
- package/dist/sources/plugins.d.ts.map +1 -0
- package/dist/sources/plugins.js +55 -0
- package/dist/sources/plugins.js.map +1 -0
- package/dist/sources/registry.d.ts +19 -0
- package/dist/sources/registry.d.ts.map +1 -0
- package/dist/sources/registry.js +183 -0
- package/dist/sources/registry.js.map +1 -0
- package/dist/sources/types.d.ts +361 -0
- package/dist/sources/types.d.ts.map +1 -0
- package/dist/sources/types.js +59 -0
- package/dist/sources/types.js.map +1 -0
- package/dist/tui/index.d.ts +22 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +711 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/ui/format.d.ts +27 -0
- package/dist/ui/format.d.ts.map +1 -0
- package/dist/ui/format.js +80 -0
- package/dist/ui/format.js.map +1 -0
- package/dist/ui/help.d.ts +2 -0
- package/dist/ui/help.d.ts.map +1 -0
- package/dist/ui/help.js +106 -0
- package/dist/ui/help.js.map +1 -0
- package/dist/web/assets.d.ts +2 -0
- package/dist/web/assets.d.ts.map +1 -0
- package/dist/web/assets.js +659 -0
- package/dist/web/assets.js.map +1 -0
- package/dist/web/server.d.ts +9 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +349 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { deleteServer as deleteServerFromRegistry, getServerMetadata, getServerDefinition, listServers as listServersFromRegistry, registerServer, slugify, updateServerMetadata, validateServerState, } from '../../core/registry.js';
|
|
5
|
+
import { getServerDir } from '../../core/paths.js';
|
|
6
|
+
import { ingestDocumentation } from '../../ingestion/pipeline.js';
|
|
7
|
+
import { generateAuthKey } from '../../lib/auth.js';
|
|
8
|
+
import { serverManager } from '../../process/manager.js';
|
|
9
|
+
import { createRAGForServer } from '../../rag/store.js';
|
|
10
|
+
import { isHybridModel } from '../../rag/models.js';
|
|
11
|
+
import { emitProgress, fromIngestionProgress, } from '../events.js';
|
|
12
|
+
import { createLegacyServerDefinition, sourceLabel, sourceListLabel, sourceHeaders, sourceToIngestionUrl, summarizeDefinition, } from '../../sources/registry.js';
|
|
13
|
+
import { ServerDefinitionSchema } from '../../sources/types.js';
|
|
14
|
+
import { resolveCustomSource } from '../../sources/plugins.js';
|
|
15
|
+
import { getTemplateKind } from '../../catalog/templates.js';
|
|
16
|
+
import { saveCredentials } from './credentials.js';
|
|
17
|
+
const DEFAULT_MAX_CHUNKS = 6000;
|
|
18
|
+
const DEFAULT_MAX_PAGES = 80;
|
|
19
|
+
function indexLabel(embeddingModel) {
|
|
20
|
+
return isHybridModel(embeddingModel) ? `Hybrid (${embeddingModel})` : 'Fuse.js';
|
|
21
|
+
}
|
|
22
|
+
function resolveTemplateKind(definition) {
|
|
23
|
+
if (!definition.template?.id)
|
|
24
|
+
return 'docs-rag';
|
|
25
|
+
return getTemplateKind(definition.template.id);
|
|
26
|
+
}
|
|
27
|
+
function makeEmptyIngestionResult(templateId) {
|
|
28
|
+
return {
|
|
29
|
+
sourceUrl: `mcp-server:${templateId}`,
|
|
30
|
+
sourceType: 'manual',
|
|
31
|
+
title: templateId,
|
|
32
|
+
chunks: [],
|
|
33
|
+
stats: {
|
|
34
|
+
totalChunks: 0,
|
|
35
|
+
totalChars: 0,
|
|
36
|
+
pagesProcessed: 0,
|
|
37
|
+
durationMs: 0,
|
|
38
|
+
truncated: false,
|
|
39
|
+
maxChunks: 0,
|
|
40
|
+
maxPages: 0,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function likelyTruncated(meta) {
|
|
45
|
+
const stats = meta.ingestionStats;
|
|
46
|
+
return !!stats?.truncated || (typeof stats?.maxChunks === 'number' && meta.chunkCount >= stats.maxChunks);
|
|
47
|
+
}
|
|
48
|
+
async function indexChunksForServer(slug, chunks, embeddingModel, onProgress) {
|
|
49
|
+
emitProgress(onProgress, { stage: 'index', message: 'Building search index...' });
|
|
50
|
+
try {
|
|
51
|
+
const rag = await createRAGForServer(slug, embeddingModel);
|
|
52
|
+
await rag.indexChunks(chunks, {
|
|
53
|
+
embeddingModel,
|
|
54
|
+
onProgress: (p) => emitProgress(onProgress, {
|
|
55
|
+
stage: 'embed',
|
|
56
|
+
message: p.message,
|
|
57
|
+
current: p.current,
|
|
58
|
+
total: p.total,
|
|
59
|
+
}),
|
|
60
|
+
});
|
|
61
|
+
await rag.close?.();
|
|
62
|
+
emitProgress(onProgress, { stage: 'index', message: `Search index built (${indexLabel(embeddingModel)})` });
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
67
|
+
emitProgress(onProgress, { stage: 'index', message: 'Search index step had issues' });
|
|
68
|
+
return message;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function resolveCreateDefinition(input) {
|
|
72
|
+
if (input.definition)
|
|
73
|
+
return ServerDefinitionSchema.parse(input.definition);
|
|
74
|
+
if (input.sources && input.sources.length > 0) {
|
|
75
|
+
return ServerDefinitionSchema.parse({ version: 1, sources: input.sources });
|
|
76
|
+
}
|
|
77
|
+
if (input.url)
|
|
78
|
+
return createLegacyServerDefinition(input.url, 'generic');
|
|
79
|
+
throw new Error('Missing source. Next: pass --url <url> or one or more --source type:value entries.');
|
|
80
|
+
}
|
|
81
|
+
function makeSourceId(index) {
|
|
82
|
+
return `source_${index + 1}`;
|
|
83
|
+
}
|
|
84
|
+
function combineIngestionResults(definition, results, maxChunks, maxPages) {
|
|
85
|
+
const chunks = [];
|
|
86
|
+
let order = 0;
|
|
87
|
+
let truncated = false;
|
|
88
|
+
for (let sourceIndex = 0; sourceIndex < results.length; sourceIndex++) {
|
|
89
|
+
const source = definition.sources[sourceIndex];
|
|
90
|
+
const result = results[sourceIndex];
|
|
91
|
+
const id = makeSourceId(sourceIndex);
|
|
92
|
+
const label = sourceLabel(source);
|
|
93
|
+
for (const chunk of result.chunks) {
|
|
94
|
+
if (chunks.length >= maxChunks) {
|
|
95
|
+
truncated = true;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
chunks.push({
|
|
99
|
+
...chunk,
|
|
100
|
+
id: `${id}_${chunk.id}`,
|
|
101
|
+
metadata: {
|
|
102
|
+
...chunk.metadata,
|
|
103
|
+
order: order++,
|
|
104
|
+
sourceId: id,
|
|
105
|
+
sourceType: source.type,
|
|
106
|
+
sourceLabel: label,
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (truncated)
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
const primary = results[0];
|
|
114
|
+
const totalChars = chunks.reduce((sum, chunk) => sum + chunk.content.length, 0);
|
|
115
|
+
const stats = {
|
|
116
|
+
totalChunks: chunks.length,
|
|
117
|
+
totalChars,
|
|
118
|
+
pagesProcessed: results.reduce((sum, result) => sum + result.stats.pagesProcessed, 0),
|
|
119
|
+
pagesDiscovered: results.reduce((sum, result) => sum + (result.stats.pagesDiscovered ?? result.stats.pagesProcessed), 0),
|
|
120
|
+
durationMs: results.reduce((sum, result) => sum + result.stats.durationMs, 0),
|
|
121
|
+
truncated: truncated || results.some((result) => result.stats.truncated),
|
|
122
|
+
maxChunks,
|
|
123
|
+
maxPages,
|
|
124
|
+
};
|
|
125
|
+
return {
|
|
126
|
+
sourceUrl: primary.sourceUrl,
|
|
127
|
+
sourceType: primary.sourceType,
|
|
128
|
+
title: primary.title,
|
|
129
|
+
chunks,
|
|
130
|
+
stats,
|
|
131
|
+
rawMarkdown: results.map((result) => result.rawMarkdown || '').filter(Boolean).join('\n\n---\n\n').slice(0, 50_000),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
async function ingestDefinition(definition, options) {
|
|
135
|
+
const resolvedDefinition = await resolveDefinitionSources(definition);
|
|
136
|
+
if (resolvedDefinition.sources.length === 1) {
|
|
137
|
+
const source = resolvedDefinition.sources[0];
|
|
138
|
+
return ingestDocumentation(sourceToIngestionUrl(source), {
|
|
139
|
+
maxChunks: options.maxChunks,
|
|
140
|
+
maxPages: options.maxPages,
|
|
141
|
+
headers: sourceHeaders(source),
|
|
142
|
+
onProgress: (p) => emitProgress(options.onProgress, fromIngestionProgress(p)),
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
const results = [];
|
|
146
|
+
for (let i = 0; i < resolvedDefinition.sources.length; i++) {
|
|
147
|
+
const source = resolvedDefinition.sources[i];
|
|
148
|
+
emitProgress(options.onProgress, {
|
|
149
|
+
stage: 'fetch',
|
|
150
|
+
message: `Ingesting source ${i + 1}/${resolvedDefinition.sources.length}: ${sourceLabel(source)}`,
|
|
151
|
+
current: i + 1,
|
|
152
|
+
total: resolvedDefinition.sources.length,
|
|
153
|
+
});
|
|
154
|
+
const result = await ingestDocumentation(sourceToIngestionUrl(source), {
|
|
155
|
+
maxChunks: options.maxChunks,
|
|
156
|
+
maxPages: options.maxPages,
|
|
157
|
+
headers: sourceHeaders(source),
|
|
158
|
+
onProgress: (p) => emitProgress(options.onProgress, {
|
|
159
|
+
...fromIngestionProgress(p),
|
|
160
|
+
message: `[${sourceLabel(source)}] ${p.message}`,
|
|
161
|
+
}),
|
|
162
|
+
});
|
|
163
|
+
results.push(result);
|
|
164
|
+
}
|
|
165
|
+
return combineIngestionResults(resolvedDefinition, results, options.maxChunks, options.maxPages);
|
|
166
|
+
}
|
|
167
|
+
async function resolveDefinitionSources(definition) {
|
|
168
|
+
const sources = [];
|
|
169
|
+
for (const source of definition.sources) {
|
|
170
|
+
if (source.type === 'custom') {
|
|
171
|
+
sources.push(await resolveCustomSource(source.provider, source.value));
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
sources.push(source);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return { ...definition, sources };
|
|
178
|
+
}
|
|
179
|
+
export async function createServer(input) {
|
|
180
|
+
const slug = slugify(input.name);
|
|
181
|
+
const definition = resolveCreateDefinition(input);
|
|
182
|
+
// mcp-server kind: skip ingestion entirely — store config + credentials only
|
|
183
|
+
if (resolveTemplateKind(definition) === 'mcp-server') {
|
|
184
|
+
return createMcpServerEntry(input, slug, definition);
|
|
185
|
+
}
|
|
186
|
+
// docs-rag kind (existing path — unchanged)
|
|
187
|
+
const maxChunks = input.maxChunks ?? DEFAULT_MAX_CHUNKS;
|
|
188
|
+
const maxPages = input.maxPages ?? DEFAULT_MAX_PAGES;
|
|
189
|
+
const ingestion = await ingestDefinition(definition, {
|
|
190
|
+
maxChunks,
|
|
191
|
+
maxPages,
|
|
192
|
+
onProgress: input.onProgress,
|
|
193
|
+
});
|
|
194
|
+
const indexWarning = await indexChunksForServer(slug, ingestion.chunks, input.embeddingModel, input.onProgress);
|
|
195
|
+
emitProgress(input.onProgress, { stage: 'register', message: 'Registering server...' });
|
|
196
|
+
const meta = await registerServer({
|
|
197
|
+
name: input.name,
|
|
198
|
+
slug,
|
|
199
|
+
sourceUrl: ingestion.sourceUrl,
|
|
200
|
+
sourceType: ingestion.sourceType,
|
|
201
|
+
ingestionVersion: '1.0.0',
|
|
202
|
+
embeddingModel: input.embeddingModel,
|
|
203
|
+
chunkCount: ingestion.stats.totalChunks,
|
|
204
|
+
ingestionStats: ingestion.stats,
|
|
205
|
+
sourceFingerprint: fingerprintChunks(ingestion.chunks),
|
|
206
|
+
vectorIndexed: isHybridModel(input.embeddingModel),
|
|
207
|
+
authKey: generateAuthKey(),
|
|
208
|
+
desiredState: 'stopped',
|
|
209
|
+
serverKind: 'docs-rag',
|
|
210
|
+
credentialKeys: [],
|
|
211
|
+
definition,
|
|
212
|
+
});
|
|
213
|
+
emitProgress(input.onProgress, { stage: 'done', message: 'Server created successfully' });
|
|
214
|
+
return {
|
|
215
|
+
meta,
|
|
216
|
+
ingestion,
|
|
217
|
+
indexLabel: indexLabel(input.embeddingModel),
|
|
218
|
+
indexWarning,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
async function createMcpServerEntry(input, slug, definition) {
|
|
222
|
+
const templateId = definition.template?.id ?? 'unknown';
|
|
223
|
+
emitProgress(input.onProgress, { stage: 'credential', message: 'Storing credentials...' });
|
|
224
|
+
const credentials = input.credentials ?? {};
|
|
225
|
+
const credentialKeys = Object.keys(credentials);
|
|
226
|
+
if (credentialKeys.length > 0) {
|
|
227
|
+
await saveCredentials(slug, credentials);
|
|
228
|
+
}
|
|
229
|
+
emitProgress(input.onProgress, { stage: 'register', message: 'Registering MCP server...' });
|
|
230
|
+
const meta = await registerServer({
|
|
231
|
+
name: input.name,
|
|
232
|
+
slug,
|
|
233
|
+
sourceUrl: `mcp-server:${templateId}`,
|
|
234
|
+
sourceType: 'manual',
|
|
235
|
+
ingestionVersion: '1.0.0',
|
|
236
|
+
embeddingModel: 'fuse',
|
|
237
|
+
chunkCount: 0,
|
|
238
|
+
vectorIndexed: false,
|
|
239
|
+
authKey: generateAuthKey(),
|
|
240
|
+
desiredState: 'stopped',
|
|
241
|
+
serverKind: 'mcp-server',
|
|
242
|
+
credentialKeys,
|
|
243
|
+
definition,
|
|
244
|
+
});
|
|
245
|
+
emitProgress(input.onProgress, { stage: 'done', message: 'MCP server configured successfully' });
|
|
246
|
+
return {
|
|
247
|
+
meta,
|
|
248
|
+
ingestion: makeEmptyIngestionResult(templateId),
|
|
249
|
+
indexLabel: 'n/a',
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
export async function reindexServer(input) {
|
|
253
|
+
const current = await getServerMetadata(input.slug);
|
|
254
|
+
const definition = getServerDefinition(current);
|
|
255
|
+
if (!definition.sources.length && !current.sourceUrl) {
|
|
256
|
+
throw new Error('This server has no recorded sourceUrl and cannot be reindexed.');
|
|
257
|
+
}
|
|
258
|
+
const maxChunks = input.maxChunks ?? DEFAULT_MAX_CHUNKS;
|
|
259
|
+
const maxPages = input.maxPages ?? DEFAULT_MAX_PAGES;
|
|
260
|
+
const ingestion = await ingestDefinition(definition, {
|
|
261
|
+
maxChunks,
|
|
262
|
+
maxPages,
|
|
263
|
+
onProgress: input.onProgress,
|
|
264
|
+
});
|
|
265
|
+
const nextFingerprint = fingerprintChunks(ingestion.chunks);
|
|
266
|
+
if (input.incremental !== false && !input.force && current.sourceFingerprint && current.sourceFingerprint === nextFingerprint) {
|
|
267
|
+
const meta = await updateServerMetadata(input.slug, {
|
|
268
|
+
lastReindexAt: new Date().toISOString(),
|
|
269
|
+
reindexSchedule: nextSchedule(current.reindexSchedule),
|
|
270
|
+
definition,
|
|
271
|
+
});
|
|
272
|
+
emitProgress(input.onProgress, { stage: 'done', message: 'No source changes detected; index is already current.' });
|
|
273
|
+
return {
|
|
274
|
+
meta,
|
|
275
|
+
ingestion,
|
|
276
|
+
indexLabel: indexLabel(input.embeddingModel),
|
|
277
|
+
skipped: true,
|
|
278
|
+
reason: 'unchanged',
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
const indexWarning = await indexChunksForServer(input.slug, ingestion.chunks, input.embeddingModel, input.onProgress);
|
|
282
|
+
const meta = await updateServerMetadata(input.slug, {
|
|
283
|
+
chunkCount: ingestion.stats.totalChunks,
|
|
284
|
+
sourceType: ingestion.sourceType,
|
|
285
|
+
ingestionStats: ingestion.stats,
|
|
286
|
+
sourceFingerprint: nextFingerprint,
|
|
287
|
+
lastReindexAt: new Date().toISOString(),
|
|
288
|
+
reindexSchedule: nextSchedule(current.reindexSchedule),
|
|
289
|
+
embeddingModel: input.embeddingModel,
|
|
290
|
+
vectorIndexed: isHybridModel(input.embeddingModel),
|
|
291
|
+
definition,
|
|
292
|
+
});
|
|
293
|
+
emitProgress(input.onProgress, { stage: 'done', message: 'Server reindexed successfully' });
|
|
294
|
+
return {
|
|
295
|
+
meta,
|
|
296
|
+
ingestion,
|
|
297
|
+
indexLabel: indexLabel(input.embeddingModel),
|
|
298
|
+
indexWarning,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
export async function updateReindexSchedule(slug, intervalHours) {
|
|
302
|
+
if (intervalHours === null) {
|
|
303
|
+
return updateServerMetadata(slug, { reindexSchedule: { enabled: false, intervalHours: 24 } });
|
|
304
|
+
}
|
|
305
|
+
const nextRunAt = new Date(Date.now() + intervalHours * 60 * 60 * 1000).toISOString();
|
|
306
|
+
return updateServerMetadata(slug, {
|
|
307
|
+
reindexSchedule: { enabled: true, intervalHours, nextRunAt },
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
export async function listDueReindexServers(now = new Date()) {
|
|
311
|
+
const servers = await listServersFromRegistry();
|
|
312
|
+
return servers.filter((server) => {
|
|
313
|
+
const schedule = server.reindexSchedule;
|
|
314
|
+
if (!schedule?.enabled || !schedule.nextRunAt)
|
|
315
|
+
return false;
|
|
316
|
+
return Date.parse(schedule.nextRunAt) <= now.getTime();
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
export async function deleteRegisteredServer(slug) {
|
|
320
|
+
await deleteServerFromRegistry(slug);
|
|
321
|
+
return { slug, deleted: true };
|
|
322
|
+
}
|
|
323
|
+
export async function listRegisteredServers(options = {}) {
|
|
324
|
+
const servers = await listServersFromRegistry();
|
|
325
|
+
if (!options.includeStatus)
|
|
326
|
+
return servers;
|
|
327
|
+
const enriched = [];
|
|
328
|
+
for (const server of servers) {
|
|
329
|
+
enriched.push({
|
|
330
|
+
...server,
|
|
331
|
+
status: await serverManager.getStatus(server.slug),
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
return enriched;
|
|
335
|
+
}
|
|
336
|
+
export async function getServerInfo(slug) {
|
|
337
|
+
const meta = await getServerMetadata(slug);
|
|
338
|
+
const status = await serverManager.getStatus(slug);
|
|
339
|
+
return { meta, status };
|
|
340
|
+
}
|
|
341
|
+
export async function getServerLogTail(slug, maxChars = 8000) {
|
|
342
|
+
const logPath = path.join(getServerDir(slug), 'host.log');
|
|
343
|
+
try {
|
|
344
|
+
const content = await fs.readFile(logPath, 'utf8');
|
|
345
|
+
return content.slice(-maxChars) || '(empty)';
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
return '(no host.log yet for this server)';
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
export async function verifyServer(slug, queries = ['overview', 'install', 'getting started', 'api', 'configuration']) {
|
|
352
|
+
const meta = await getServerMetadata(slug);
|
|
353
|
+
const definition = getServerDefinition(meta);
|
|
354
|
+
const summary = summarizeDefinition(definition);
|
|
355
|
+
const validation = await validateServerState(slug);
|
|
356
|
+
const rag = await createRAGForServer(slug, meta.embeddingModel || 'fuse');
|
|
357
|
+
const diagnostics = await rag.getDiagnostics?.() ?? null;
|
|
358
|
+
const samples = [];
|
|
359
|
+
let groundedCount = 0;
|
|
360
|
+
const weakQueries = [];
|
|
361
|
+
for (const query of queries) {
|
|
362
|
+
const results = await rag.search(query, { limit: 2, mode: 'hybrid' });
|
|
363
|
+
const top = results[0];
|
|
364
|
+
if (top?.metadata.url)
|
|
365
|
+
groundedCount++;
|
|
366
|
+
const grounded = !!top?.metadata.url;
|
|
367
|
+
const weak = results.length === 0 || !grounded || (top?.score ?? 0) < 0.45;
|
|
368
|
+
if (weak)
|
|
369
|
+
weakQueries.push(query);
|
|
370
|
+
samples.push({
|
|
371
|
+
query,
|
|
372
|
+
hits: results.length,
|
|
373
|
+
top: top ? {
|
|
374
|
+
title: top.metadata.title,
|
|
375
|
+
sectionPath: top.metadata.sectionPath,
|
|
376
|
+
url: top.metadata.url,
|
|
377
|
+
score: top.score,
|
|
378
|
+
} : null,
|
|
379
|
+
grounded,
|
|
380
|
+
weak,
|
|
381
|
+
results,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
const toc = await rag.getTableOfContents();
|
|
385
|
+
const ingestionStats = meta.ingestionStats || null;
|
|
386
|
+
return {
|
|
387
|
+
slug,
|
|
388
|
+
name: meta.name,
|
|
389
|
+
sourceUrl: meta.sourceUrl,
|
|
390
|
+
sourceType: meta.sourceType,
|
|
391
|
+
chunkCount: meta.chunkCount,
|
|
392
|
+
validation,
|
|
393
|
+
searchable: samples.some((sample) => sample.hits > 0),
|
|
394
|
+
groundingPercent: Math.round((groundedCount / queries.length) * 100),
|
|
395
|
+
sourceCoveragePercent: diagnostics?.sourceCoveragePercent ?? null,
|
|
396
|
+
uniqueSourceUrls: diagnostics?.uniqueSourceUrls ?? null,
|
|
397
|
+
totalChars: diagnostics?.totalChars ?? null,
|
|
398
|
+
averageChunkChars: diagnostics?.averageChunkChars ?? null,
|
|
399
|
+
duplicateChunkIds: diagnostics?.duplicateChunkIds ?? null,
|
|
400
|
+
weakQueries,
|
|
401
|
+
ingestion: ingestionStats ? {
|
|
402
|
+
pagesProcessed: ingestionStats.pagesProcessed,
|
|
403
|
+
pagesDiscovered: ingestionStats.pagesDiscovered,
|
|
404
|
+
maxPages: ingestionStats.maxPages,
|
|
405
|
+
maxChunks: ingestionStats.maxChunks,
|
|
406
|
+
truncated: likelyTruncated(meta),
|
|
407
|
+
} : {
|
|
408
|
+
truncated: likelyTruncated(meta),
|
|
409
|
+
note: 'No persisted ingestion stats; reindex to record cap details.',
|
|
410
|
+
},
|
|
411
|
+
samples,
|
|
412
|
+
tocEntries: toc.length,
|
|
413
|
+
tocPreview: toc.slice(0, 12),
|
|
414
|
+
toc,
|
|
415
|
+
diagnostics,
|
|
416
|
+
embeddingModel: meta.embeddingModel,
|
|
417
|
+
freshnessUpdatedAt: meta.lastUpdatedAt,
|
|
418
|
+
definition,
|
|
419
|
+
sourceCount: summary.count,
|
|
420
|
+
sourceLabels: summary.labels,
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
export function getServerSourceLabel(meta) {
|
|
424
|
+
return sourceListLabel(getServerDefinition(meta));
|
|
425
|
+
}
|
|
426
|
+
function fingerprintChunks(chunks) {
|
|
427
|
+
const hash = createHash('sha256');
|
|
428
|
+
for (const chunk of chunks) {
|
|
429
|
+
hash.update(chunk.metadata.url);
|
|
430
|
+
hash.update('\0');
|
|
431
|
+
hash.update(chunk.content);
|
|
432
|
+
hash.update('\0');
|
|
433
|
+
}
|
|
434
|
+
return hash.digest('hex');
|
|
435
|
+
}
|
|
436
|
+
function nextSchedule(schedule) {
|
|
437
|
+
if (!schedule?.enabled)
|
|
438
|
+
return schedule;
|
|
439
|
+
return {
|
|
440
|
+
enabled: true,
|
|
441
|
+
intervalHours: schedule.intervalHours,
|
|
442
|
+
nextRunAt: new Date(Date.now() + schedule.intervalHours * 60 * 60 * 1000).toISOString(),
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
//# sourceMappingURL=servers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"servers.js","sourceRoot":"","sources":["../../../src/app/services/servers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Community template loader.
|
|
3
|
+
*
|
|
4
|
+
* Reads and validates *.json files from the user's community templates directory
|
|
5
|
+
* (~/.local/share/hoolix/templates/ on Linux, ~/Library/Application Support/hoolix/templates/ on macOS,
|
|
6
|
+
* %APPDATA%\hoolix\templates on Windows, or override via HOOLIX_TEMPLATE_DIR).
|
|
7
|
+
*
|
|
8
|
+
* Invalid files emit a logger.warn and are skipped; they never crash the CLI.
|
|
9
|
+
* Follows the same pattern as src/sources/plugins.ts.
|
|
10
|
+
*/
|
|
11
|
+
import { type CatalogTemplate } from './templates.js';
|
|
12
|
+
/** Absolute path to the user's community template directory. */
|
|
13
|
+
export declare function getCommunityTemplateDir(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Load, validate, and return all community templates.
|
|
16
|
+
* Invalid manifests emit a warning and are skipped rather than thrown.
|
|
17
|
+
*/
|
|
18
|
+
export declare function listCommunityTemplates(): Promise<CatalogTemplate[]>;
|
|
19
|
+
//# sourceMappingURL=community.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"community.d.ts","sourceRoot":"","sources":["../../src/catalog/community.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAI7E,gEAAgE;AAChE,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAUD;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAmBzE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Community template loader.
|
|
3
|
+
*
|
|
4
|
+
* Reads and validates *.json files from the user's community templates directory
|
|
5
|
+
* (~/.local/share/hoolix/templates/ on Linux, ~/Library/Application Support/hoolix/templates/ on macOS,
|
|
6
|
+
* %APPDATA%\hoolix\templates on Windows, or override via HOOLIX_TEMPLATE_DIR).
|
|
7
|
+
*
|
|
8
|
+
* Invalid files emit a logger.warn and are skipped; they never crash the CLI.
|
|
9
|
+
* Follows the same pattern as src/sources/plugins.ts.
|
|
10
|
+
*/
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
import fs from 'fs-extra';
|
|
13
|
+
import { getPaths } from '../core/paths.js';
|
|
14
|
+
import { logger } from '../core/logger.js';
|
|
15
|
+
import { CatalogTemplateSchema } from './templates.js';
|
|
16
|
+
const COMMUNITY_SUBDIR = 'templates';
|
|
17
|
+
/** Absolute path to the user's community template directory. */
|
|
18
|
+
export function getCommunityTemplateDir() {
|
|
19
|
+
return path.join(getPaths().data, COMMUNITY_SUBDIR);
|
|
20
|
+
}
|
|
21
|
+
/** All directories that are searched for community templates (primary + HOOLIX_TEMPLATE_DIR). */
|
|
22
|
+
function communityTemplateDirs() {
|
|
23
|
+
const dirs = [getCommunityTemplateDir()];
|
|
24
|
+
const extra = process.env.HOOLIX_TEMPLATE_DIR;
|
|
25
|
+
if (extra)
|
|
26
|
+
dirs.push(...extra.split(path.delimiter).filter(Boolean));
|
|
27
|
+
return dirs;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Load, validate, and return all community templates.
|
|
31
|
+
* Invalid manifests emit a warning and are skipped rather than thrown.
|
|
32
|
+
*/
|
|
33
|
+
export async function listCommunityTemplates() {
|
|
34
|
+
const dirs = communityTemplateDirs();
|
|
35
|
+
const templates = [];
|
|
36
|
+
for (const dir of dirs) {
|
|
37
|
+
if (!(await fs.pathExists(dir)))
|
|
38
|
+
continue;
|
|
39
|
+
const files = (await fs.readdir(dir).catch(() => [])).filter((f) => f.endsWith('.json'));
|
|
40
|
+
for (const file of files) {
|
|
41
|
+
try {
|
|
42
|
+
const raw = await fs.readJson(path.join(dir, file));
|
|
43
|
+
const parsed = CatalogTemplateSchema.parse(raw);
|
|
44
|
+
templates.push(parsed);
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
logger.warn(`Community template "${file}" is invalid and was skipped: ${e?.message || String(e)}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return templates.sort((a, b) => a.id.localeCompare(b.id));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=community.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"community.js","sourceRoot":"","sources":["../../src/catalog/community.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,qBAAqB,EAAwB,MAAM,gBAAgB,CAAC;AAE7E,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAErC,gEAAgE;AAChE,MAAM,UAAU,uBAAuB;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;AACtD,CAAC;AAED,iGAAiG;AACjG,SAAS,qBAAqB;IAC5B,MAAM,IAAI,GAAG,CAAC,uBAAuB,EAAE,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IAC9C,IAAI,KAAK;QAAE,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,IAAI,GAAG,qBAAqB,EAAE,CAAC;IACrC,MAAM,SAAS,GAAsB,EAAE,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAAE,SAAS;QAC1C,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACrG,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;gBACpD,MAAM,MAAM,GAAG,qBAAqB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAChD,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CAAC,uBAAuB,IAAI,iCAAiC,CAAC,EAAE,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACrG,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5D,CAAC"}
|