@oneentry/mcp-platform-server 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.
- package/LICENSE +21 -0
- package/README.md +62 -61
- package/dist/api/audit.d.ts +0 -11
- package/dist/api/audit.js +0 -10
- package/dist/api/auth.d.ts +0 -18
- package/dist/api/auth.js +0 -20
- package/dist/api/build-catalog.d.ts +1 -14
- package/dist/api/build-catalog.js +16 -77
- package/dist/api/catalog.d.ts +5 -27
- package/dist/api/catalog.d.ts.map +1 -1
- package/dist/api/catalog.js +31 -43
- package/dist/api/catalog.js.map +1 -1
- package/dist/api/client.d.ts +0 -24
- package/dist/api/client.js +6 -28
- package/dist/api/normalize-schema.d.ts +0 -11
- package/dist/api/normalize-schema.js +0 -18
- package/dist/api/policy.d.ts +0 -23
- package/dist/api/policy.js +0 -0
- package/dist/api/shape.d.ts +0 -13
- package/dist/api/shape.js +0 -21
- package/dist/api/swagger-source.d.ts +13 -12
- package/dist/api/swagger-source.js +93 -50
- package/dist/api/types.d.ts +0 -34
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/types.js +0 -1
- package/dist/bin/cli.d.ts +0 -1
- package/dist/bin/cli.js +1 -5
- package/dist/bin/cli.js.map +1 -1
- package/dist/config/config.d.ts +0 -54
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +0 -60
- package/dist/config/config.js.map +1 -1
- package/dist/index.d.ts +2 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -6
- package/dist/index.js.map +1 -1
- package/dist/knowledge/chunk.d.ts +0 -15
- package/dist/knowledge/chunk.js +0 -16
- package/dist/knowledge/github.d.ts +0 -25
- package/dist/knowledge/github.js +0 -40
- package/dist/knowledge/loader.d.ts +0 -28
- package/dist/knowledge/loader.d.ts.map +1 -1
- package/dist/knowledge/loader.js +0 -26
- package/dist/knowledge/loader.js.map +1 -1
- package/dist/knowledge/search.d.ts +0 -22
- package/dist/knowledge/search.d.ts.map +1 -1
- package/dist/knowledge/search.js +0 -34
- package/dist/knowledge/search.js.map +1 -1
- package/dist/knowledge/tar.d.ts +0 -15
- package/dist/knowledge/tar.js +0 -33
- package/dist/knowledge/types.d.ts +0 -35
- package/dist/knowledge/types.d.ts.map +1 -1
- package/dist/knowledge/types.js +0 -1
- package/dist/server.d.ts +0 -12
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +29 -15
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +0 -23
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +0 -18
- package/dist/session.js.map +1 -1
- package/dist/tools/api-call.d.ts +0 -2
- package/dist/tools/api-call.js +0 -23
- package/dist/tools/api-discovery.d.ts +0 -2
- package/dist/tools/api-discovery.js +2 -5
- package/dist/tools/docs.d.ts +0 -2
- package/dist/tools/docs.js +1 -5
- package/dist/tools/guide.d.ts +0 -7
- package/dist/tools/guide.d.ts.map +1 -1
- package/dist/tools/guide.js +2 -9
- package/dist/tools/guide.js.map +1 -1
- package/dist/tools/result.d.ts +0 -8
- package/dist/tools/result.js +0 -7
- package/dist/tools/whoami.d.ts +0 -2
- package/dist/tools/whoami.d.ts.map +1 -1
- package/dist/tools/whoami.js +1 -3
- package/dist/tools/whoami.js.map +1 -1
- package/dist/transports/http.d.ts +0 -6
- package/dist/transports/http.d.ts.map +1 -1
- package/dist/transports/http.js +1 -27
- package/dist/transports/http.js.map +1 -1
- package/dist/transports/stdio.d.ts +0 -6
- package/dist/transports/stdio.js +0 -6
- package/dist/transports/stdio.js.map +1 -1
- package/knowledge/operating-rules.md +70 -125
- package/package.json +18 -5
- package/dist/api/build-catalog.d.ts.map +0 -1
- package/dist/api/build-catalog.js.map +0 -1
- package/dist/api/normalize-schema.d.ts.map +0 -1
- package/dist/api/normalize-schema.js.map +0 -1
- package/dist/api/swagger-source.d.ts.map +0 -1
- package/dist/api/swagger-source.js.map +0 -1
- package/dist/knowledge/github.d.ts.map +0 -1
- package/dist/knowledge/github.js.map +0 -1
- package/dist/knowledge/tar.d.ts.map +0 -1
- package/dist/knowledge/tar.js.map +0 -1
|
@@ -1,76 +1,119 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
/** Язык описаний. Английский — тот же, на котором написаны summary в каталоге. */
|
|
4
|
+
const API_ADMIN_PREFIX = '/api/admin';
|
|
5
|
+
const NODE_SWAGGER_PATH = '/workflows/nodes/admin-api/swagger.json';
|
|
7
6
|
const LANG_CODE = 'en_US';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
const FULL_PARAM = 'full=true';
|
|
8
|
+
export const nestSwaggerUrl = (baseUrl) => {
|
|
9
|
+
const at = baseUrl.indexOf(API_ADMIN_PREFIX);
|
|
10
|
+
const prefix = at === -1 ? baseUrl : baseUrl.slice(0, at + API_ADMIN_PREFIX.length);
|
|
11
|
+
return `${prefix}-json`;
|
|
12
|
+
};
|
|
13
|
+
export const nodeSwaggerUrl = (baseUrl) => `${baseUrl}${NODE_SWAGGER_PATH}?langCode=${LANG_CODE}&${FULL_PARAM}`;
|
|
14
|
+
export const swaggerAttempts = (baseUrl) => [
|
|
15
|
+
{ variant: 'full', url: nestSwaggerUrl(baseUrl), authenticated: false },
|
|
16
|
+
{ variant: 'node', url: nodeSwaggerUrl(baseUrl), authenticated: true },
|
|
17
|
+
];
|
|
18
|
+
const cacheFile = (source, variant) => join(source.cacheDir, 'swagger', `${createHash('sha256').update(source.baseUrl).digest('hex').slice(0, 16)}-${variant}.json`);
|
|
19
|
+
const readCache = (source, variant) => {
|
|
14
20
|
try {
|
|
15
|
-
return readFileSync(cacheFile(source), 'utf8');
|
|
21
|
+
return readFileSync(cacheFile(source, variant), 'utf8');
|
|
16
22
|
}
|
|
17
23
|
catch {
|
|
18
24
|
return undefined;
|
|
19
25
|
}
|
|
20
26
|
};
|
|
21
|
-
const writeCache = (source, raw) => {
|
|
22
|
-
const file = cacheFile(source);
|
|
27
|
+
const writeCache = (source, variant, raw) => {
|
|
28
|
+
const file = cacheFile(source, variant);
|
|
23
29
|
mkdirSync(join(source.cacheDir, 'swagger'), { recursive: true });
|
|
24
30
|
writeFileSync(file, raw);
|
|
25
31
|
};
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const assertOpenApiDocument = (raw, url) => {
|
|
33
|
+
if (raw.trim() === '') {
|
|
34
|
+
throw new Error(`${url} answered 200 with an empty body instead of an API document`);
|
|
35
|
+
}
|
|
36
|
+
let parsed;
|
|
37
|
+
try {
|
|
38
|
+
parsed = JSON.parse(raw);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw new Error(`${url} answered 200 with a body that is not JSON (starts with "${raw.slice(0, 40).replace(/\s+/g, ' ')}")`);
|
|
42
|
+
}
|
|
43
|
+
if (typeof parsed !== 'object' ||
|
|
44
|
+
parsed === null ||
|
|
45
|
+
!('paths' in parsed) ||
|
|
46
|
+
typeof parsed.paths !== 'object' ||
|
|
47
|
+
parsed.paths === null) {
|
|
48
|
+
throw new Error(`${url} did not answer with an OpenAPI document`);
|
|
49
|
+
}
|
|
50
|
+
return parsed;
|
|
51
|
+
};
|
|
52
|
+
const assertAdminApiDocument = (document, url) => {
|
|
53
|
+
const paths = Object.keys(document['paths']);
|
|
54
|
+
const own = paths.filter((path) => path.startsWith(API_ADMIN_PREFIX)).length;
|
|
55
|
+
if (own * 2 <= paths.length) {
|
|
56
|
+
throw new Error(`${url} answered with an OpenAPI document that is not the Admin API ` +
|
|
57
|
+
`(${String(own)} of ${String(paths.length)} path(s) start with ${API_ADMIN_PREFIX})`);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const attemptFetch = async (attempt, source) => {
|
|
61
|
+
const bearer = attempt.authenticated ? source.bearer : undefined;
|
|
62
|
+
const response = await fetch(attempt.url, {
|
|
35
63
|
headers: {
|
|
36
64
|
accept: 'application/json',
|
|
37
65
|
...(bearer ? { authorization: `Bearer ${bearer}` } : {}),
|
|
38
66
|
},
|
|
39
67
|
signal: AbortSignal.timeout(source.timeoutMs),
|
|
40
68
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
throw new Error(`${attempt.url} answered ${String(response.status)}` +
|
|
71
|
+
(attempt.variant === 'full' && response.status === 404
|
|
72
|
+
? ' — this instance does not publish its own API document, which is normal ' +
|
|
73
|
+
'outside CORS_MODE=DEV'
|
|
74
|
+
: '') +
|
|
75
|
+
(attempt.authenticated && (response.status === 401 || response.status === 403)
|
|
76
|
+
? ' — this endpoint is behind the admin auth guard and requires an admin ' +
|
|
77
|
+
'token whose account holds the "workflows.get" permission'
|
|
78
|
+
: ''));
|
|
79
|
+
}
|
|
80
|
+
const raw = await response.text();
|
|
81
|
+
const document = assertOpenApiDocument(raw, attempt.url);
|
|
82
|
+
if (attempt.variant === 'full') {
|
|
83
|
+
assertAdminApiDocument(document, attempt.url);
|
|
84
|
+
}
|
|
85
|
+
return raw;
|
|
86
|
+
};
|
|
87
|
+
export const fetchSwagger = async (source) => {
|
|
88
|
+
const attempts = swaggerAttempts(source.baseUrl);
|
|
89
|
+
const failures = [];
|
|
90
|
+
for (const attempt of attempts) {
|
|
91
|
+
try {
|
|
92
|
+
const raw = await attemptFetch(attempt, source);
|
|
93
|
+
writeCache(source, attempt.variant, raw);
|
|
94
|
+
return {
|
|
95
|
+
raw,
|
|
96
|
+
origin: attempt.variant === 'full' ? 'instance-full' : 'instance-node',
|
|
97
|
+
url: attempt.url,
|
|
98
|
+
variant: attempt.variant,
|
|
99
|
+
failures,
|
|
100
|
+
};
|
|
51
101
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
* Проверяем, что это вообще OpenAPI, до записи в кэш. Стенд за прокси легко
|
|
55
|
-
* отвечает страницей входа или конвертом ошибки с кодом 200; закэшировать
|
|
56
|
-
* такое — значит подсунуть агенту пустой каталог до следующей чистки кэша.
|
|
57
|
-
*/
|
|
58
|
-
const parsed = JSON.parse(raw);
|
|
59
|
-
if (typeof parsed !== 'object' ||
|
|
60
|
-
parsed === null ||
|
|
61
|
-
!('paths' in parsed) ||
|
|
62
|
-
typeof parsed.paths !== 'object') {
|
|
63
|
-
throw new Error(`${source.baseUrl}${SWAGGER_PATH} did not answer with an OpenAPI document`);
|
|
102
|
+
catch (error) {
|
|
103
|
+
failures.push(error instanceof Error ? error.message : String(error));
|
|
64
104
|
}
|
|
65
|
-
writeCache(source, raw);
|
|
66
|
-
return { raw, origin: 'stand' };
|
|
67
105
|
}
|
|
68
|
-
|
|
69
|
-
const cached = readCache(source);
|
|
106
|
+
for (const attempt of attempts) {
|
|
107
|
+
const cached = readCache(source, attempt.variant);
|
|
70
108
|
if (cached) {
|
|
71
|
-
return {
|
|
109
|
+
return {
|
|
110
|
+
raw: cached,
|
|
111
|
+
origin: 'cache',
|
|
112
|
+
url: attempt.url,
|
|
113
|
+
variant: attempt.variant,
|
|
114
|
+
failures,
|
|
115
|
+
};
|
|
72
116
|
}
|
|
73
|
-
throw error instanceof Error ? error : new Error(String(error));
|
|
74
117
|
}
|
|
118
|
+
throw new Error(failures.join('; '));
|
|
75
119
|
};
|
|
76
|
-
//# sourceMappingURL=swagger-source.js.map
|
package/dist/api/types.d.ts
CHANGED
|
@@ -1,25 +1,13 @@
|
|
|
1
|
-
/** HTTP-методы, встречающиеся в Admin API. */
|
|
2
1
|
export type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
3
|
-
/**
|
|
4
|
-
* Класс риска операции. Определяется на сборке каталога, а не в рантайме,
|
|
5
|
-
* чтобы политику доступа нельзя было обойти хитрым аргументом.
|
|
6
|
-
*/
|
|
7
2
|
export type RiskLevel = 'read' | 'write' | 'destructive';
|
|
8
|
-
/** Параметр операции (path / query / header). */
|
|
9
3
|
export interface OperationParam {
|
|
10
4
|
name: string;
|
|
11
5
|
location: 'path' | 'query' | 'header';
|
|
12
6
|
required: boolean;
|
|
13
7
|
description?: string;
|
|
14
|
-
/** Нормализованная JSON-схема параметра. */
|
|
15
8
|
schema: JsonSchema;
|
|
16
9
|
example?: unknown;
|
|
17
10
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Нормализованная JSON-схема. Swagger проекта содержит 311 TypeScript-подобных
|
|
20
|
-
* значений `type` (`Record<string, any>`, `CommonLocalizeInfos`, `image`…),
|
|
21
|
-
* поэтому «схема» здесь — результат приведения, а не исходник.
|
|
22
|
-
*/
|
|
23
11
|
export interface JsonSchema {
|
|
24
12
|
type?: string;
|
|
25
13
|
format?: string;
|
|
@@ -29,28 +17,19 @@ export interface JsonSchema {
|
|
|
29
17
|
items?: JsonSchema;
|
|
30
18
|
properties?: Record<string, JsonSchema>;
|
|
31
19
|
required?: string[];
|
|
32
|
-
/** Тип не удалось привести к JSON Schema: доверять следует `example`. */
|
|
33
20
|
'x-loose'?: boolean;
|
|
34
|
-
/** Исходный TypeScript-подобный тип из swagger — сохранён как подсказка. */
|
|
35
21
|
'x-source-type'?: string;
|
|
36
|
-
/** Схема была урезана по размеру. */
|
|
37
22
|
'x-truncated'?: boolean;
|
|
38
23
|
}
|
|
39
|
-
/** Одна операция Admin API в каталоге. */
|
|
40
24
|
export interface Operation {
|
|
41
|
-
/** `operationId` из swagger, например `AdminPagesController_findAllRoot`. */
|
|
42
25
|
opId: string;
|
|
43
26
|
method: HttpMethod;
|
|
44
|
-
/** Путь без префикса API, например `/pages/{id}`. */
|
|
45
27
|
path: string;
|
|
46
|
-
/** Полный путь как в swagger, например `/api/admin/pages/{id}`. */
|
|
47
28
|
fullPath: string;
|
|
48
29
|
tag: string;
|
|
49
30
|
summary: string;
|
|
50
|
-
/** Требуемое право из `AdminPermissionsEnum`, если объявлено в контроллере. */
|
|
51
31
|
permission?: string;
|
|
52
32
|
risk: RiskLevel;
|
|
53
|
-
/** Операция навсегда остаётся за подтверждением, независимо от уровня allow. */
|
|
54
33
|
alwaysConfirm: boolean;
|
|
55
34
|
params: OperationParam[];
|
|
56
35
|
body?: {
|
|
@@ -59,27 +38,14 @@ export interface Operation {
|
|
|
59
38
|
required: boolean;
|
|
60
39
|
};
|
|
61
40
|
responseSummary?: string;
|
|
62
|
-
/** Идентификаторы разделов документации (`<docId>#<anchor>`), объясняющих операцию. */
|
|
63
|
-
docLinks: string[];
|
|
64
|
-
/** Склеенный текст для поиска по каталогу. */
|
|
65
41
|
searchText: string;
|
|
66
42
|
}
|
|
67
|
-
/** Собранный каталог: результат `buildCatalog` — swagger стенда плюс карта прав. */
|
|
68
43
|
export interface Catalog {
|
|
69
44
|
version: 1;
|
|
70
45
|
builtAt: string;
|
|
71
|
-
/** Префикс путей из swagger (`/api/admin`) — проверяется при сборке. */
|
|
72
46
|
apiPrefix: string;
|
|
73
|
-
/** Хэш исходного swagger.json — виден в cms_whoami, ловит рассинхрон. */
|
|
74
47
|
swaggerHash: string;
|
|
75
|
-
/** Полный список значений `AdminPermissionsEnum`. */
|
|
76
48
|
permissions: string[];
|
|
77
|
-
/**
|
|
78
|
-
* Замечания сборки — прежде всего признаки устаревшего swagger.json.
|
|
79
|
-
* Показываются в `cms_whoami`: рассинхрон каталога и реального API должен быть
|
|
80
|
-
* виден агенту, а не выясняться по 404.
|
|
81
|
-
*/
|
|
82
49
|
warnings: string[];
|
|
83
50
|
operations: Operation[];
|
|
84
51
|
}
|
|
85
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/api/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;AAEzD,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,0CAA0C;AAC1C,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,gFAAgF;IAChF,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uFAAuF;IACvF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/api/types.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;AAEzD,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qCAAqC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,0CAA0C;AAC1C,MAAM,WAAW,SAAS;IACxB,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,gFAAgF;IAChF,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IACtE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uFAAuF;IACvF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,6EAA6E;AAC7E,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,SAAS,EAAE,CAAC;CACzB"}
|
package/dist/api/types.js
CHANGED
package/dist/bin/cli.d.ts
CHANGED
package/dist/bin/cli.js
CHANGED
|
@@ -24,7 +24,7 @@ Knowledge (documentation is fetched from GitHub, not bundled)
|
|
|
24
24
|
--knowledge-ref <ref> branch, tag or commit, default main
|
|
25
25
|
--knowledge-path <dir> read a local clone instead of GitHub (fast edit loop)
|
|
26
26
|
--knowledge-ttl <ms> how long a cached commit stays fresh, default 3600000
|
|
27
|
-
--cache-dir <path> where the knowledge tree and the
|
|
27
|
+
--cache-dir <path> where the knowledge tree and the API document are cached
|
|
28
28
|
--offline never touch the network: cache and bundled rules only
|
|
29
29
|
|
|
30
30
|
Environment
|
|
@@ -47,10 +47,6 @@ const main = async () => {
|
|
|
47
47
|
await runStdio(config);
|
|
48
48
|
};
|
|
49
49
|
main().catch((error) => {
|
|
50
|
-
/**
|
|
51
|
-
* В stdio-режиме stdout занят протоколом, поэтому любая диагностика идёт в stderr.
|
|
52
|
-
*/
|
|
53
50
|
process.stderr.write(`oneentry-mcp-platform: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
54
51
|
process.exitCode = 1;
|
|
55
52
|
});
|
|
56
|
-
//# sourceMappingURL=cli.js.map
|
package/dist/bin/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,MAAM,KAAK,GAAG
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/bin/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAElD,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;CAsBb,CAAC;AAEF,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;IACrC,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;QACtB,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;AACzB,CAAC,CAAC;AAEF,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC9B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC3G,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
package/dist/config/config.d.ts
CHANGED
|
@@ -1,33 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
/**
|
|
3
|
-
* Уровень разрешённых операций.
|
|
4
|
-
* Читаем по умолчанию: агент не может ничего испортить, пока человек явно не разрешил.
|
|
5
|
-
*/
|
|
6
2
|
export declare const AllowLevelSchema: z.ZodEnum<["read", "write", "destructive"]>;
|
|
7
3
|
export type AllowLevel = z.infer<typeof AllowLevelSchema>;
|
|
8
|
-
/**
|
|
9
|
-
* Режим работы сервера. Определяется транспортом, а не отдельным флагом:
|
|
10
|
-
* stdio -> local (агент и CMS на одной машине), streamable HTTP -> remote (сервис).
|
|
11
|
-
*/
|
|
12
4
|
export declare const ServerModeSchema: z.ZodEnum<["local", "remote"]>;
|
|
13
5
|
export type ServerMode = z.infer<typeof ServerModeSchema>;
|
|
14
|
-
/**
|
|
15
|
-
* Откуда брать документацию. Знания живут в отдельном публичном репозитории GitHub
|
|
16
|
-
* и скачиваются в рантайме, а не вшиваются в пакет: иначе правка одной строки
|
|
17
|
-
* документации требовала бы перевыпуска npm-пакета.
|
|
18
|
-
*/
|
|
19
6
|
export declare const KnowledgeConfigSchema: z.ZodObject<{
|
|
20
|
-
/** `owner/name` репозитория знаний. */
|
|
21
7
|
repo: z.ZodString;
|
|
22
|
-
/** Ветка, тег или коммит. Пин на тег — способ зафиксировать знания для стенда. */
|
|
23
8
|
ref: z.ZodString;
|
|
24
|
-
/** Локальный клон репозитория знаний: читать его вместо сети. */
|
|
25
9
|
path: z.ZodOptional<z.ZodString>;
|
|
26
|
-
/** Сколько считать закэшированный коммит свежим, не спрашивая GitHub. */
|
|
27
10
|
refreshTtlMs: z.ZodNumber;
|
|
28
|
-
/** Не ходить в сеть: только кэш и вшитые правила. */
|
|
29
11
|
offline: z.ZodBoolean;
|
|
30
|
-
/** Токен GitHub — только чтобы поднять лимит API. Репозиторий публичный. */
|
|
31
12
|
token: z.ZodOptional<z.ZodString>;
|
|
32
13
|
}, "strip", z.ZodTypeAny, {
|
|
33
14
|
repo: string;
|
|
@@ -45,33 +26,19 @@ export declare const KnowledgeConfigSchema: z.ZodObject<{
|
|
|
45
26
|
token?: string | undefined;
|
|
46
27
|
}>;
|
|
47
28
|
export type KnowledgeSettings = z.infer<typeof KnowledgeConfigSchema>;
|
|
48
|
-
/**
|
|
49
|
-
* Полная конфигурация сервера после слияния источников.
|
|
50
|
-
* Все дальнейшие слои получают её как зависимость и не читают process.env сами —
|
|
51
|
-
* это то, что позволяет держать один и тот же код для local и remote.
|
|
52
|
-
*/
|
|
53
29
|
export declare const ConfigSchema: z.ZodObject<{
|
|
54
30
|
mode: z.ZodEnum<["local", "remote"]>;
|
|
55
|
-
/** Базовый URL Admin API, всегда с префиксом /api/admin и без завершающего слэша. */
|
|
56
31
|
baseUrl: z.ZodString;
|
|
57
32
|
allow: z.ZodEnum<["read", "write", "destructive"]>;
|
|
58
|
-
/** Логин/пароль админа. В remote-режиме могут отсутствовать — тогда их даёт сессия. */
|
|
59
33
|
login: z.ZodOptional<z.ZodString>;
|
|
60
34
|
password: z.ZodOptional<z.ZodString>;
|
|
61
|
-
/** Готовый access-токен вместо логина/пароля. */
|
|
62
35
|
token: z.ZodOptional<z.ZodString>;
|
|
63
36
|
knowledge: z.ZodObject<{
|
|
64
|
-
/** `owner/name` репозитория знаний. */
|
|
65
37
|
repo: z.ZodString;
|
|
66
|
-
/** Ветка, тег или коммит. Пин на тег — способ зафиксировать знания для стенда. */
|
|
67
38
|
ref: z.ZodString;
|
|
68
|
-
/** Локальный клон репозитория знаний: читать его вместо сети. */
|
|
69
39
|
path: z.ZodOptional<z.ZodString>;
|
|
70
|
-
/** Сколько считать закэшированный коммит свежим, не спрашивая GitHub. */
|
|
71
40
|
refreshTtlMs: z.ZodNumber;
|
|
72
|
-
/** Не ходить в сеть: только кэш и вшитые правила. */
|
|
73
41
|
offline: z.ZodBoolean;
|
|
74
|
-
/** Токен GitHub — только чтобы поднять лимит API. Репозиторий публичный. */
|
|
75
42
|
token: z.ZodOptional<z.ZodString>;
|
|
76
43
|
}, "strip", z.ZodTypeAny, {
|
|
77
44
|
repo: string;
|
|
@@ -88,18 +55,13 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
88
55
|
path?: string | undefined;
|
|
89
56
|
token?: string | undefined;
|
|
90
57
|
}>;
|
|
91
|
-
/** Каталог кэша: распакованный репозиторий знаний и снимок swagger стенда. */
|
|
92
58
|
cacheDir: z.ZodString;
|
|
93
|
-
/** Файл JSONL-аудита. В remote-режиме обязателен. */
|
|
94
59
|
auditPath: z.ZodOptional<z.ZodString>;
|
|
95
|
-
/** Таймаут одного запроса к Admin API, мс. */
|
|
96
60
|
requestTimeoutMs: z.ZodNumber;
|
|
97
|
-
/** Максимальный размер сериализованного ответа, отдаваемого модели, в байтах. */
|
|
98
61
|
maxResponseBytes: z.ZodNumber;
|
|
99
62
|
http: z.ZodObject<{
|
|
100
63
|
port: z.ZodNumber;
|
|
101
64
|
host: z.ZodString;
|
|
102
|
-
/** Разрешённые Origin для remote-режима. Пустой список = принимать только запросы без Origin. */
|
|
103
65
|
allowedOrigins: z.ZodArray<z.ZodString, "many">;
|
|
104
66
|
}, "strip", z.ZodTypeAny, {
|
|
105
67
|
port: number;
|
|
@@ -160,23 +122,7 @@ export declare const ConfigSchema: z.ZodObject<{
|
|
|
160
122
|
auditPath?: string | undefined;
|
|
161
123
|
}>;
|
|
162
124
|
export type Config = z.infer<typeof ConfigSchema>;
|
|
163
|
-
/** Разобранные аргументы командной строки. */
|
|
164
125
|
export type CliFlags = Record<string, string | boolean>;
|
|
165
|
-
/**
|
|
166
|
-
* Минимальный разбор argv: поддерживаются `--flag`, `--key=value` и `--key value`.
|
|
167
|
-
* Своя реализация вместо зависимости — набор флагов маленький и стабильный.
|
|
168
|
-
*/
|
|
169
126
|
export declare const parseFlags: (argv: readonly string[]) => CliFlags;
|
|
170
|
-
/**
|
|
171
|
-
* Нормализует базовый URL: убирает завершающий слэш и требует префикс Admin API.
|
|
172
|
-
* Сервер работает только с админским API — это гарантия, а не соглашение,
|
|
173
|
-
* поэтому проверка живёт здесь, а не в клиенте.
|
|
174
|
-
*/
|
|
175
127
|
export declare const normalizeBaseUrl: (raw: string) => string;
|
|
176
|
-
/**
|
|
177
|
-
* Собирает конфигурацию по приоритету: флаги > переменные окружения > ./oneentry-mcp-platform.json > дефолты.
|
|
178
|
-
* Валидация одна и та же для обоих режимов; отличается только то, что в remote-режиме
|
|
179
|
-
* обязателен путь аудита, а документация всегда берётся из снапшота.
|
|
180
|
-
*/
|
|
181
128
|
export declare const loadConfig: (argv: readonly string[], env?: NodeJS.ProcessEnv, cwd?: string) => Config;
|
|
182
|
-
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,eAAO,MAAM,gBAAgB,6CAA2C,CAAC;AACzE,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,gBAAgB,gCAA8B,CAAC;AAC5D,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;GAIG;AACH,eAAO,MAAM,YAAY;;IAEvB,qFAAqF;;;IAGrF,uFAAuF;;;IAGvF,iDAAiD;;IAEjD,sFAAsF;;IAEtF,gCAAgC;;IAEhC,qDAAqD;;IAErD,8CAA8C;;IAE9C,iFAAiF;;;;;QAK/E,iGAAiG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGnG,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAWlD,8CAA8C;AAC9C,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC;AAExD;;;GAGG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,SAAS,MAAM,EAAE,KAAG,QAsBpD,CAAC;AAgBF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,MAAM,KAAG,MAS9C,CAAC;AAkBF;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,SAAS,MAAM,EAAE,EACvB,MAAK,MAAM,CAAC,UAAwB,EACpC,MAAK,MAAsB,KAC1B,MAsDF,CAAC"}
|
package/dist/config/config.js
CHANGED
|
@@ -2,63 +2,31 @@ import { readFileSync } from 'node:fs';
|
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { resolve } from 'node:path';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
-
/**
|
|
6
|
-
* Уровень разрешённых операций.
|
|
7
|
-
* Читаем по умолчанию: агент не может ничего испортить, пока человек явно не разрешил.
|
|
8
|
-
*/
|
|
9
5
|
export const AllowLevelSchema = z.enum(['read', 'write', 'destructive']);
|
|
10
|
-
/**
|
|
11
|
-
* Режим работы сервера. Определяется транспортом, а не отдельным флагом:
|
|
12
|
-
* stdio -> local (агент и CMS на одной машине), streamable HTTP -> remote (сервис).
|
|
13
|
-
*/
|
|
14
6
|
export const ServerModeSchema = z.enum(['local', 'remote']);
|
|
15
|
-
/**
|
|
16
|
-
* Откуда брать документацию. Знания живут в отдельном публичном репозитории GitHub
|
|
17
|
-
* и скачиваются в рантайме, а не вшиваются в пакет: иначе правка одной строки
|
|
18
|
-
* документации требовала бы перевыпуска npm-пакета.
|
|
19
|
-
*/
|
|
20
7
|
export const KnowledgeConfigSchema = z.object({
|
|
21
|
-
/** `owner/name` репозитория знаний. */
|
|
22
8
|
repo: z.string().regex(/^[\w.-]+\/[\w.-]+$/, 'knowledge repo must look like "owner/name"'),
|
|
23
|
-
/** Ветка, тег или коммит. Пин на тег — способ зафиксировать знания для стенда. */
|
|
24
9
|
ref: z.string().min(1),
|
|
25
|
-
/** Локальный клон репозитория знаний: читать его вместо сети. */
|
|
26
10
|
path: z.string().optional(),
|
|
27
|
-
/** Сколько считать закэшированный коммит свежим, не спрашивая GitHub. */
|
|
28
11
|
refreshTtlMs: z.number().int().nonnegative(),
|
|
29
|
-
/** Не ходить в сеть: только кэш и вшитые правила. */
|
|
30
12
|
offline: z.boolean(),
|
|
31
|
-
/** Токен GitHub — только чтобы поднять лимит API. Репозиторий публичный. */
|
|
32
13
|
token: z.string().min(1).optional(),
|
|
33
14
|
});
|
|
34
|
-
/**
|
|
35
|
-
* Полная конфигурация сервера после слияния источников.
|
|
36
|
-
* Все дальнейшие слои получают её как зависимость и не читают process.env сами —
|
|
37
|
-
* это то, что позволяет держать один и тот же код для local и remote.
|
|
38
|
-
*/
|
|
39
15
|
export const ConfigSchema = z.object({
|
|
40
16
|
mode: ServerModeSchema,
|
|
41
|
-
/** Базовый URL Admin API, всегда с префиксом /api/admin и без завершающего слэша. */
|
|
42
17
|
baseUrl: z.string().url(),
|
|
43
18
|
allow: AllowLevelSchema,
|
|
44
|
-
/** Логин/пароль админа. В remote-режиме могут отсутствовать — тогда их даёт сессия. */
|
|
45
19
|
login: z.string().min(1).optional(),
|
|
46
20
|
password: z.string().min(1).optional(),
|
|
47
|
-
/** Готовый access-токен вместо логина/пароля. */
|
|
48
21
|
token: z.string().min(1).optional(),
|
|
49
22
|
knowledge: KnowledgeConfigSchema,
|
|
50
|
-
/** Каталог кэша: распакованный репозиторий знаний и снимок swagger стенда. */
|
|
51
23
|
cacheDir: z.string().min(1),
|
|
52
|
-
/** Файл JSONL-аудита. В remote-режиме обязателен. */
|
|
53
24
|
auditPath: z.string().optional(),
|
|
54
|
-
/** Таймаут одного запроса к Admin API, мс. */
|
|
55
25
|
requestTimeoutMs: z.number().int().positive(),
|
|
56
|
-
/** Максимальный размер сериализованного ответа, отдаваемого модели, в байтах. */
|
|
57
26
|
maxResponseBytes: z.number().int().positive(),
|
|
58
27
|
http: z.object({
|
|
59
28
|
port: z.number().int().min(1).max(65535),
|
|
60
29
|
host: z.string().min(1),
|
|
61
|
-
/** Разрешённые Origin для remote-режима. Пустой список = принимать только запросы без Origin. */
|
|
62
30
|
allowedOrigins: z.array(z.string()),
|
|
63
31
|
}),
|
|
64
32
|
});
|
|
@@ -71,13 +39,8 @@ const DEFAULTS = {
|
|
|
71
39
|
httpHost: '127.0.0.1',
|
|
72
40
|
knowledgeRepo: 'ONEENTRY-PLATFORM/oneentry-platform-rules',
|
|
73
41
|
knowledgeRef: 'main',
|
|
74
|
-
/** Час: достаточно редко, чтобы цикл перезапусков не упирался в лимит API GitHub. */
|
|
75
42
|
knowledgeTtlMs: 3_600_000,
|
|
76
43
|
};
|
|
77
|
-
/**
|
|
78
|
-
* Минимальный разбор argv: поддерживаются `--flag`, `--key=value` и `--key value`.
|
|
79
|
-
* Своя реализация вместо зависимости — набор флагов маленький и стабильный.
|
|
80
|
-
*/
|
|
81
44
|
export const parseFlags = (argv) => {
|
|
82
45
|
const flags = {};
|
|
83
46
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -103,10 +66,6 @@ export const parseFlags = (argv) => {
|
|
|
103
66
|
return flags;
|
|
104
67
|
};
|
|
105
68
|
const asString = (value) => typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
106
|
-
/**
|
|
107
|
-
* Булев флаг из трёх источников. Голый `--offline` — это `true`, поэтому
|
|
108
|
-
* значение флага может быть и строкой, и признаком присутствия.
|
|
109
|
-
*/
|
|
110
69
|
const asBoolean = (value, fallback) => {
|
|
111
70
|
if (value === undefined) {
|
|
112
71
|
return fallback;
|
|
@@ -116,10 +75,6 @@ const asBoolean = (value, fallback) => {
|
|
|
116
75
|
}
|
|
117
76
|
return ['1', 'true', 'yes', 'on'].includes(value.trim().toLowerCase());
|
|
118
77
|
};
|
|
119
|
-
/**
|
|
120
|
-
* Каталог кэша по умолчанию: XDG, с откатом на `~/.cache`.
|
|
121
|
-
* Кэш обязан пережить перезапуск процесса, поэтому временный каталог не годится.
|
|
122
|
-
*/
|
|
123
78
|
const defaultCacheDir = (env) => {
|
|
124
79
|
const xdg = asString(env['XDG_CACHE_HOME']);
|
|
125
80
|
return resolve(xdg ?? resolve(homedir(), '.cache'), 'oneentry-mcp-platform');
|
|
@@ -134,11 +89,6 @@ const asNumber = (value, fallback) => {
|
|
|
134
89
|
}
|
|
135
90
|
return parsed;
|
|
136
91
|
};
|
|
137
|
-
/**
|
|
138
|
-
* Нормализует базовый URL: убирает завершающий слэш и требует префикс Admin API.
|
|
139
|
-
* Сервер работает только с админским API — это гарантия, а не соглашение,
|
|
140
|
-
* поэтому проверка живёт здесь, а не в клиенте.
|
|
141
|
-
*/
|
|
142
92
|
export const normalizeBaseUrl = (raw) => {
|
|
143
93
|
const trimmed = raw.replace(/\/+$/, '');
|
|
144
94
|
if (!trimmed.includes('/api/admin')) {
|
|
@@ -163,11 +113,6 @@ const readConfigFile = (cwd) => {
|
|
|
163
113
|
throw error;
|
|
164
114
|
}
|
|
165
115
|
};
|
|
166
|
-
/**
|
|
167
|
-
* Собирает конфигурацию по приоритету: флаги > переменные окружения > ./oneentry-mcp-platform.json > дефолты.
|
|
168
|
-
* Валидация одна и та же для обоих режимов; отличается только то, что в remote-режиме
|
|
169
|
-
* обязателен путь аудита, а документация всегда берётся из снапшота.
|
|
170
|
-
*/
|
|
171
116
|
export const loadConfig = (argv, env = process.env, cwd = process.cwd()) => {
|
|
172
117
|
const flags = parseFlags(argv);
|
|
173
118
|
const file = readConfigFile(cwd);
|
|
@@ -202,7 +147,6 @@ export const loadConfig = (argv, env = process.env, cwd = process.cwd()) => {
|
|
|
202
147
|
path: pickKnowledge('knowledge-path', 'ONEENTRY_MCP_KNOWLEDGE_PATH', 'path'),
|
|
203
148
|
refreshTtlMs: asNumber(pickKnowledge('knowledge-ttl', 'ONEENTRY_MCP_KNOWLEDGE_TTL_MS', 'refreshTtlMs'), DEFAULTS.knowledgeTtlMs),
|
|
204
149
|
offline: asBoolean(flags['offline'] ?? env['ONEENTRY_MCP_OFFLINE'], false),
|
|
205
|
-
/** Только из окружения: секрет не должен попадать ни в argv, ни в файл конфигурации. */
|
|
206
150
|
token: asString(env['ONEENTRY_GITHUB_TOKEN']),
|
|
207
151
|
},
|
|
208
152
|
cacheDir: pick('cache-dir', 'ONEENTRY_MCP_CACHE_DIR', 'cacheDir') ?? defaultCacheDir(env),
|
|
@@ -216,9 +160,6 @@ export const loadConfig = (argv, env = process.env, cwd = process.cwd()) => {
|
|
|
216
160
|
},
|
|
217
161
|
};
|
|
218
162
|
const config = ConfigSchema.parse(candidate);
|
|
219
|
-
/**
|
|
220
|
-
* Пароль через флаг не принимаем ни в каком режиме: argv видно в списке процессов.
|
|
221
|
-
*/
|
|
222
163
|
if (asString(flags['password'])) {
|
|
223
164
|
throw new Error('Refusing --password: pass ONEENTRY_CMS_PASSWORD via the environment instead.');
|
|
224
165
|
}
|
|
@@ -227,4 +168,3 @@ export const loadConfig = (argv, env = process.env, cwd = process.cwd()) => {
|
|
|
227
168
|
}
|
|
228
169
|
return config;
|
|
229
170
|
};
|
|
230
|
-
//# sourceMappingURL=config.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Публичный API пакета: всё, что нужно, чтобы встроить сервер в свой процесс
|
|
3
|
-
* или собрать его иначе, чем это делает CLI.
|
|
4
|
-
*/
|
|
5
1
|
export { loadConfig, parseFlags, normalizeBaseUrl, ConfigSchema } from './config/config.js';
|
|
6
2
|
export type { Config, AllowLevel, ServerMode } from './config/config.js';
|
|
7
3
|
export { createServer, createSharedDeps } from './server.js';
|
|
@@ -22,9 +18,9 @@ export type { KnowledgeFile, KnowledgeSource, KnowledgeTree } from './knowledge/
|
|
|
22
18
|
export { readTar, readTarGz } from './knowledge/tar.js';
|
|
23
19
|
export { buildCatalog } from './api/build-catalog.js';
|
|
24
20
|
export type { PermissionMap } from './api/build-catalog.js';
|
|
25
|
-
export { fetchSwagger } from './api/swagger-source.js';
|
|
21
|
+
export { fetchSwagger, nestSwaggerUrl, nodeSwaggerUrl, swaggerAttempts } from './api/swagger-source.js';
|
|
22
|
+
export type { FetchedSwagger, SwaggerAttempt, SwaggerVariant } from './api/swagger-source.js';
|
|
26
23
|
export { runStdio } from './transports/stdio.js';
|
|
27
24
|
export { runHttp } from './transports/http.js';
|
|
28
25
|
export type { Catalog, Operation, JsonSchema, RiskLevel } from './api/types.js';
|
|
29
26
|
export type { KnowledgeChunk, KnowledgeDoc, KnowledgeOrigin, KnowledgePack, } from './knowledge/types.js';
|
|
30
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5F,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC5F,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC"}
|