@oneentry/mcp-platform-server 0.1.1 → 0.1.3

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 (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -61
  3. package/dist/api/audit.d.ts +0 -11
  4. package/dist/api/audit.js +0 -10
  5. package/dist/api/auth.d.ts +0 -18
  6. package/dist/api/auth.js +0 -20
  7. package/dist/api/build-catalog.d.ts +0 -14
  8. package/dist/api/build-catalog.js +7 -77
  9. package/dist/api/catalog.d.ts +0 -26
  10. package/dist/api/catalog.js +3 -30
  11. package/dist/api/client.d.ts +0 -24
  12. package/dist/api/client.js +6 -28
  13. package/dist/api/normalize-schema.d.ts +0 -11
  14. package/dist/api/normalize-schema.js +0 -18
  15. package/dist/api/policy.d.ts +0 -23
  16. package/dist/api/policy.js +0 -0
  17. package/dist/api/shape.d.ts +0 -13
  18. package/dist/api/shape.js +0 -21
  19. package/dist/api/swagger-source.d.ts +1 -12
  20. package/dist/api/swagger-source.js +2 -20
  21. package/dist/api/types.d.ts +0 -34
  22. package/dist/api/types.js +0 -1
  23. package/dist/bin/cli.d.ts +0 -1
  24. package/dist/bin/cli.js +1 -5
  25. package/dist/config/config.d.ts +0 -54
  26. package/dist/config/config.js +0 -60
  27. package/dist/index.d.ts +0 -5
  28. package/dist/index.js +0 -5
  29. package/dist/knowledge/chunk.d.ts +0 -15
  30. package/dist/knowledge/chunk.js +0 -16
  31. package/dist/knowledge/github.d.ts +0 -25
  32. package/dist/knowledge/github.js +0 -40
  33. package/dist/knowledge/loader.d.ts +0 -28
  34. package/dist/knowledge/loader.js +0 -26
  35. package/dist/knowledge/search.d.ts +0 -22
  36. package/dist/knowledge/search.js +0 -34
  37. package/dist/knowledge/tar.d.ts +0 -15
  38. package/dist/knowledge/tar.js +0 -33
  39. package/dist/knowledge/types.d.ts +0 -35
  40. package/dist/knowledge/types.js +0 -1
  41. package/dist/server.d.ts +0 -12
  42. package/dist/server.js +10 -14
  43. package/dist/session.d.ts +0 -23
  44. package/dist/session.js +0 -18
  45. package/dist/tools/api-call.d.ts +0 -2
  46. package/dist/tools/api-call.js +0 -23
  47. package/dist/tools/api-discovery.d.ts +0 -2
  48. package/dist/tools/api-discovery.js +2 -5
  49. package/dist/tools/docs.d.ts +0 -2
  50. package/dist/tools/docs.js +1 -5
  51. package/dist/tools/guide.d.ts +0 -7
  52. package/dist/tools/guide.js +2 -9
  53. package/dist/tools/result.d.ts +0 -8
  54. package/dist/tools/result.js +0 -7
  55. package/dist/tools/whoami.d.ts +0 -2
  56. package/dist/tools/whoami.js +1 -3
  57. package/dist/transports/http.d.ts +0 -6
  58. package/dist/transports/http.js +0 -26
  59. package/dist/transports/stdio.d.ts +0 -6
  60. package/dist/transports/stdio.js +0 -6
  61. package/knowledge/operating-rules.md +70 -125
  62. package/package.json +18 -5
  63. package/dist/api/audit.d.ts.map +0 -1
  64. package/dist/api/audit.js.map +0 -1
  65. package/dist/api/auth.d.ts.map +0 -1
  66. package/dist/api/auth.js.map +0 -1
  67. package/dist/api/build-catalog.d.ts.map +0 -1
  68. package/dist/api/build-catalog.js.map +0 -1
  69. package/dist/api/catalog.d.ts.map +0 -1
  70. package/dist/api/catalog.js.map +0 -1
  71. package/dist/api/client.d.ts.map +0 -1
  72. package/dist/api/client.js.map +0 -1
  73. package/dist/api/normalize-schema.d.ts.map +0 -1
  74. package/dist/api/normalize-schema.js.map +0 -1
  75. package/dist/api/policy.d.ts.map +0 -1
  76. package/dist/api/policy.js.map +0 -1
  77. package/dist/api/shape.d.ts.map +0 -1
  78. package/dist/api/shape.js.map +0 -1
  79. package/dist/api/swagger-source.d.ts.map +0 -1
  80. package/dist/api/swagger-source.js.map +0 -1
  81. package/dist/api/types.d.ts.map +0 -1
  82. package/dist/api/types.js.map +0 -1
  83. package/dist/bin/cli.d.ts.map +0 -1
  84. package/dist/bin/cli.js.map +0 -1
  85. package/dist/config/config.d.ts.map +0 -1
  86. package/dist/config/config.js.map +0 -1
  87. package/dist/index.d.ts.map +0 -1
  88. package/dist/index.js.map +0 -1
  89. package/dist/knowledge/chunk.d.ts.map +0 -1
  90. package/dist/knowledge/chunk.js.map +0 -1
  91. package/dist/knowledge/github.d.ts.map +0 -1
  92. package/dist/knowledge/github.js.map +0 -1
  93. package/dist/knowledge/loader.d.ts.map +0 -1
  94. package/dist/knowledge/loader.js.map +0 -1
  95. package/dist/knowledge/search.d.ts.map +0 -1
  96. package/dist/knowledge/search.js.map +0 -1
  97. package/dist/knowledge/tar.d.ts.map +0 -1
  98. package/dist/knowledge/tar.js.map +0 -1
  99. package/dist/knowledge/types.d.ts.map +0 -1
  100. package/dist/knowledge/types.js.map +0 -1
  101. package/dist/server.d.ts.map +0 -1
  102. package/dist/server.js.map +0 -1
  103. package/dist/session.d.ts.map +0 -1
  104. package/dist/session.js.map +0 -1
  105. package/dist/tools/api-call.d.ts.map +0 -1
  106. package/dist/tools/api-call.js.map +0 -1
  107. package/dist/tools/api-discovery.d.ts.map +0 -1
  108. package/dist/tools/api-discovery.js.map +0 -1
  109. package/dist/tools/docs.d.ts.map +0 -1
  110. package/dist/tools/docs.js.map +0 -1
  111. package/dist/tools/guide.d.ts.map +0 -1
  112. package/dist/tools/guide.js.map +0 -1
  113. package/dist/tools/result.d.ts.map +0 -1
  114. package/dist/tools/result.js.map +0 -1
  115. package/dist/tools/whoami.d.ts.map +0 -1
  116. package/dist/tools/whoami.js.map +0 -1
  117. package/dist/transports/http.d.ts.map +0 -1
  118. package/dist/transports/http.js.map +0 -1
  119. package/dist/transports/stdio.d.ts.map +0 -1
  120. package/dist/transports/stdio.js.map +0 -1
@@ -1,10 +1,8 @@
1
1
  import { type KnowledgeFile } from './github.js';
2
2
  import type { KnowledgeOrigin, KnowledgePack } from './types.js';
3
- /** Настройки источника знаний, как их отдаёт конфигурация. */
4
3
  export interface KnowledgeConfig {
5
4
  repo: string;
6
5
  ref: string;
7
- /** Локальный клон репозитория знаний: приоритетнее сети. */
8
6
  path?: string;
9
7
  cacheDir: string;
10
8
  refreshTtlMs: number;
@@ -12,22 +10,9 @@ export interface KnowledgeConfig {
12
10
  token?: string;
13
11
  timeoutMs: number;
14
12
  }
15
- /** Каталог с вшитым минимумом знаний (`operating-rules.md`). */
16
13
  export declare const seedDir: () => string;
17
- /** Каталог со сгенерированными данными пакета (`permissions.json`). */
18
14
  export declare const dataDir: () => string;
19
- /**
20
- * docId из пути внутри `knowledge/`.
21
- * `<имя>/index.md` даёт docId `<имя>`: это позволяет разрезать большой документ
22
- * на каталог из мелких файлов, не меняя идентификатор, на который уже ссылаются
23
- * `docLinks` каталога операций и золотые запросы тестов.
24
- */
25
15
  export declare const docIdFromPath: (path: string) => string;
26
- /**
27
- * Собирает пакет знаний из плоского списка файлов.
28
- * Один вход для всех трёх источников — сети, кэша и локального клона, — поэтому
29
- * поведение поиска не может разойтись между ними.
30
- */
31
16
  export declare const packFromFiles: (params: {
32
17
  files: readonly KnowledgeFile[];
33
18
  source: KnowledgeOrigin;
@@ -37,18 +22,5 @@ export declare const packFromFiles: (params: {
37
22
  sha?: string;
38
23
  warning?: string;
39
24
  }) => KnowledgePack;
40
- /**
41
- * Вшитый минимум: собственные правила эксплуатации пакета.
42
- * Существует только затем, чтобы сервер без сети всё равно мог ответить на вопрос
43
- * «как безопасно писать в эту CMS». Всё остальное живёт в репозитории знаний.
44
- */
45
25
  export declare const seedPack: (warning?: string) => KnowledgePack;
46
- /**
47
- * Выбирает источник знаний: локальный клон -> GitHub (через кэш) -> вшитый минимум.
48
- * Недоступный GitHub не мешает серверу подняться: пакет беднеет до вшитого минимума,
49
- * а причина уезжает в `warning`, потому что сеть — не ошибка конфигурации.
50
- * Единственное исключение бросается на нечитаемый локальный путь: его оператор указал
51
- * явно, и молчаливое падение до вшитых правил выглядело бы как пустой корпус.
52
- */
53
26
  export declare const resolveKnowledge: (config: KnowledgeConfig) => Promise<KnowledgePack>;
54
- //# sourceMappingURL=loader.d.ts.map
@@ -4,22 +4,9 @@ import { fileURLToPath } from 'node:url';
4
4
  import { chunkDocument } from './chunk.js';
5
5
  import { fetchKnowledgeTree, readLocalTree } from './github.js';
6
6
  const messageOf = (error) => error instanceof Error ? error.message : String(error);
7
- /** Каталог с вшитым минимумом знаний (`operating-rules.md`). */
8
7
  export const seedDir = () => resolve(fileURLToPath(new URL('.', import.meta.url)), '../../knowledge');
9
- /** Каталог со сгенерированными данными пакета (`permissions.json`). */
10
8
  export const dataDir = () => resolve(fileURLToPath(new URL('.', import.meta.url)), '../../data');
11
- /**
12
- * docId из пути внутри `knowledge/`.
13
- * `<имя>/index.md` даёт docId `<имя>`: это позволяет разрезать большой документ
14
- * на каталог из мелких файлов, не меняя идентификатор, на который уже ссылаются
15
- * `docLinks` каталога операций и золотые запросы тестов.
16
- */
17
9
  export const docIdFromPath = (path) => path.replace(/\.md$/, '').replace(/\/index$/, '');
18
- /**
19
- * Собирает пакет знаний из плоского списка файлов.
20
- * Один вход для всех трёх источников — сети, кэша и локального клона, — поэтому
21
- * поведение поиска не может разойтись между ними.
22
- */
23
10
  export const packFromFiles = (params) => {
24
11
  const docs = [];
25
12
  const chunks = [];
@@ -46,11 +33,6 @@ export const packFromFiles = (params) => {
46
33
  chunks,
47
34
  };
48
35
  };
49
- /**
50
- * Вшитый минимум: собственные правила эксплуатации пакета.
51
- * Существует только затем, чтобы сервер без сети всё равно мог ответить на вопрос
52
- * «как безопасно писать в эту CMS». Всё остальное живёт в репозитории знаний.
53
- */
54
36
  export const seedPack = (warning) => packFromFiles({
55
37
  files: [
56
38
  {
@@ -62,13 +44,6 @@ export const seedPack = (warning) => packFromFiles({
62
44
  builtAt: new Date().toISOString(),
63
45
  ...(warning ? { warning } : {}),
64
46
  });
65
- /**
66
- * Выбирает источник знаний: локальный клон -> GitHub (через кэш) -> вшитый минимум.
67
- * Недоступный GitHub не мешает серверу подняться: пакет беднеет до вшитого минимума,
68
- * а причина уезжает в `warning`, потому что сеть — не ошибка конфигурации.
69
- * Единственное исключение бросается на нечитаемый локальный путь: его оператор указал
70
- * явно, и молчаливое падение до вшитых правил выглядело бы как пустой корпус.
71
- */
72
47
  export const resolveKnowledge = async (config) => {
73
48
  const builtAt = new Date().toISOString();
74
49
  if (config.path) {
@@ -109,4 +84,3 @@ export const resolveKnowledge = async (config) => {
109
84
  'Only the bundled operating rules are available — module reference docs will not be found.');
110
85
  }
111
86
  };
112
- //# sourceMappingURL=loader.js.map
@@ -1,5 +1,4 @@
1
1
  import type { KnowledgeChunk, KnowledgeDoc, KnowledgePack } from './types.js';
2
- /** Найденный раздел с оценкой и вырезкой вокруг совпадения. */
3
2
  export interface KnowledgeHit {
4
3
  id: string;
5
4
  docId: string;
@@ -10,36 +9,15 @@ export interface KnowledgeHit {
10
9
  score: number;
11
10
  snippet: string;
12
11
  }
13
- /**
14
- * Выбрасывает из запроса слова короче трёх букв.
15
- * Заголовок весит вчетверо больше текста, поэтому раздел «Не входит в scope»
16
- * выигрывал у описания модуля на вопросе «почему атрибут не попал в индекс»:
17
- * два служебных слова совпадали с заголовком, а значащие — с телом. Предлоги и
18
- * частицы (`не`, `в`, `на`, `of`, `to`) не несут смысла ни в русском запросе,
19
- * ни в английском, и участвовать в ранжировании не должны.
20
- * Если после отбора не осталось ничего, запрос возвращается как есть —
21
- * поиск по одному короткому слову лучше поиска ни по чему.
22
- */
23
12
  export declare const meaningfulQuery: (query: string) => string;
24
- /**
25
- * Поисковый индекс по разделам документации.
26
- * Хранит только идентификаторы в индексе, а тексты — в отдельной карте:
27
- * так `cms_docs_search` отдаёт вырезки, не поднимая в память дубли корпуса.
28
- */
29
13
  export declare class KnowledgeIndex {
30
14
  private readonly mini;
31
15
  private readonly byId;
32
16
  private readonly byDocId;
33
17
  readonly pack: KnowledgePack;
34
18
  constructor(pack: KnowledgePack);
35
- /** Разделы документа в порядке следования — для листания в cms_docs_read. */
36
19
  doc(docId: string): KnowledgeDoc | undefined;
37
20
  chunk(id: string): KnowledgeChunk | undefined;
38
21
  docs(): readonly KnowledgeDoc[];
39
- /**
40
- * Ищет разделы по запросу. Оценка minisearch домножается на веса источника и вида
41
- * документа, поэтому правила эксплуатации всегда всплывают выше истории фиксов.
42
- */
43
22
  search(query: string, limit?: number): KnowledgeHit[];
44
23
  }
45
- //# sourceMappingURL=search.d.ts.map
@@ -1,9 +1,4 @@
1
1
  import MiniSearch from 'minisearch';
2
- /**
3
- * Веса источников. `mcp` — собственные правила эксплуатации, они всегда должны
4
- * побеждать первичную документацию; `fixes` — история багов, полезна, но шумна,
5
- * поэтому опускается вниз, чтобы не вытеснять описание модуля.
6
- */
7
2
  const REPO_WEIGHT = { mcp: 1.6, back: 1, front: 0.9 };
8
3
  const KIND_WEIGHT = {
9
4
  docs: 1.15,
@@ -12,13 +7,6 @@ const KIND_WEIGHT = {
12
7
  fixes: 0.6,
13
8
  specs: 0.6,
14
9
  };
15
- /**
16
- * Вид документа. Обычно это второй сегмент docId (`back/docs/…` -> `docs`),
17
- * но каталог `specs` третьим сегментом разбирается отдельно: это датированные
18
- * описания задач и merge request'ов. По форме документация, по сути — та же история изменений,
19
- * что и `fixes`: длинная прозаическая, богатая случайными совпадениями и
20
- * вытесняющая описание модуля. Вес у них поэтому такой же.
21
- */
22
10
  const kindOf = (docId) => {
23
11
  const parts = docId.split('/');
24
12
  if (parts[2] === 'specs') {
@@ -27,21 +15,10 @@ const kindOf = (docId) => {
27
15
  return parts[1] ?? 'docs';
28
16
  };
29
17
  const SNIPPET_RADIUS = 180;
30
- /**
31
- * Выбрасывает из запроса слова короче трёх букв.
32
- * Заголовок весит вчетверо больше текста, поэтому раздел «Не входит в scope»
33
- * выигрывал у описания модуля на вопросе «почему атрибут не попал в индекс»:
34
- * два служебных слова совпадали с заголовком, а значащие — с телом. Предлоги и
35
- * частицы (`не`, `в`, `на`, `of`, `to`) не несут смысла ни в русском запросе,
36
- * ни в английском, и участвовать в ранжировании не должны.
37
- * Если после отбора не осталось ничего, запрос возвращается как есть —
38
- * поиск по одному короткому слову лучше поиска ни по чему.
39
- */
40
18
  export const meaningfulQuery = (query) => {
41
19
  const kept = query.split(/\s+/).filter((word) => word.replace(/[^\p{L}\p{N}]/gu, '').length > 2);
42
20
  return kept.length > 0 ? kept.join(' ') : query;
43
21
  };
44
- /** Вырезка вокруг первого совпавшего терма; при отсутствии — начало раздела. */
45
22
  const makeSnippet = (text, terms) => {
46
23
  const flat = text.replace(/\s+/g, ' ').trim();
47
24
  const lower = flat.toLowerCase();
@@ -59,11 +36,6 @@ const makeSnippet = (text, terms) => {
59
36
  const end = Math.min(flat.length, at + SNIPPET_RADIUS);
60
37
  return `${start > 0 ? '…' : ''}${flat.slice(start, end)}${end < flat.length ? '…' : ''}`;
61
38
  };
62
- /**
63
- * Поисковый индекс по разделам документации.
64
- * Хранит только идентификаторы в индексе, а тексты — в отдельной карте:
65
- * так `cms_docs_search` отдаёт вырезки, не поднимая в память дубли корпуса.
66
- */
67
39
  export class KnowledgeIndex {
68
40
  mini;
69
41
  byId;
@@ -86,7 +58,6 @@ export class KnowledgeIndex {
86
58
  });
87
59
  this.mini.addAll(pack.chunks);
88
60
  }
89
- /** Разделы документа в порядке следования — для листания в cms_docs_read. */
90
61
  doc(docId) {
91
62
  return this.byDocId.get(docId);
92
63
  }
@@ -96,10 +67,6 @@ export class KnowledgeIndex {
96
67
  docs() {
97
68
  return this.pack.docs;
98
69
  }
99
- /**
100
- * Ищет разделы по запросу. Оценка minisearch домножается на веса источника и вида
101
- * документа, поэтому правила эксплуатации всегда всплывают выше истории фиксов.
102
- */
103
70
  search(query, limit = 8) {
104
71
  const terms = query.split(/\s+/).filter((t) => t.length > 1);
105
72
  const raw = this.mini.search(meaningfulQuery(query));
@@ -125,4 +92,3 @@ export class KnowledgeIndex {
125
92
  return hits.slice(0, limit);
126
93
  }
127
94
  }
128
- //# sourceMappingURL=search.js.map
@@ -1,22 +1,7 @@
1
- /** Один распакованный файл архива. */
2
1
  export interface TarEntry {
3
- /** Путь внутри архива, уже без корневого каталога. */
4
2
  path: string;
5
3
  content: string;
6
4
  }
7
- /**
8
- * Разбирает несжатый tar и возвращает только обычные файлы.
9
- * Своя реализация вместо зависимости: пакету нужен один сценарий чтения,
10
- * а каждая зависимость опубликованного npm-пакета — это ещё одна поверхность атаки.
11
- * Поддержаны оба способа записать длинный путь: расширенный заголовок pax
12
- * (`git archive`, а значит и GitHub) и GNU longname.
13
- */
14
5
  export declare const readTar: (buffer: Buffer) => TarEntry[];
15
- /**
16
- * Убирает общий первый сегмент пути. GitHub кладёт весь архив в каталог
17
- * `<repo>-<sha>/`, и без этого docId у каждого документа начинался бы с хэша коммита.
18
- */
19
6
  export declare const stripRoot: (entries: readonly TarEntry[]) => TarEntry[];
20
- /** Распаковывает `.tar.gz` целиком: gzip снимается встроенным zlib. */
21
7
  export declare const readTarGz: (buffer: Buffer) => TarEntry[];
22
- //# sourceMappingURL=tar.d.ts.map
@@ -1,26 +1,16 @@
1
1
  import { gunzipSync } from 'node:zlib';
2
- /** Размер блока формата tar — и заголовок, и выравнивание данных кратны ему. */
3
2
  const BLOCK = 512;
4
- /** Смещения полей заголовка ustar. */
5
3
  const FIELD = {
6
4
  name: [0, 100],
7
5
  size: [124, 12],
8
6
  typeflag: [156, 1],
9
7
  prefix: [345, 155],
10
8
  };
11
- /**
12
- * Читает строковое поле заголовка: оно дополнено нулями до фиксированной длины.
13
- */
14
9
  const readString = (block, [offset, length]) => {
15
10
  const raw = block.subarray(offset, offset + length);
16
11
  const end = raw.indexOf(0);
17
12
  return raw.subarray(0, end === -1 ? raw.length : end).toString('utf8').trim();
18
13
  };
19
- /**
20
- * Читает размер файла. В tar он записан восьмеричной строкой; GNU-расширение
21
- * с базой 256 (старший бит первого байта) в архивах GitHub не встречается,
22
- * но молча вернуть из него мусор нельзя — такой архив лучше отвергнуть.
23
- */
24
14
  const readSize = (block) => {
25
15
  const [offset, length] = FIELD.size;
26
16
  const first = block[offset] ?? 0;
@@ -34,23 +24,16 @@ const readSize = (block) => {
34
24
  }
35
25
  return parsed;
36
26
  };
37
- /**
38
- * Достаёт `path=` из расширенного заголовка pax.
39
- * Записи имеют вид `<длина> <ключ>=<значение>\n`; нас интересует только путь,
40
- * которым pax подменяет имя следующей записи, когда оно не влезает в ustar.
41
- */
42
27
  const readPaxPath = (data) => {
43
28
  const text = data.toString('utf8');
44
29
  const match = /(?:^|\n)\d+ path=([^\n]*)\n/.exec(text);
45
30
  return match?.[1];
46
31
  };
47
- /** Полное имя записи: ustar разбивает длинный путь на `prefix` и `name`. */
48
32
  const fullName = (block) => {
49
33
  const name = readString(block, FIELD.name);
50
34
  const prefix = readString(block, FIELD.prefix);
51
35
  return prefix === '' ? name : `${prefix}/${name}`;
52
36
  };
53
- /** Блок из одних нулей — маркер конца архива. */
54
37
  const isZeroBlock = (block) => {
55
38
  for (const byte of block) {
56
39
  if (byte !== 0) {
@@ -59,17 +42,9 @@ const isZeroBlock = (block) => {
59
42
  }
60
43
  return true;
61
44
  };
62
- /**
63
- * Разбирает несжатый tar и возвращает только обычные файлы.
64
- * Своя реализация вместо зависимости: пакету нужен один сценарий чтения,
65
- * а каждая зависимость опубликованного npm-пакета — это ещё одна поверхность атаки.
66
- * Поддержаны оба способа записать длинный путь: расширенный заголовок pax
67
- * (`git archive`, а значит и GitHub) и GNU longname.
68
- */
69
45
  export const readTar = (buffer) => {
70
46
  const entries = [];
71
47
  let offset = 0;
72
- /** Имя, навязанное предыдущим заголовком pax или GNU longname. */
73
48
  let pendingName;
74
49
  while (offset + BLOCK <= buffer.length) {
75
50
  const header = buffer.subarray(offset, offset + BLOCK);
@@ -84,7 +59,6 @@ export const readTar = (buffer) => {
84
59
  throw new Error('tar: truncated archive');
85
60
  }
86
61
  const data = buffer.subarray(dataStart, dataEnd);
87
- /** Данные записи выровнены по границе блока. */
88
62
  offset = dataStart + Math.ceil(size / BLOCK) * BLOCK;
89
63
  if (typeflag === 'x' || typeflag === 'X') {
90
64
  pendingName = readPaxPath(data) ?? pendingName;
@@ -94,7 +68,6 @@ export const readTar = (buffer) => {
94
68
  pendingName = data.toString('utf8').replace(/\0+$/, '');
95
69
  continue;
96
70
  }
97
- /** Глобальные заголовки pax и всё, что не является обычным файлом, нас не интересуют. */
98
71
  if (typeflag === 'g') {
99
72
  continue;
100
73
  }
@@ -107,14 +80,8 @@ export const readTar = (buffer) => {
107
80
  }
108
81
  return entries;
109
82
  };
110
- /**
111
- * Убирает общий первый сегмент пути. GitHub кладёт весь архив в каталог
112
- * `<repo>-<sha>/`, и без этого docId у каждого документа начинался бы с хэша коммита.
113
- */
114
83
  export const stripRoot = (entries) => entries.map((entry) => {
115
84
  const cut = entry.path.indexOf('/');
116
85
  return cut === -1 ? entry : { path: entry.path.slice(cut + 1), content: entry.content };
117
86
  });
118
- /** Распаковывает `.tar.gz` целиком: gzip снимается встроенным zlib. */
119
87
  export const readTarGz = (buffer) => stripRoot(readTar(gunzipSync(buffer)));
120
- //# sourceMappingURL=tar.js.map
@@ -1,31 +1,13 @@
1
- /**
2
- * Один раздел документации — единица поиска и чтения.
3
- * Резать документы на разделы обязательно: даже при ограничении на размер файла
4
- * модели нужен ровно тот раздел, который отвечает на её вопрос.
5
- */
6
1
  export interface KnowledgeChunk {
7
- /** Стабильный идентификатор `<docId>#<anchor>`. */
8
2
  id: string;
9
- /** Идентификатор документа, например `back/docs/menus-module`. */
10
3
  docId: string;
11
- /**
12
- * Первый сегмент docId: `mcp`, `back`, `front`. Строка, а не перечисление —
13
- * репозиторий знаний живёт отдельно от этого пакета и может завести новый раздел,
14
- * не требуя релиза сервера. Неизвестный источник получает вес 1.
15
- */
16
4
  repo: string;
17
- /** Путь файла в репозитории знаний, например `knowledge/back/docs/menus-module.md`. */
18
5
  path: string;
19
- /** Слаг заголовка раздела; пустая строка — преамбула документа. */
20
6
  anchor: string;
21
- /** Текст заголовка раздела. */
22
7
  title: string;
23
- /** Заголовок документа (первый `#`), нужен для ранжирования и вывода. */
24
8
  docTitle: string;
25
- /** Тело раздела без заголовка. */
26
9
  text: string;
27
10
  }
28
- /** Документ целиком: список его разделов, чтобы агент мог листать соседние. */
29
11
  export interface KnowledgeDoc {
30
12
  docId: string;
31
13
  repo: string;
@@ -37,32 +19,15 @@ export interface KnowledgeDoc {
37
19
  bytes: number;
38
20
  }>;
39
21
  }
40
- /**
41
- * Откуда взялся пакет знаний.
42
- * `github` — только что скачан, `cache` — распакованная копия на диске,
43
- * `local` — клон репозитория знаний рядом, `seed` — только вшитые правила эксплуатации.
44
- */
45
22
  export type KnowledgeOrigin = 'github' | 'cache' | 'local' | 'seed';
46
- /** Собранный пакет знаний — то, с чем работает KnowledgeIndex. */
47
23
  export interface KnowledgePack {
48
- /** Версия формата — чтобы рантайм не пытался читать несовместимый пакет. */
49
24
  version: 1;
50
- /** Когда собран (ISO). Показывается в cms_whoami. */
51
25
  builtAt: string;
52
26
  source: KnowledgeOrigin;
53
- /** Репозиторий знаний `owner/name`, если пакет пришёл оттуда. */
54
27
  repo?: string;
55
- /** Ветка или тег, с которого читали. */
56
28
  ref?: string;
57
- /** Коммит, которым адресуется содержимое. */
58
29
  sha?: string;
59
- /**
60
- * Почему пакет неполон. Пустое значение — норма; заполненное обязано попадать
61
- * и в `cms_whoami`, и в `cms_guide`: деградировавший пакет знаний агент должен
62
- * видеть, а не обнаруживать по отсутствию нужного документа.
63
- */
64
30
  warning?: string;
65
31
  docs: KnowledgeDoc[];
66
32
  chunks: KnowledgeChunk[];
67
33
  }
68
- //# sourceMappingURL=types.d.ts.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=types.js.map
package/dist/server.d.ts CHANGED
@@ -1,17 +1,5 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { Config } from './config/config.js';
3
3
  import { Session, type SharedDeps } from './session.js';
4
- /**
5
- * Собирает разделяемые зависимости: каталог операций, индекс знаний, журнал.
6
- * Вынесено отдельно, чтобы remote-режим строил их один раз на процесс,
7
- * а не на каждую сессию. Асинхронно, потому что знания приезжают из репозитория
8
- * GitHub, а каталог — со swagger подключённого стенда.
9
- */
10
4
  export declare const createSharedDeps: (config: Config) => Promise<SharedDeps>;
11
- /**
12
- * Создаёт MCP-сервер с полным набором инструментов.
13
- * Сессия передаётся геттером: в stdio-режиме она одна на процесс,
14
- * в HTTP-режиме — своя на каждое подключение, и код инструментов от этого не зависит.
15
- */
16
5
  export declare const createServer: (deps: SharedDeps, getSession: () => Session) => McpServer;
17
- //# sourceMappingURL=server.d.ts.map
package/dist/server.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createRequire } from 'node:module';
1
2
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
3
  import { AuditLog } from './api/audit.js';
3
4
  import { OperationCatalog } from './api/catalog.js';
@@ -8,14 +9,15 @@ import { registerApiDiscovery } from './tools/api-discovery.js';
8
9
  import { registerDocs } from './tools/docs.js';
9
10
  import { registerGuide } from './tools/guide.js';
10
11
  import { registerWhoami } from './tools/whoami.js';
11
- /** Версия пакета, сообщаемая клиенту при handshake. */
12
- const SERVER_VERSION = '0.1.0';
13
- /**
14
- * Собирает разделяемые зависимости: каталог операций, индекс знаний, журнал.
15
- * Вынесено отдельно, чтобы remote-режим строил их один раз на процесс,
16
- * а не на каждую сессию. Асинхронно, потому что знания приезжают из репозитория
17
- * GitHub, а каталог — со swagger подключённого стенда.
18
- */
12
+ const SERVER_VERSION = (() => {
13
+ try {
14
+ const pkg = createRequire(import.meta.url)('../package.json');
15
+ return pkg.version ?? '0.0.0';
16
+ }
17
+ catch {
18
+ return '0.0.0';
19
+ }
20
+ })();
19
21
  export const createSharedDeps = async (config) => ({
20
22
  config,
21
23
  catalog: await OperationCatalog.resolve(config),
@@ -34,11 +36,6 @@ export const createSharedDeps = async (config) => ({
34
36
  mode: config.mode,
35
37
  }),
36
38
  });
37
- /**
38
- * Создаёт MCP-сервер с полным набором инструментов.
39
- * Сессия передаётся геттером: в stdio-режиме она одна на процесс,
40
- * в HTTP-режиме — своя на каждое подключение, и код инструментов от этого не зависит.
41
- */
42
39
  export const createServer = (deps, getSession) => {
43
40
  const server = new McpServer({ name: 'oneentry-mcp-platform', version: SERVER_VERSION }, {
44
41
  instructions: 'OneEntry CMS Admin API. Call cms_guide first, then cms_docs_read on "mcp/operating-rules" before any write. ' +
@@ -52,4 +49,3 @@ export const createServer = (deps, getSession) => {
52
49
  registerApiCall(server, getSession);
53
50
  return server;
54
51
  };
55
- //# sourceMappingURL=server.js.map
package/dist/session.d.ts CHANGED
@@ -6,21 +6,12 @@ import { ConfirmStore } from './api/policy.js';
6
6
  import type { Config } from './config/config.js';
7
7
  import { KnowledgeIndex } from './knowledge/search.js';
8
8
  import type { Operation } from './api/types.js';
9
- /**
10
- * Разделяемые между сессиями зависимости.
11
- * Каталог и индекс знаний строятся один раз на процесс — они неизменяемы,
12
- * и в remote-режиме держать их копию на сессию было бы чистой растратой.
13
- */
14
9
  export interface SharedDeps {
15
10
  config: Config;
16
11
  catalog: OperationCatalog;
17
12
  knowledge: KnowledgeIndex;
18
13
  audit: AuditLog;
19
14
  }
20
- /**
21
- * Состояние одной MCP-сессии: свои учётные данные, свои токены,
22
- * свои токены подтверждения. Именно эта изоляция делает remote-режим безопасным.
23
- */
24
15
  export declare class Session {
25
16
  readonly shared: SharedDeps;
26
17
  readonly confirms: ConfirmStore;
@@ -29,21 +20,7 @@ export declare class Session {
29
20
  private identityCache;
30
21
  constructor(shared: SharedDeps, credentials?: Credentials);
31
22
  get isConfigured(): boolean;
32
- /**
33
- * Access-токен сессии. Нужен единственному потребителю вне клиента —
34
- * дозагрузке каталога в remote-режиме, когда стенд отдаёт swagger
35
- * только авторизованным.
36
- */
37
23
  accessToken(): Promise<string>;
38
- /**
39
- * Кто мы. Кэшируется: набор прав нужен почти каждому изменяющему вызову,
40
- * а меняется он редко.
41
- */
42
24
  identity(): Promise<AdminIdentity | undefined>;
43
- /**
44
- * Пытается показать, что именно будет изменено: ищет GET по тому же пути
45
- * и читает объект. Без этого «подтверждение удаления» — подпись под пустым листом.
46
- */
47
25
  describeTarget(operation: Operation, args: CallArgs): Promise<unknown>;
48
26
  }
49
- //# sourceMappingURL=session.d.ts.map
package/dist/session.js CHANGED
@@ -1,10 +1,6 @@
1
1
  import { adminIdFromToken, credentialsFromConfig, TokenStore } from './api/auth.js';
2
2
  import { AdminApiClient, buildUrl } from './api/client.js';
3
3
  import { ConfirmStore } from './api/policy.js';
4
- /**
5
- * Состояние одной MCP-сессии: свои учётные данные, свои токены,
6
- * свои токены подтверждения. Именно эта изоляция делает remote-режим безопасным.
7
- */
8
4
  export class Session {
9
5
  shared;
10
6
  confirms = new ConfirmStore();
@@ -27,18 +23,9 @@ export class Session {
27
23
  get isConfigured() {
28
24
  return this.tokens.isConfigured;
29
25
  }
30
- /**
31
- * Access-токен сессии. Нужен единственному потребителю вне клиента —
32
- * дозагрузке каталога в remote-режиме, когда стенд отдаёт swagger
33
- * только авторизованным.
34
- */
35
26
  async accessToken() {
36
27
  return this.tokens.accessToken();
37
28
  }
38
- /**
39
- * Кто мы. Кэшируется: набор прав нужен почти каждому изменяющему вызову,
40
- * а меняется он редко.
41
- */
42
29
  async identity() {
43
30
  if (this.identityCache) {
44
31
  return this.identityCache;
@@ -57,10 +44,6 @@ export class Session {
57
44
  return undefined;
58
45
  }
59
46
  }
60
- /**
61
- * Пытается показать, что именно будет изменено: ищет GET по тому же пути
62
- * и читает объект. Без этого «подтверждение удаления» — подпись под пустым листом.
63
- */
64
47
  async describeTarget(operation, args) {
65
48
  const sibling = this.shared.catalog
66
49
  .operations()
@@ -80,4 +63,3 @@ export class Session {
80
63
  return result.ok ? result.body : undefined;
81
64
  }
82
65
  }
83
- //# sourceMappingURL=session.js.map
@@ -1,5 +1,3 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import type { Session } from '../session.js';
3
- /** Регистрирует `cms_api_call`. */
4
3
  export declare const registerApiCall: (server: McpServer, getSession: () => Session) => void;
5
- //# sourceMappingURL=api-call.d.ts.map