@oneentry/mcp-platform-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +189 -0
  2. package/data/catalog.json +1 -0
  3. package/data/knowledge.json +1 -0
  4. package/dist/api/audit.d.ts +32 -0
  5. package/dist/api/audit.d.ts.map +1 -0
  6. package/dist/api/audit.js +35 -0
  7. package/dist/api/audit.js.map +1 -0
  8. package/dist/api/auth.d.ts +53 -0
  9. package/dist/api/auth.d.ts.map +1 -0
  10. package/dist/api/auth.js +126 -0
  11. package/dist/api/auth.js.map +1 -0
  12. package/dist/api/catalog.d.ts +39 -0
  13. package/dist/api/catalog.d.ts.map +1 -0
  14. package/dist/api/catalog.js +108 -0
  15. package/dist/api/catalog.js.map +1 -0
  16. package/dist/api/client.d.ts +60 -0
  17. package/dist/api/client.d.ts.map +1 -0
  18. package/dist/api/client.js +196 -0
  19. package/dist/api/client.js.map +1 -0
  20. package/dist/api/policy.d.ts +52 -0
  21. package/dist/api/policy.d.ts.map +1 -0
  22. package/dist/api/policy.js +0 -0
  23. package/dist/api/policy.js.map +1 -0
  24. package/dist/api/shape.d.ts +19 -0
  25. package/dist/api/shape.d.ts.map +1 -0
  26. package/dist/api/shape.js +151 -0
  27. package/dist/api/shape.js.map +1 -0
  28. package/dist/api/types.d.ts +85 -0
  29. package/dist/api/types.d.ts.map +1 -0
  30. package/dist/api/types.js +2 -0
  31. package/dist/api/types.js.map +1 -0
  32. package/dist/bin/cli.d.ts +3 -0
  33. package/dist/bin/cli.d.ts.map +1 -0
  34. package/dist/bin/cli.js +48 -0
  35. package/dist/bin/cli.js.map +1 -0
  36. package/dist/config/config.d.ts +108 -0
  37. package/dist/config/config.d.ts.map +1 -0
  38. package/dist/config/config.js +167 -0
  39. package/dist/config/config.js.map +1 -0
  40. package/dist/index.d.ts +23 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +18 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/knowledge/chunk.d.ts +35 -0
  45. package/dist/knowledge/chunk.d.ts.map +1 -0
  46. package/dist/knowledge/chunk.js +87 -0
  47. package/dist/knowledge/chunk.js.map +1 -0
  48. package/dist/knowledge/loader.d.ts +27 -0
  49. package/dist/knowledge/loader.d.ts.map +1 -0
  50. package/dist/knowledge/loader.js +125 -0
  51. package/dist/knowledge/loader.js.map +1 -0
  52. package/dist/knowledge/search.d.ts +34 -0
  53. package/dist/knowledge/search.d.ts.map +1 -0
  54. package/dist/knowledge/search.js +95 -0
  55. package/dist/knowledge/search.js.map +1 -0
  56. package/dist/knowledge/types.d.ts +47 -0
  57. package/dist/knowledge/types.d.ts.map +1 -0
  58. package/dist/knowledge/types.js +2 -0
  59. package/dist/knowledge/types.js.map +1 -0
  60. package/dist/server.d.ts +16 -0
  61. package/dist/server.d.ts.map +1 -0
  62. package/dist/server.js +48 -0
  63. package/dist/server.js.map +1 -0
  64. package/dist/session.d.ts +43 -0
  65. package/dist/session.d.ts.map +1 -0
  66. package/dist/session.js +75 -0
  67. package/dist/session.js.map +1 -0
  68. package/dist/tools/api-call.d.ts +5 -0
  69. package/dist/tools/api-call.d.ts.map +1 -0
  70. package/dist/tools/api-call.js +169 -0
  71. package/dist/tools/api-call.js.map +1 -0
  72. package/dist/tools/api-discovery.d.ts +5 -0
  73. package/dist/tools/api-discovery.d.ts.map +1 -0
  74. package/dist/tools/api-discovery.js +80 -0
  75. package/dist/tools/api-discovery.js.map +1 -0
  76. package/dist/tools/docs.d.ts +5 -0
  77. package/dist/tools/docs.d.ts.map +1 -0
  78. package/dist/tools/docs.js +113 -0
  79. package/dist/tools/docs.js.map +1 -0
  80. package/dist/tools/guide.d.ts +11 -0
  81. package/dist/tools/guide.d.ts.map +1 -0
  82. package/dist/tools/guide.js +67 -0
  83. package/dist/tools/guide.js.map +1 -0
  84. package/dist/tools/result.d.ts +19 -0
  85. package/dist/tools/result.d.ts.map +1 -0
  86. package/dist/tools/result.js +19 -0
  87. package/dist/tools/result.js.map +1 -0
  88. package/dist/tools/whoami.d.ts +5 -0
  89. package/dist/tools/whoami.d.ts.map +1 -0
  90. package/dist/tools/whoami.js +42 -0
  91. package/dist/tools/whoami.js.map +1 -0
  92. package/dist/transports/http.d.ts +10 -0
  93. package/dist/transports/http.d.ts.map +1 -0
  94. package/dist/transports/http.js +126 -0
  95. package/dist/transports/http.js.map +1 -0
  96. package/dist/transports/stdio.d.ts +8 -0
  97. package/dist/transports/stdio.d.ts.map +1 -0
  98. package/dist/transports/stdio.js +15 -0
  99. package/dist/transports/stdio.js.map +1 -0
  100. package/package.json +60 -0
@@ -0,0 +1,108 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Уровень разрешённых операций.
4
+ * Читаем по умолчанию: агент не может ничего испортить, пока человек явно не разрешил.
5
+ */
6
+ export declare const AllowLevelSchema: z.ZodEnum<["read", "write", "destructive"]>;
7
+ export type AllowLevel = z.infer<typeof AllowLevelSchema>;
8
+ /**
9
+ * Режим работы сервера. Определяется транспортом, а не отдельным флагом:
10
+ * stdio -> local (агент и CMS на одной машине), streamable HTTP -> remote (сервис).
11
+ */
12
+ export declare const ServerModeSchema: z.ZodEnum<["local", "remote"]>;
13
+ export type ServerMode = z.infer<typeof ServerModeSchema>;
14
+ /**
15
+ * Полная конфигурация сервера после слияния источников.
16
+ * Все дальнейшие слои получают её как зависимость и не читают process.env сами —
17
+ * это то, что позволяет держать один и тот же код для local и remote.
18
+ */
19
+ export declare const ConfigSchema: z.ZodObject<{
20
+ mode: z.ZodEnum<["local", "remote"]>;
21
+ /** Базовый URL Admin API, всегда с префиксом /api/admin и без завершающего слэша. */
22
+ baseUrl: z.ZodString;
23
+ allow: z.ZodEnum<["read", "write", "destructive"]>;
24
+ /** Логин/пароль админа. В remote-режиме могут отсутствовать — тогда их даёт сессия. */
25
+ login: z.ZodOptional<z.ZodString>;
26
+ password: z.ZodOptional<z.ZodString>;
27
+ /** Готовый access-токен вместо логина/пароля. */
28
+ token: z.ZodOptional<z.ZodString>;
29
+ /** Путь к чекауту dnk-back: включает чтение документации «живьём» вместо снапшота. */
30
+ backPath: z.ZodOptional<z.ZodString>;
31
+ /** Путь к чекауту dnk-front. */
32
+ frontPath: z.ZodOptional<z.ZodString>;
33
+ /** Файл JSONL-аудита. В remote-режиме обязателен. */
34
+ auditPath: z.ZodOptional<z.ZodString>;
35
+ /** Таймаут одного запроса к Admin API, мс. */
36
+ requestTimeoutMs: z.ZodNumber;
37
+ /** Максимальный размер сериализованного ответа, отдаваемого модели, в байтах. */
38
+ maxResponseBytes: z.ZodNumber;
39
+ http: z.ZodObject<{
40
+ port: z.ZodNumber;
41
+ host: z.ZodString;
42
+ /** Разрешённые Origin для remote-режима. Пустой список = принимать только запросы без Origin. */
43
+ allowedOrigins: z.ZodArray<z.ZodString, "many">;
44
+ }, "strip", z.ZodTypeAny, {
45
+ port: number;
46
+ host: string;
47
+ allowedOrigins: string[];
48
+ }, {
49
+ port: number;
50
+ host: string;
51
+ allowedOrigins: string[];
52
+ }>;
53
+ }, "strip", z.ZodTypeAny, {
54
+ mode: "local" | "remote";
55
+ baseUrl: string;
56
+ allow: "read" | "write" | "destructive";
57
+ requestTimeoutMs: number;
58
+ maxResponseBytes: number;
59
+ http: {
60
+ port: number;
61
+ host: string;
62
+ allowedOrigins: string[];
63
+ };
64
+ login?: string | undefined;
65
+ password?: string | undefined;
66
+ token?: string | undefined;
67
+ backPath?: string | undefined;
68
+ frontPath?: string | undefined;
69
+ auditPath?: string | undefined;
70
+ }, {
71
+ mode: "local" | "remote";
72
+ baseUrl: string;
73
+ allow: "read" | "write" | "destructive";
74
+ requestTimeoutMs: number;
75
+ maxResponseBytes: number;
76
+ http: {
77
+ port: number;
78
+ host: string;
79
+ allowedOrigins: string[];
80
+ };
81
+ login?: string | undefined;
82
+ password?: string | undefined;
83
+ token?: string | undefined;
84
+ backPath?: string | undefined;
85
+ frontPath?: string | undefined;
86
+ auditPath?: string | undefined;
87
+ }>;
88
+ export type Config = z.infer<typeof ConfigSchema>;
89
+ /** Разобранные аргументы командной строки. */
90
+ export type CliFlags = Record<string, string | boolean>;
91
+ /**
92
+ * Минимальный разбор argv: поддерживаются `--flag`, `--key=value` и `--key value`.
93
+ * Своя реализация вместо зависимости — набор флагов маленький и стабильный.
94
+ */
95
+ export declare const parseFlags: (argv: readonly string[]) => CliFlags;
96
+ /**
97
+ * Нормализует базовый URL: убирает завершающий слэш и требует префикс Admin API.
98
+ * Сервер работает только с админским API — это гарантия, а не соглашение,
99
+ * поэтому проверка живёт здесь, а не в клиенте.
100
+ */
101
+ export declare const normalizeBaseUrl: (raw: string) => string;
102
+ /**
103
+ * Собирает конфигурацию по приоритету: флаги > переменные окружения > ./oneentry-mcp-platform.json > дефолты.
104
+ * Валидация одна и та же для обоих режимов; отличается только то, что в remote-режиме
105
+ * обязателен путь аудита, а документация всегда берётся из снапшота.
106
+ */
107
+ export declare const loadConfig: (argv: readonly string[], env?: NodeJS.ProcessEnv, cwd?: string) => Config;
108
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
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"}
@@ -0,0 +1,167 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { z } from 'zod';
4
+ /**
5
+ * Уровень разрешённых операций.
6
+ * Читаем по умолчанию: агент не может ничего испортить, пока человек явно не разрешил.
7
+ */
8
+ export const AllowLevelSchema = z.enum(['read', 'write', 'destructive']);
9
+ /**
10
+ * Режим работы сервера. Определяется транспортом, а не отдельным флагом:
11
+ * stdio -> local (агент и CMS на одной машине), streamable HTTP -> remote (сервис).
12
+ */
13
+ export const ServerModeSchema = z.enum(['local', 'remote']);
14
+ /**
15
+ * Полная конфигурация сервера после слияния источников.
16
+ * Все дальнейшие слои получают её как зависимость и не читают process.env сами —
17
+ * это то, что позволяет держать один и тот же код для local и remote.
18
+ */
19
+ export const ConfigSchema = z.object({
20
+ mode: ServerModeSchema,
21
+ /** Базовый URL Admin API, всегда с префиксом /api/admin и без завершающего слэша. */
22
+ baseUrl: z.string().url(),
23
+ allow: AllowLevelSchema,
24
+ /** Логин/пароль админа. В remote-режиме могут отсутствовать — тогда их даёт сессия. */
25
+ login: z.string().min(1).optional(),
26
+ password: z.string().min(1).optional(),
27
+ /** Готовый access-токен вместо логина/пароля. */
28
+ token: z.string().min(1).optional(),
29
+ /** Путь к чекауту dnk-back: включает чтение документации «живьём» вместо снапшота. */
30
+ backPath: z.string().optional(),
31
+ /** Путь к чекауту dnk-front. */
32
+ frontPath: z.string().optional(),
33
+ /** Файл JSONL-аудита. В remote-режиме обязателен. */
34
+ auditPath: z.string().optional(),
35
+ /** Таймаут одного запроса к Admin API, мс. */
36
+ requestTimeoutMs: z.number().int().positive(),
37
+ /** Максимальный размер сериализованного ответа, отдаваемого модели, в байтах. */
38
+ maxResponseBytes: z.number().int().positive(),
39
+ http: z.object({
40
+ port: z.number().int().min(1).max(65535),
41
+ host: z.string().min(1),
42
+ /** Разрешённые Origin для remote-режима. Пустой список = принимать только запросы без Origin. */
43
+ allowedOrigins: z.array(z.string()),
44
+ }),
45
+ });
46
+ const DEFAULTS = {
47
+ baseUrl: 'http://localhost:3003/api/admin',
48
+ allow: 'read',
49
+ requestTimeoutMs: 30_000,
50
+ maxResponseBytes: 24_576,
51
+ httpPort: 8931,
52
+ httpHost: '127.0.0.1',
53
+ };
54
+ /**
55
+ * Минимальный разбор argv: поддерживаются `--flag`, `--key=value` и `--key value`.
56
+ * Своя реализация вместо зависимости — набор флагов маленький и стабильный.
57
+ */
58
+ export const parseFlags = (argv) => {
59
+ const flags = {};
60
+ for (let i = 0; i < argv.length; i++) {
61
+ const arg = argv[i];
62
+ if (!arg || !arg.startsWith('--')) {
63
+ continue;
64
+ }
65
+ const body = arg.slice(2);
66
+ const eq = body.indexOf('=');
67
+ if (eq !== -1) {
68
+ flags[body.slice(0, eq)] = body.slice(eq + 1);
69
+ continue;
70
+ }
71
+ const next = argv[i + 1];
72
+ if (next && !next.startsWith('--')) {
73
+ flags[body] = next;
74
+ i++;
75
+ }
76
+ else {
77
+ flags[body] = true;
78
+ }
79
+ }
80
+ return flags;
81
+ };
82
+ const asString = (value) => typeof value === 'string' && value.length > 0 ? value : undefined;
83
+ const asNumber = (value, fallback) => {
84
+ if (value === undefined) {
85
+ return fallback;
86
+ }
87
+ const parsed = Number(value);
88
+ if (!Number.isFinite(parsed)) {
89
+ throw new Error(`Expected a number, got "${value}"`);
90
+ }
91
+ return parsed;
92
+ };
93
+ /**
94
+ * Нормализует базовый URL: убирает завершающий слэш и требует префикс Admin API.
95
+ * Сервер работает только с админским API — это гарантия, а не соглашение,
96
+ * поэтому проверка живёт здесь, а не в клиенте.
97
+ */
98
+ export const normalizeBaseUrl = (raw) => {
99
+ const trimmed = raw.replace(/\/+$/, '');
100
+ if (!trimmed.includes('/api/admin')) {
101
+ throw new Error(`baseUrl must point at the Admin API (…/api/admin), got "${raw}". ` +
102
+ 'This server intentionally exposes the Admin API only.');
103
+ }
104
+ return trimmed;
105
+ };
106
+ const readConfigFile = (cwd) => {
107
+ try {
108
+ const raw = readFileSync(resolve(cwd, 'oneentry-mcp-platform.json'), 'utf8');
109
+ const parsed = JSON.parse(raw);
110
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
111
+ throw new Error('oneentry-mcp-platform.json must contain a JSON object');
112
+ }
113
+ return parsed;
114
+ }
115
+ catch (error) {
116
+ if (error.code === 'ENOENT') {
117
+ return {};
118
+ }
119
+ throw error;
120
+ }
121
+ };
122
+ /**
123
+ * Собирает конфигурацию по приоритету: флаги > переменные окружения > ./oneentry-mcp-platform.json > дефолты.
124
+ * Валидация одна и та же для обоих режимов; отличается только то, что в remote-режиме
125
+ * обязателен путь аудита, а документация всегда берётся из снапшота.
126
+ */
127
+ export const loadConfig = (argv, env = process.env, cwd = process.cwd()) => {
128
+ const flags = parseFlags(argv);
129
+ const file = readConfigFile(cwd);
130
+ const fileString = (key) => {
131
+ const value = file[key];
132
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
133
+ };
134
+ const pick = (flagKey, envKey, fileKey) => asString(flags[flagKey]) ?? asString(env[envKey]) ?? fileString(fileKey);
135
+ const mode = flags['http'] === true || asString(flags['http']) ? 'remote' : 'local';
136
+ const originsRaw = pick('allowed-origins', 'ONEENTRY_MCP_ALLOWED_ORIGINS', 'allowedOrigins');
137
+ const candidate = {
138
+ mode,
139
+ baseUrl: normalizeBaseUrl(pick('base-url', 'ONEENTRY_CMS_BASE_URL', 'baseUrl') ?? DEFAULTS.baseUrl),
140
+ allow: AllowLevelSchema.parse(pick('allow', 'ONEENTRY_MCP_ALLOW', 'allow') ?? DEFAULTS.allow),
141
+ login: pick('login', 'ONEENTRY_CMS_LOGIN', 'login'),
142
+ password: asString(env['ONEENTRY_CMS_PASSWORD']) ?? fileString('password'),
143
+ token: asString(env['ONEENTRY_CMS_TOKEN']) ?? fileString('token'),
144
+ backPath: pick('back', 'ONEENTRY_MCP_BACK_PATH', 'backPath'),
145
+ frontPath: pick('front', 'ONEENTRY_MCP_FRONT_PATH', 'frontPath'),
146
+ auditPath: pick('audit', 'ONEENTRY_MCP_AUDIT_PATH', 'auditPath'),
147
+ requestTimeoutMs: asNumber(pick('request-timeout', 'ONEENTRY_MCP_REQUEST_TIMEOUT_MS', 'requestTimeoutMs'), DEFAULTS.requestTimeoutMs),
148
+ maxResponseBytes: asNumber(pick('max-response-bytes', 'ONEENTRY_MCP_MAX_RESPONSE_BYTES', 'maxResponseBytes'), DEFAULTS.maxResponseBytes),
149
+ http: {
150
+ port: asNumber(pick('port', 'ONEENTRY_MCP_PORT', 'port'), DEFAULTS.httpPort),
151
+ host: pick('host', 'ONEENTRY_MCP_HOST', 'host') ?? DEFAULTS.httpHost,
152
+ allowedOrigins: originsRaw ? originsRaw.split(',').map((o) => o.trim()).filter(Boolean) : [],
153
+ },
154
+ };
155
+ const config = ConfigSchema.parse(candidate);
156
+ /**
157
+ * Пароль через флаг не принимаем ни в каком режиме: argv видно в списке процессов.
158
+ */
159
+ if (asString(flags['password'])) {
160
+ throw new Error('Refusing --password: pass ONEENTRY_CMS_PASSWORD via the environment instead.');
161
+ }
162
+ if (config.mode === 'remote' && !config.auditPath) {
163
+ throw new Error('Remote mode requires --audit <path>: every mutation must be auditable.');
164
+ }
165
+ return config;
166
+ };
167
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Публичный API пакета: всё, что нужно, чтобы встроить сервер в свой процесс
3
+ * или собрать его иначе, чем это делает CLI.
4
+ */
5
+ export { loadConfig, parseFlags, normalizeBaseUrl, ConfigSchema } from './config/config.js';
6
+ export type { Config, AllowLevel, ServerMode } from './config/config.js';
7
+ export { createServer, createSharedDeps } from './server.js';
8
+ export { Session } from './session.js';
9
+ export type { SharedDeps } from './session.js';
10
+ export { OperationCatalog } from './api/catalog.js';
11
+ export { AdminApiClient, buildUrl, RequestBuildError } from './api/client.js';
12
+ export { ConfirmStore, decide } from './api/policy.js';
13
+ export type { PolicyDecision } from './api/policy.js';
14
+ export { shapeResponse } from './api/shape.js';
15
+ export { AuditLog } from './api/audit.js';
16
+ export { TokenStore, AuthError } from './api/auth.js';
17
+ export { KnowledgeIndex } from './knowledge/search.js';
18
+ export { buildPack, loadSnapshot, resolveKnowledge } from './knowledge/loader.js';
19
+ export { runStdio } from './transports/stdio.js';
20
+ export { runHttp } from './transports/http.js';
21
+ export type { Catalog, Operation, JsonSchema, RiskLevel } from './api/types.js';
22
+ export type { KnowledgeChunk, KnowledgeDoc, KnowledgePack } from './knowledge/types.js';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,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"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Публичный API пакета: всё, что нужно, чтобы встроить сервер в свой процесс
3
+ * или собрать его иначе, чем это делает CLI.
4
+ */
5
+ export { loadConfig, parseFlags, normalizeBaseUrl, ConfigSchema } from './config/config.js';
6
+ export { createServer, createSharedDeps } from './server.js';
7
+ export { Session } from './session.js';
8
+ export { OperationCatalog } from './api/catalog.js';
9
+ export { AdminApiClient, buildUrl, RequestBuildError } from './api/client.js';
10
+ export { ConfirmStore, decide } from './api/policy.js';
11
+ export { shapeResponse } from './api/shape.js';
12
+ export { AuditLog } from './api/audit.js';
13
+ export { TokenStore, AuthError } from './api/auth.js';
14
+ export { KnowledgeIndex } from './knowledge/search.js';
15
+ export { buildPack, loadSnapshot, resolveKnowledge } from './knowledge/loader.js';
16
+ export { runStdio } from './transports/stdio.js';
17
+ export { runHttp } from './transports/http.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,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;AAEvD,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"}
@@ -0,0 +1,35 @@
1
+ import type { KnowledgeChunk, KnowledgeDoc } from './types.js';
2
+ /**
3
+ * Слаг заголовка в стиле GitHub: нижний регистр, пробелы в дефисы,
4
+ * пунктуация выброшена. Кириллица сохраняется — документация в проекте русскоязычная.
5
+ */
6
+ export declare const slugify: (heading: string) => string;
7
+ interface Section {
8
+ title: string;
9
+ lines: string[];
10
+ }
11
+ /**
12
+ * Режет markdown по заголовкам `##` и `###`.
13
+ * Преамбула до первого `##` становится разделом с пустым anchor — в ней обычно
14
+ * лежит самое важное описание модуля, терять его нельзя.
15
+ */
16
+ export declare const splitSections: (markdown: string) => {
17
+ docTitle: string;
18
+ sections: Section[];
19
+ };
20
+ /**
21
+ * Превращает один markdown-файл в документ + его разделы.
22
+ * Anchor'ы дедуплицируются суффиксом, иначе два одинаковых `## Схема`
23
+ * в одном файле стали бы неразличимы для cms_docs_read.
24
+ */
25
+ export declare const chunkDocument: (params: {
26
+ docId: string;
27
+ repo: KnowledgeChunk["repo"];
28
+ path: string;
29
+ markdown: string;
30
+ }) => {
31
+ doc: KnowledgeDoc;
32
+ chunks: KnowledgeChunk[];
33
+ };
34
+ export {};
35
+ //# sourceMappingURL=chunk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk.d.ts","sourceRoot":"","sources":["../../src/knowledge/chunk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,OAAO,GAAI,SAAS,MAAM,KAAG,MAMzB,CAAC;AAKlB,UAAU,OAAO;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,UAAU,MAAM,KAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,EAAE,CAAA;CA6BvF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,GAAI,QAAQ;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,KAAG;IAAE,GAAG,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,cAAc,EAAE,CAAA;CAqChD,CAAC"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Слаг заголовка в стиле GitHub: нижний регистр, пробелы в дефисы,
3
+ * пунктуация выброшена. Кириллица сохраняется — документация в проекте русскоязычная.
4
+ */
5
+ export const slugify = (heading) => heading
6
+ .toLowerCase()
7
+ .replace(/`|\*|_|\[|\]|\(|\)|:|,|\.|\/|\\|«|»|"|'|\?|!|;/g, '')
8
+ .trim()
9
+ .replace(/\s+/g, '-')
10
+ .slice(0, 80);
11
+ /** Строки внутри огороженных блоков кода не считаются заголовками. */
12
+ const isFence = (line) => line.startsWith('```') || line.startsWith('~~~');
13
+ /**
14
+ * Режет markdown по заголовкам `##` и `###`.
15
+ * Преамбула до первого `##` становится разделом с пустым anchor — в ней обычно
16
+ * лежит самое важное описание модуля, терять его нельзя.
17
+ */
18
+ export const splitSections = (markdown) => {
19
+ const lines = markdown.split('\n');
20
+ let docTitle = '';
21
+ const sections = [{ title: '', lines: [] }];
22
+ let inFence = false;
23
+ for (const line of lines) {
24
+ if (isFence(line)) {
25
+ inFence = !inFence;
26
+ }
27
+ if (!inFence) {
28
+ const h1 = /^#\s+(.*)$/.exec(line);
29
+ if (h1 && !docTitle) {
30
+ docTitle = (h1[1] ?? '').trim();
31
+ continue;
32
+ }
33
+ const heading = /^(##|###)\s+(.*)$/.exec(line);
34
+ if (heading) {
35
+ sections.push({ title: (heading[2] ?? '').trim(), lines: [] });
36
+ continue;
37
+ }
38
+ }
39
+ sections[sections.length - 1]?.lines.push(line);
40
+ }
41
+ return {
42
+ docTitle,
43
+ sections: sections.filter((s) => s.title !== '' || s.lines.join('').trim() !== ''),
44
+ };
45
+ };
46
+ /**
47
+ * Превращает один markdown-файл в документ + его разделы.
48
+ * Anchor'ы дедуплицируются суффиксом, иначе два одинаковых `## Схема`
49
+ * в одном файле стали бы неразличимы для cms_docs_read.
50
+ */
51
+ export const chunkDocument = (params) => {
52
+ const { docTitle, sections } = splitSections(params.markdown);
53
+ const seen = new Map();
54
+ const chunks = [];
55
+ for (const section of sections) {
56
+ const base = section.title === '' ? '' : slugify(section.title);
57
+ const count = seen.get(base) ?? 0;
58
+ seen.set(base, count + 1);
59
+ const anchor = count === 0 ? base : `${base}-${count + 1}`;
60
+ const text = section.lines.join('\n').trim();
61
+ chunks.push({
62
+ id: `${params.docId}#${anchor}`,
63
+ docId: params.docId,
64
+ repo: params.repo,
65
+ path: params.path,
66
+ anchor,
67
+ title: section.title === '' ? (docTitle || params.docId) : section.title,
68
+ docTitle: docTitle || params.docId,
69
+ text,
70
+ });
71
+ }
72
+ return {
73
+ doc: {
74
+ docId: params.docId,
75
+ repo: params.repo,
76
+ path: params.path,
77
+ title: docTitle || params.docId,
78
+ anchors: chunks.map((c) => ({
79
+ anchor: c.anchor,
80
+ title: c.title,
81
+ bytes: Buffer.byteLength(c.text, 'utf8'),
82
+ })),
83
+ },
84
+ chunks,
85
+ };
86
+ };
87
+ //# sourceMappingURL=chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk.js","sourceRoot":"","sources":["../../src/knowledge/chunk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { KnowledgePack } from './types.js';
2
+ /** Каталог со собственными знаниями пакета (operating-rules.md и т.п.). */
3
+ export declare const ownKnowledgeDir: () => string;
4
+ /** Каталог со собранными данными пакета (knowledge.json, catalog.json). */
5
+ export declare const dataDir: () => string;
6
+ /**
7
+ * Собирает пакет знаний из чекаутов. Используется и сборкой снапшота,
8
+ * и live-режимом, поэтому результат в обоих случаях идентичен по структуре.
9
+ */
10
+ export declare const buildPack: (params: {
11
+ backPath?: string;
12
+ frontPath?: string;
13
+ source: KnowledgePack["source"];
14
+ builtAt: string;
15
+ }) => KnowledgePack;
16
+ /** Читает собранный снапшот из data/knowledge.json. */
17
+ export declare const loadSnapshot: () => KnowledgePack;
18
+ /**
19
+ * Выбирает источник знаний: живой чекаут, если он указан, иначе снапшот пакета.
20
+ * Live-режим нужен, чтобы правка документации в dnk-back действовала сразу,
21
+ * без переиздания npm-пакета.
22
+ */
23
+ export declare const resolveKnowledge: (params: {
24
+ backPath?: string;
25
+ frontPath?: string;
26
+ }) => KnowledgePack;
27
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/knowledge/loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAgC,aAAa,EAAE,MAAM,YAAY,CAAC;AAsF9E,2EAA2E;AAC3E,eAAO,MAAM,eAAe,QAAO,MACuC,CAAC;AAE3E,2EAA2E;AAC3E,eAAO,MAAM,OAAO,QAAO,MAC0C,CAAC;AAEtE;;;GAGG;AACH,eAAO,MAAM,SAAS,GAAI,QAAQ;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB,KAAG,aA0BH,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,YAAY,QAAO,aAO/B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,QAAQ;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,KAAG,aAUH,CAAC"}
@@ -0,0 +1,125 @@
1
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import { join, relative, resolve, sep } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { chunkDocument } from './chunk.js';
5
+ const BACK_SOURCES = [
6
+ { repo: 'back', subPath: '.claude/docs', docPrefix: 'back/docs' },
7
+ { repo: 'back', subPath: '.claude/tests', docPrefix: 'back/tests' },
8
+ { repo: 'back', subPath: '.claude/rules', docPrefix: 'back/rules' },
9
+ { repo: 'back', subPath: '.claude/fixes', docPrefix: 'back/fixes' },
10
+ { repo: 'back', subPath: '.claude/CLAUDE.md', docPrefix: 'back', singleFile: true },
11
+ ];
12
+ const FRONT_SOURCES = [
13
+ { repo: 'front', subPath: '.claude/docs', docPrefix: 'front/docs' },
14
+ { repo: 'front', subPath: '.claude/rules', docPrefix: 'front/rules' },
15
+ { repo: 'front', subPath: '.claude/fixes', docPrefix: 'front/fixes' },
16
+ ];
17
+ /** Рекурсивно собирает пути всех `*.md` внутри каталога. */
18
+ const walkMarkdown = (root) => {
19
+ const out = [];
20
+ const visit = (dir) => {
21
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
22
+ const full = join(dir, entry.name);
23
+ if (entry.isDirectory()) {
24
+ visit(full);
25
+ }
26
+ else if (entry.isFile() && entry.name.endsWith('.md')) {
27
+ out.push(full);
28
+ }
29
+ }
30
+ };
31
+ visit(root);
32
+ return out.sort();
33
+ };
34
+ const exists = (path) => {
35
+ try {
36
+ statSync(path);
37
+ return true;
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ };
43
+ const collectSource = (repoRoot, spec) => {
44
+ const target = resolve(repoRoot, spec.subPath);
45
+ const docs = [];
46
+ const chunks = [];
47
+ if (!exists(target)) {
48
+ return { docs, chunks };
49
+ }
50
+ const files = spec.singleFile ? [target] : walkMarkdown(target);
51
+ for (const file of files) {
52
+ const rel = spec.singleFile
53
+ ? file.split(sep).slice(-1).join('')
54
+ : relative(target, file);
55
+ const slug = rel.replace(/\.md$/, '').split(sep).join('/');
56
+ const docId = spec.docPrefix ? `${spec.docPrefix}/${slug}` : slug;
57
+ const result = chunkDocument({
58
+ docId,
59
+ repo: spec.repo,
60
+ path: relative(repoRoot, file).split(sep).join('/'),
61
+ markdown: readFileSync(file, 'utf8'),
62
+ });
63
+ docs.push(result.doc);
64
+ chunks.push(...result.chunks);
65
+ }
66
+ return { docs, chunks };
67
+ };
68
+ /** Каталог со собственными знаниями пакета (operating-rules.md и т.п.). */
69
+ export const ownKnowledgeDir = () => resolve(fileURLToPath(new URL('.', import.meta.url)), '../../knowledge');
70
+ /** Каталог со собранными данными пакета (knowledge.json, catalog.json). */
71
+ export const dataDir = () => resolve(fileURLToPath(new URL('.', import.meta.url)), '../../data');
72
+ /**
73
+ * Собирает пакет знаний из чекаутов. Используется и сборкой снапшота,
74
+ * и live-режимом, поэтому результат в обоих случаях идентичен по структуре.
75
+ */
76
+ export const buildPack = (params) => {
77
+ const docs = [];
78
+ const chunks = [];
79
+ const own = collectSource(ownKnowledgeDir(), {
80
+ repo: 'mcp',
81
+ subPath: '.',
82
+ docPrefix: 'mcp',
83
+ });
84
+ docs.push(...own.docs);
85
+ chunks.push(...own.chunks);
86
+ const add = (root, specs) => {
87
+ if (!root) {
88
+ return;
89
+ }
90
+ for (const spec of specs) {
91
+ const result = collectSource(root, spec);
92
+ docs.push(...result.docs);
93
+ chunks.push(...result.chunks);
94
+ }
95
+ };
96
+ add(params.backPath, BACK_SOURCES);
97
+ add(params.frontPath, FRONT_SOURCES);
98
+ return { version: 1, builtAt: params.builtAt, source: params.source, docs, chunks };
99
+ };
100
+ /** Читает собранный снапшот из data/knowledge.json. */
101
+ export const loadSnapshot = () => {
102
+ const file = resolve(dataDir(), 'knowledge.json');
103
+ const parsed = JSON.parse(readFileSync(file, 'utf8'));
104
+ if (parsed.version !== 1) {
105
+ throw new Error(`Unsupported knowledge pack version ${String(parsed.version)}`);
106
+ }
107
+ return parsed;
108
+ };
109
+ /**
110
+ * Выбирает источник знаний: живой чекаут, если он указан, иначе снапшот пакета.
111
+ * Live-режим нужен, чтобы правка документации в dnk-back действовала сразу,
112
+ * без переиздания npm-пакета.
113
+ */
114
+ export const resolveKnowledge = (params) => {
115
+ if (params.backPath) {
116
+ return buildPack({
117
+ backPath: params.backPath,
118
+ frontPath: params.frontPath,
119
+ source: 'live',
120
+ builtAt: new Date().toISOString(),
121
+ });
122
+ }
123
+ return loadSnapshot();
124
+ };
125
+ //# sourceMappingURL=loader.js.map