@naparnik/mcp 0.1.0 → 0.10.9
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/CHANGELOG.md +1344 -0
- package/LICENSE.md +8 -1
- package/README.md +279 -23
- package/THIRD-PARTY.md +59 -0
- package/dist/chunk-JBXYRTS4.js +21450 -0
- package/dist/cli.d.ts +25 -0
- package/dist/cli.js +449 -15
- package/dist/index.d.ts +1490 -16
- package/dist/index.js +1 -1
- package/package.json +15 -11
- package/dist/chunk-T6UWKM37.js +0 -4989
package/dist/cli.d.ts
CHANGED
|
@@ -1 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Режим установщика. Возвращает true, если аргументы разобраны и сервер
|
|
4
|
+
* поднимать не надо.
|
|
5
|
+
*
|
|
6
|
+
* ⚠ ЭКСПОРТИРУЕТСЯ РАДИ ОДНОГО СТОРОЖА, И СТОРОЖ ЭТОГО СТОИТ. Отказ на ключ в
|
|
7
|
+
* аргументе — единственное место, где утечка либо есть, либо её нет; проверять
|
|
8
|
+
* его по копии разбора в `installer-args.test.ts` бесполезно: сними здесь
|
|
9
|
+
* вызов `keyRefusal` — и копия останется зелёной, а ключ снова уедет в историю
|
|
10
|
+
* оболочки (проверено мутацией). Импорт модуля при этом ничего не поднимает:
|
|
11
|
+
* `main()` зовётся только при прямом запуске (`launchedDirectly`).
|
|
12
|
+
*/
|
|
13
|
+
declare function installer(args: string[]): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Поднять сервер MCP.
|
|
16
|
+
*
|
|
17
|
+
* ⚠ ЭТО ЭКСПОРТ, И ЭКСПОРТ ОБЯЗАТЕЛЬНЫЙ. Так пусковой файл из `.mcpb` зовёт
|
|
18
|
+
* ТЕЛО, скачанное с раздачи (`launcher.ts`): он импортирует этот модуль и
|
|
19
|
+
* вызывает `start`. Запускайся тело само при импорте, его собственный
|
|
20
|
+
* `catch → process.exit(1)` убил бы процесс мимо перехвата пускового файла, и
|
|
21
|
+
* обещанный откат на встроенную версию остался бы обещанием. Имя `start` —
|
|
22
|
+
* часть договора, за номером которого следит `LAUNCHER_PROTOCOL`.
|
|
23
|
+
*/
|
|
24
|
+
declare function start(): Promise<void>;
|
|
25
|
+
|
|
26
|
+
export { installer, start };
|
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,414 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { Engine, chooseBody, handOverToBody, VERSION, rollback, rollbackShell, remove, fromNpxCache, install, keyFromBlock, readConfig, ForeignBlockError, currentMachineFingerprint, McpServer, buildAll, buildResources, StdioServerTransport, fromHost, WHERE_TO_GET_KEY, installStep, NaparnikApiClient, timeToCheck2, manifestUrlFor, fetchManifest, markChecked2, decide, shellDir, timeToCheck, bundleUrlFor, fetchShellManifest, markChecked, decideShell, installedShell, NaparnikConfigError } from './chunk-JBXYRTS4.js';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { realpathSync, readFileSync } from 'fs';
|
|
3
5
|
|
|
4
|
-
// src/
|
|
6
|
+
// src/api-client.ts
|
|
7
|
+
function apiClientFor(state, machine = currentMachineFingerprint, engineVersion = () => null) {
|
|
8
|
+
return state.ok ? new NaparnikApiClient(state.config, machine, engineVersion) : notConfiguredClient(state.message);
|
|
9
|
+
}
|
|
10
|
+
function notConfiguredClient(reason) {
|
|
11
|
+
const stub = {
|
|
12
|
+
postMontage: async () => {
|
|
13
|
+
throw new NaparnikConfigError(
|
|
14
|
+
`${reason} \u0412\u043F\u0438\u0448\u0438\u0442\u0435 \u043A\u043B\u044E\u0447 \u0432 \u0441\u0435\u043A\u0446\u0438\u044E env \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 Claude \u2014 \u043F\u043E\u0441\u043B\u0435 \u044D\u0442\u043E\u0433\u043E \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B \u0437\u0430\u0440\u0430\u0431\u043E\u0442\u0430\u044E\u0442.`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
return stub;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/instructions.ts
|
|
22
|
+
var WHAT_IS_IT = `
|
|
23
|
+
\u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A \u043C\u043E\u043D\u0442\u0438\u0440\u0443\u0435\u0442 \u0432\u0438\u0434\u0435\u043E \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430. \u041D\u0438 \u0432\u0438\u0434\u0435\u043E, \u043D\u0438 \u0437\u0432\u0443\u043A, \u043D\u0438 \u0440\u0435\u0447\u044C
|
|
24
|
+
\u043D\u0438\u043A\u0443\u0434\u0430 \u043D\u0435 \u0443\u0435\u0437\u0436\u0430\u044E\u0442 \u2014 \u043D\u0430\u0432\u0435\u0440\u0445 \u0443\u0445\u043E\u0434\u0438\u0442 \u0442\u043E\u043B\u044C\u043A\u043E \u043A\u043B\u044E\u0447 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438.
|
|
25
|
+
`.trim();
|
|
26
|
+
var HOW_MONTAGE_WORKS = `
|
|
27
|
+
\u041A\u0410\u041A \u041C\u041E\u041D\u0422\u0418\u0420\u041E\u0412\u0410\u0422\u042C
|
|
28
|
+
|
|
29
|
+
1. setup \u043F\u0435\u0440\u0432\u044B\u043C, \u0434\u043E \u0432\u0438\u0434\u0435\u043E: \u0447\u0442\u043E \u0441\u0442\u043E\u0438\u0442, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442, \u0447\u0435\u0439 \u0441\u0442\u0438\u043B\u044C \u0438
|
|
30
|
+
\u043F\u043E\u0440\u044F\u0434\u043E\u043A. \u0418\u0437 \u043F\u0430\u043C\u044F\u0442\u0438 \u043D\u0435 \u0440\u0430\u0441\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439.
|
|
31
|
+
2. plan \u0431\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u2014 \u0447\u0442\u043E \u0443 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0441\u043D\u044F\u0442\u043E; plan \u0441 video \u2014 \u0427\u0415\u0420\u041D\u041E\u0412\u0418\u041A
|
|
32
|
+
\u0421\u041B\u041E\u0412\u0410\u041C\u0418, \u0434\u043E \u0441\u0431\u043E\u0440\u043A\u0438. \u041D\u0430\u0437\u043E\u0432\u0451\u0442 \u0444\u0430\u0439\u043B\u044B \u0441\u043A\u0438\u043B\u043B\u043E\u0432 \u2014 \u043F\u0440\u043E\u0447\u0442\u0438 \u0438\u0445 plan \u0441 read.
|
|
33
|
+
3. \u041F\u0435\u0440\u0435\u0441\u043A\u0430\u0436\u0438 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u041F\u041E\u0421\u0422\u0420\u041E\u0427\u041D\u041E \u0438 \u043E\u0431\u0441\u0443\u0434\u0438. \u041F\u0440\u0430\u0432\u043A\u0438 \u2014 plan_edit. \u041F\u043E\u043A\u0430 \u043D\u0435 \u0441\u043A\u0430\u0437\u0430\u043B
|
|
34
|
+
\xAB\u0434\u0430\xBB, \u043D\u0435 \u0441\u043E\u0431\u0438\u0440\u0430\u0439; \u0441\u043A\u0430\u0437\u0430\u043B \u2014 plan_edit \u0441 confirm.
|
|
35
|
+
\u0423\u0437\u043A\u0430\u044F \u043F\u0440\u043E\u0441\u044C\u0431\u0430 (\xAB\u043F\u0440\u043E\u0441\u0442\u043E \u0443\u0441\u043A\u043E\u0440\u044C\xBB) \u2014 \u043F\u043B\u0430\u043D \u043F\u0443\u0441\u0442\u043E\u0439, \u043B\u0438\u0448\u043D\u0435\u0433\u043E \u043D\u0435 \u0431\u0443\u0434\u0435\u0442.
|
|
36
|
+
4. \u0421\u0442\u0438\u043B\u044C \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0439 \u2014 \u0441\u043F\u0440\u043E\u0441\u0438 \u041E\u0414\u0418\u041D \u0440\u0430\u0437, \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0430\u043C\u0438 \u043F\u043E \u0440\u0430\u0437\u0434\u0435\u043B\u0430\u043C \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430
|
|
37
|
+
(\u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044B, \u0446\u0432\u0435\u0442, \u043F\u0430\u0443\u0437\u044B, \u0441\u0432\u043E\u0439 \u0441\u0442\u0438\u043B\u044C): AskUserQuestion, \u0431\u0435\u0437 \u043D\u0435\u0433\u043E \u2014 \u0441\u043B\u043E\u0432\u0430\u043C\u0438 \u0441
|
|
38
|
+
\u043D\u043E\u043C\u0435\u0440\u0430\u043C\u0438. \u0412\u044B\u0431\u0440\u0430\u043D\u043D\u043E\u0435 \u2014 choose_variant(questions=[\u0440\u0430\u0437\u0434\u0435\u043B\u044B]), \xAB\u0413\u043E\u0442\u043E\u0432\u043E\xBB
|
|
39
|
+
\u0437\u0430\u043F\u0438\u0448\u0435\u0442. \u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0432\u044B\u0431\u0440\u0430\u043B \u2014 variant_chosen \u0441 keep=true.
|
|
40
|
+
\u0421\u0442\u0438\u043B\u044C \u0443\u0436\u0435 \u0441\u0432\u043E\u0439 \u2014 \u043D\u0435 \u0441\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0439.
|
|
41
|
+
5. \u0414\u0430\u043B\u044C\u0448\u0435 render: \u0432\u0435\u0440\u043D\u0451\u0442 \u041D\u041E\u041C\u0415\u0420 \u0417\u0410\u0414\u0410\u0427\u0418, \u0436\u0434\u0451\u0442 \u0435\u0433\u043E wait. \u041F\u0435\u0440\u0435\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439 \u0448\u0430\u0433\u0438,
|
|
42
|
+
\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u0435 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044F \xAB\u0437\u0430\u0432\u0438\u0441\u043B\u043E\xBB; \u0447\u0435\u043A-\u043B\u0438\u0441\u0442 (TaskUpdate) \u2014 \u0432\u0435\u0434\u0438 \u0432 \u043D\u0451\u043C. \u0413\u043E\u0442\u043E\u0432\u043E \u2014
|
|
43
|
+
preview.
|
|
44
|
+
6. \xAB\u0425\u043E\u0447\u0443 \u0438\u043D\u0430\u0447\u0435\xBB: \u0441\u0442\u0438\u043B\u044C \u0438 \u0432\u0430\u0440\u0438\u0430\u043D\u0442 \u2014 choose_variant; \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0438\u0441\u0445\u043E\u0434\u043D\u0438\u043A\u043E\u0432,
|
|
45
|
+
split-screen, PiP, \u0442\u043E\u0447\u043D\u044B\u0435 in/out \u2014 \u0441\u043A\u0438\u043B\u043B composer (plan \u0441 read), project \u2014
|
|
46
|
+
plan_edit, \u0441\u0431\u043E\u0440\u043A\u0430 \u2014 render \u0441 reel; \u0441\u0432\u043E\u0451 \u2014 \u0441\u0432\u043E\u0439 \u0448\u0430\u0433 \u0432 mine/steps (\u043F\u0430\u043F\u043A\u0443
|
|
47
|
+
\u0432\u0435\u0440\u0441\u0438\u0438 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u0437\u0430\u043C\u0435\u043D\u044F\u0435\u0442), \u0434\u0430\u043B\u044C\u0448\u0435 plan_edit \u0441\u043E step; \u043A\u0430\u043A \u2014 \u0432 \u0441\u043A\u0438\u043B\u043B\u0435 builder.
|
|
48
|
+
\u0422\u043E\u043B\u044C\u043A\u043E \u043F\u0430\u0443\u0437\u044B \u2014 render \u0441 only_pauses.
|
|
49
|
+
7. \u0422\u044F\u0436\u0451\u043B\u043E\u0435 (\u0432\u044B\u0440\u0435\u0437 \u0433\u0435\u0440\u043E\u044F, \u0447\u0438\u0441\u0442\u043A\u0430 \u0433\u043E\u043B\u043E\u0441\u0430, \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438 \u2014 1,5 \u0413\u0411) \u2014 \u041F\u041E
|
|
50
|
+
\u041F\u0420\u041E\u0421\u042C\u0411\u0415: \u043D\u0430\u0437\u043E\u0432\u0438 \u0432\u0435\u0441, \u043F\u043E\u0441\u043B\u0435 \xAB\u0434\u0430\xBB setup \u0441 consent=true. \u0422\u0430\u043A \u0436\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F,
|
|
51
|
+
\u0432 \u0441\u0438\u043B\u0435 \u043F\u043E\u0441\u043B\u0435 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0430.
|
|
52
|
+
|
|
53
|
+
\u0421\u043A\u0438\u043B\u043B\u044B (\u0432\u0438\u0437\u0443\u0430\u043B, \u0434\u0432\u0438\u0436\u0435\u043D\u0438\u0435, \u0432\u043A\u0443\u0441) \u0447\u0438\u0442\u0430\u0435\u0442 plan \u0441 read \u0438 \u0411\u0415\u0417 \u0440\u043E\u043B\u0438\u043A\u0430: \u0433\u043E\u0434\u044F\u0442\u0441\u044F \u0438
|
|
54
|
+
\u0434\u043B\u044F \u043F\u0440\u0435\u0437\u0435\u043D\u0442\u0430\u0446\u0438\u0438. \u041F\u0435\u0440\u0435\u0447\u0435\u043D\u044C \u0432 setup.
|
|
55
|
+
|
|
56
|
+
\u041D\u0435 \u0432\u044B\u0434\u0443\u043C\u044B\u0432\u0430\u0439, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442 \u043C\u043E\u043D\u0442\u0430\u0436, \u0432\u0440\u0435\u043C\u044F \u043D\u0430\u0437\u044B\u0432\u0430\u0439 \u0442\u043E\u043B\u044C\u043A\u043E \u043E\u0442 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0430.
|
|
57
|
+
\u041A\u0430\u043A \u0443\u0441\u0442\u0440\u043E\u0435\u043D\u043E \u0432\u043D\u0443\u0442\u0440\u0438, \u043D\u0435 \u0440\u0430\u0441\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439. \u041B\u0435\u043D\u0442\u0430 \u0438 \u043F\u043E\u043C\u043E\u0449\u043D\u0438\u043A\u0438 \u0443\u0431\u0440\u0430\u043D\u044B.
|
|
58
|
+
`.trim();
|
|
59
|
+
function notConfiguredInstructions(problem, detail) {
|
|
60
|
+
const diagnosis = problem === "missing_key" ? "\u041A\u043B\u044E\u0447 \u0434\u043E\u0441\u0442\u0443\u043F\u0430 \u043D\u0435 \u0437\u0430\u0434\u0430\u043D." : `\u041A\u043B\u044E\u0447 \u0437\u0430\u0434\u0430\u043D, \u043D\u043E \u0432\u044B\u0433\u043B\u044F\u0434\u0438\u0442 \u043D\u0435\u043F\u0440\u0430\u0432\u0438\u043B\u044C\u043D\u043E. ${detail}`;
|
|
61
|
+
const hint = problem === "malformed_key" ? "\u0427\u0430\u0441\u0442\u044B\u0435 \u043F\u0440\u0438\u0447\u0438\u043D\u044B: \u0441\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u043D\u0430 \u0447\u0430\u0441\u0442\u044C \u043A\u043B\u044E\u0447\u0430, \u043F\u043E\u043F\u0430\u043B\u0438 \u043A\u0430\u0432\u044B\u0447\u043A\u0438 \u0438\u043B\u0438 \u043F\u0440\u043E\u0431\u0435\u043B\u044B." : "";
|
|
62
|
+
return `
|
|
63
|
+
${WHAT_IS_IT}
|
|
64
|
+
|
|
65
|
+
\u26A0\uFE0F \u0418\u041D\u0422\u0415\u0413\u0420\u0410\u0426\u0418\u042F \u041D\u0415 \u041D\u0410\u0421\u0422\u0420\u041E\u0415\u041D\u0410. ${diagnosis}
|
|
66
|
+
|
|
67
|
+
\u0411\u0435\u0437 \u043A\u043B\u044E\u0447\u0430 \u0440\u0430\u0431\u043E\u0442\u0430\u044E\u0442 setup (\u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430), plan \u0431\u0435\u0437 \u0432\u0438\u0434\u0435\u043E, wait, preview \u0438
|
|
68
|
+
choose_variant: \u043E\u043D\u0438 \u0441\u0447\u0438\u0442\u0430\u044E\u0442 \u043D\u0430 \u0435\u0433\u043E \u043C\u0430\u0448\u0438\u043D\u0435. render \u0438 plan \u0441 \u0432\u0438\u0434\u0435\u043E \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u0442\u044F\u0442\u0441\u044F \u2014
|
|
69
|
+
\u043F\u043E \u043A\u043B\u044E\u0447\u0443 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442\u0441\u044F \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0430, \u2014 \u0438 \u0434\u0432\u0438\u0436\u043E\u043A \u043D\u0435 \u0441\u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F: \u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u0437\u0430\u043A\u0440\u044B\u0442\u0430. \u041D\u0435
|
|
70
|
+
\u0433\u043E\u0432\u043E\u0440\u0438 \xAB\u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442\xBB: \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u043C\u043E\u0436\u043D\u043E, \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043D\u0443\u0436\u0435\u043D \u043A\u043B\u044E\u0447.
|
|
71
|
+
|
|
72
|
+
\u041A\u0410\u041A \u041F\u041E\u041B\u0423\u0427\u0418\u0422\u042C \u041A\u041B\u042E\u0427. ${WHERE_TO_GET_KEY} \u041E\u043F\u043B\u0430\u0442\u0438\u0432\u0448\u0435\u043C\u0443 \u0431\u043E\u0442 \u043F\u0440\u0438\u0448\u043B\u0451\u0442 \u0444\u0430\u0439\u043B \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F
|
|
73
|
+
\u0441 \u0443\u0436\u0435 \u0432\u0448\u0438\u0442\u044B\u043C \u043A\u043B\u044E\u0447\u043E\u043C \u2014 \u0435\u0433\u043E \u0434\u043E\u0441\u0442\u0430\u0442\u043E\u0447\u043D\u043E \u043E\u0442\u043A\u0440\u044B\u0442\u044C. \u0421\u0442\u0430\u0432\u0438\u043B\u0438 \u0447\u0435\u0440\u0435\u0437 npx \u0438\u043B\u0438 Codex \u2014
|
|
74
|
+
\u043F\u0440\u0438\u0448\u043B\u0451\u0442 \u0433\u043E\u0442\u043E\u0432\u0443\u044E \u0441\u0442\u0440\u043E\u043A\u0443.
|
|
75
|
+
|
|
76
|
+
\u041A\u043B\u044E\u0447 \u0432\u044B\u0433\u043B\u044F\u0434\u0438\u0442 \u0442\u0430\u043A: npk_ \u0438 \u0434\u0430\u043B\u044C\u0448\u0435 64 \u0441\u0438\u043C\u0432\u043E\u043B\u0430 \u0438\u0437 \u0446\u0438\u0444\u0440 \u0438 \u043B\u0430\u0442\u0438\u043D\u0441\u043A\u0438\u0445 \u0431\u0443\u043A\u0432 a-f.
|
|
77
|
+
\u0412\u0440\u0443\u0447\u043D\u0443\u044E \u0435\u0433\u043E \u0432\u043F\u0438\u0441\u044B\u0432\u0430\u044E\u0442 \u0432 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044E \u044D\u0442\u043E\u0433\u043E MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0432 \u0441\u0435\u043A\u0446\u0438\u044E env:
|
|
78
|
+
|
|
79
|
+
{ "mcpServers": { "naparnik": { "command": "npx", "args": ["-y", "@naparnik/mcp"],
|
|
80
|
+
"env": { "NAPARNIK_API_KEY": "npk_\u0441\u044E\u0434\u0430_\u043A\u043B\u044E\u0447" } } } }
|
|
81
|
+
|
|
82
|
+
\u041F\u043E\u0441\u043B\u0435 \u044D\u0442\u043E\u0433\u043E \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u041A\u043B\u043E\u0434\u0430 \u0438\u043B\u0438 Codex. ${hint}
|
|
83
|
+
|
|
84
|
+
\u26A0\uFE0F \u041A\u041B\u042E\u0427 \u0416\u0418\u0412\u0401\u0422 \u041D\u0410 \u041E\u0414\u041D\u041E\u041C \u041A\u041E\u041C\u041F\u042C\u042E\u0422\u0415\u0420\u0415: \u043D\u043E\u0432\u044B\u0439 \u0432\u044B\u043F\u0443\u0441\u043A \u043E\u0442\u0437\u044B\u0432\u0430\u0435\u0442 \u043F\u0440\u0435\u0436\u043D\u0438\u0439. \xAB\u041F\u0440\u0438\u0448\u043B\u0438\u0442\u0435 \u043C\u043E\u0439
|
|
85
|
+
\u043A\u043B\u044E\u0447\xBB \u043E\u0437\u043D\u0430\u0447\u0430\u0435\u0442 \xAB\u0432\u044B\u0434\u0430\u0439\u0442\u0435 \u043D\u043E\u0432\u044B\u0439, \u0441\u0442\u0430\u0440\u044B\u0439 \u043E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u0435\xBB \u2014 \u0441\u043A\u0430\u0437\u0430\u0442\u044C \u044D\u0442\u043E \u043D\u0430\u0434\u043E \u0414\u041E, \u0430 \u043D\u0435
|
|
86
|
+
\u043F\u043E\u0441\u043B\u0435. \u0421\u043C\u0435\u043D\u0438\u0442\u044C \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440 \u043C\u043E\u0436\u043D\u043E \u043A\u043D\u043E\u043F\u043A\u043E\u0439 \u0432 \u0431\u043E\u0442\u0435.
|
|
87
|
+
`.trim();
|
|
88
|
+
}
|
|
89
|
+
function configuredInstructions(baseUrl) {
|
|
90
|
+
return `
|
|
91
|
+
${WHAT_IS_IT}
|
|
92
|
+
|
|
93
|
+
\u041F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u043E \u043A: ${baseUrl}
|
|
94
|
+
|
|
95
|
+
${HOW_MONTAGE_WORKS}
|
|
96
|
+
|
|
97
|
+
\u041C\u043E\u043D\u0442\u0430\u0436 \u041D\u0415 \u0442\u0440\u0430\u0442\u0438\u0442 \u043D\u0438 \u0431\u0430\u043B\u0430\u043D\u0441, \u043D\u0438 \u0442\u043E\u043A\u0435\u043D\u044B.
|
|
98
|
+
`.trim();
|
|
99
|
+
}
|
|
100
|
+
function aboutNewPayload(ownDir, fresh, megabytes) {
|
|
101
|
+
return `
|
|
102
|
+
\u0412\u042B\u0428\u041B\u0410 \u041D\u041E\u0412\u0410\u042F \u0412\u0415\u0420\u0421\u0418\u042F \u0414\u0412\u0418\u0416\u041A\u0410 \u041C\u041E\u041D\u0422\u0410\u0416\u0410
|
|
103
|
+
|
|
104
|
+
${ownDir === null ? "\u0414\u0432\u0438\u0436\u043E\u043A \u0435\u0449\u0451 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D" : `\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430 ${ownDir}`}, \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 ${fresh} (${megabytes.toFixed(1)} \u041C\u0411).
|
|
105
|
+
\u0421\u0430\u043C\u0430 \u043E\u043D\u0430 \u043D\u0435 \u0441\u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F. \u041A\u043E\u0433\u0434\u0430 \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0432 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u0440\u0430\u0437 \u0437\u0430\u0433\u043E\u0432\u043E\u0440\u0438\u0442 \u043E \u043C\u043E\u043D\u0442\u0430\u0436\u0435,
|
|
106
|
+
\u0441\u043A\u0430\u0436\u0438 \u043E\u0431 \u044D\u0442\u043E\u043C \u043E\u0434\u043D\u043E\u0439 \u0444\u0440\u0430\u0437\u043E\u0439 \u0438 \u0441\u043F\u0440\u043E\u0441\u0438, \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u043B\u0438; \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0442\u0441\u044F \u2014 \u0437\u043E\u0432\u0438
|
|
107
|
+
setup \u0441 what=engine \u0438 consent=true. \u041D\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0439 \u043C\u043E\u043B\u0447\u0430 \u0438 \u043D\u0435 \u0431\u0440\u043E\u0441\u0430\u0439 \u0440\u0430\u0434\u0438 \u044D\u0442\u043E\u0433\u043E \u0435\u0433\u043E
|
|
108
|
+
\u0442\u0435\u043A\u0443\u0449\u0443\u044E \u0437\u0430\u0434\u0430\u0447\u0443: \u0441\u0442\u0430\u0440\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043A\u0430\u043A \u0440\u0430\u0431\u043E\u0442\u0430\u043B\u0430.
|
|
109
|
+
`.trim();
|
|
110
|
+
}
|
|
111
|
+
function aboutNewShell(installed, fresh, notes) {
|
|
112
|
+
return `
|
|
113
|
+
\u0412\u042B\u0428\u041B\u0410 \u041D\u041E\u0412\u0410\u042F \u0412\u0415\u0420\u0421\u0418\u042F \u0421\u0410\u041C\u041E\u0413\u041E \u0420\u0410\u0421\u0428\u0418\u0420\u0415\u041D\u0418\u042F
|
|
114
|
+
|
|
115
|
+
\u0421\u0442\u043E\u0438\u0442 ${installed}, \u0432\u044B\u0448\u043B\u0430 ${fresh}. \u0425\u043E\u0434\u0438\u0442\u044C \u043A \u0431\u043E\u0442\u0443 \u0437\u0430 \u0444\u0430\u0439\u043B\u043E\u043C \u0431\u043E\u043B\u044C\u0448\u0435 \u043D\u0435 \u043D\u0443\u0436\u043D\u043E \u2014
|
|
116
|
+
\u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F \u043E\u0442\u0441\u044E\u0434\u0430.
|
|
117
|
+
${notes === null ? "" : `
|
|
118
|
+
\u0427\u0422\u041E \u041D\u041E\u0412\u041E\u0413\u041E (\u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0436\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0441\u0432\u043E\u0438\u043C\u0438 \u0441\u043B\u043E\u0432\u0430\u043C\u0438, \u043D\u0435 \u0437\u0430\u0447\u0438\u0442\u044B\u0432\u0430\u0439 \u0446\u0435\u043B\u0438\u043A\u043E\u043C):
|
|
119
|
+
${notes}
|
|
120
|
+
`}
|
|
121
|
+
\u0421\u0430\u043C\u0430 \u043E\u043D\u0430 \u043D\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F. \u041A\u043E\u0433\u0434\u0430 \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0432 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0438\u0439 \u0440\u0430\u0437 \u0437\u0430\u0433\u043E\u0432\u043E\u0440\u0438\u0442 \u043E \u043C\u043E\u043D\u0442\u0430\u0436\u0435, \u0441\u043A\u0430\u0436\u0438
|
|
122
|
+
\u043E\u0431 \u044D\u0442\u043E\u043C \u043E\u0434\u043D\u043E\u0439 \u0444\u0440\u0430\u0437\u043E\u0439 \u0438 \u0441\u043F\u0440\u043E\u0441\u0438, \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u043B\u0438; \u0441\u043E\u0433\u043B\u0430\u0441\u0438\u0442\u0441\u044F \u2014 \u0437\u043E\u0432\u0438 setup \u0441
|
|
123
|
+
what=shell \u0438 consent=true. \u041D\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0439 \u043C\u043E\u043B\u0447\u0430 \u0438 \u043D\u0435 \u0431\u0440\u043E\u0441\u0430\u0439 \u0440\u0430\u0434\u0438 \u044D\u0442\u043E\u0433\u043E \u0435\u0433\u043E \u0442\u0435\u043A\u0443\u0449\u0443\u044E \u0437\u0430\u0434\u0430\u0447\u0443.
|
|
124
|
+
\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u0432\u0441\u0442\u0443\u043F\u0438\u0442 \u0432 \u0441\u0438\u043B\u0443 \u043F\u043E\u0441\u043B\u0435 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0430 \u041A\u043B\u043E\u0434\u0430 \u0438\u043B\u0438 Codex \u2014 \u0441\u043A\u0430\u0436\u0438 \u0438 \u044D\u0442\u043E, \u0438\u043D\u0430\u0447\u0435
|
|
125
|
+
\u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0440\u0435\u0448\u0438\u0442, \u0447\u0442\u043E \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u043E.
|
|
126
|
+
`.trim();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/auto-install.ts
|
|
130
|
+
var NO_AUTO = "NAPARNIK_NO_AUTOINSTALL";
|
|
131
|
+
async function prepareEngine(engine, opts) {
|
|
132
|
+
const say = opts.tell ?? (() => {
|
|
133
|
+
});
|
|
134
|
+
const quiet = { worked: false, ok: true, lines: [] };
|
|
135
|
+
if (engine.variable(NO_AUTO) !== void 0) return quiet;
|
|
136
|
+
if (opts.key === void 0 || opts.key === "") return quiet;
|
|
137
|
+
if (engine.pathSetByHand()) return quiet;
|
|
138
|
+
if (engine.place() !== null && await engine.pythonTrouble() === null) return quiet;
|
|
139
|
+
say("\u041A\u0430\u0447\u0430\u044E \u0434\u0432\u0438\u0436\u043E\u043A \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u2014 \u044D\u0442\u043E \u0440\u0430\u0437\u043E\u0432\u0430\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430, \u0434\u0430\u043B\u044C\u0448\u0435 \u043E\u043D \u043E\u0441\u0442\u0430\u0451\u0442\u0441\u044F \u043D\u0430 \u043C\u0430\u0448\u0438\u043D\u0435.");
|
|
140
|
+
const done = await installStep(engine, { step: "all", consent: true }, opts.key, opts.baseUrl, say);
|
|
141
|
+
const text = typeof done === "object" && "error" in done ? done.error : typeof done.content === "string" ? done.content : "";
|
|
142
|
+
if (text !== "") say(text);
|
|
143
|
+
return { worked: true, ok: !("error" in done), lines: text === "" ? [] : [text] };
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// src/installer-args.ts
|
|
147
|
+
var KEY_ARG = "--key";
|
|
148
|
+
var INSTALLER_ARGS = {
|
|
149
|
+
install: {
|
|
150
|
+
arg: "--install",
|
|
151
|
+
after: " codex",
|
|
152
|
+
what: "\u043F\u0440\u043E\u043F\u0438\u0441\u0430\u0442\u044C \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 ~/.codex/config.toml"
|
|
153
|
+
},
|
|
154
|
+
remove: {
|
|
155
|
+
arg: "--remove",
|
|
156
|
+
after: " codex",
|
|
157
|
+
what: "\u0443\u0431\u0440\u0430\u0442\u044C \u043E\u0442\u0442\u0443\u0434\u0430 \u043D\u0430\u0448 \u0431\u043B\u043E\u043A"
|
|
158
|
+
},
|
|
159
|
+
version: {
|
|
160
|
+
arg: "--version",
|
|
161
|
+
after: "",
|
|
162
|
+
what: "\u0432\u0435\u0440\u0441\u0438\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F"
|
|
163
|
+
},
|
|
164
|
+
rollback: {
|
|
165
|
+
arg: "--rollback",
|
|
166
|
+
after: "",
|
|
167
|
+
what: "\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0434\u0432\u0438\u0436\u043E\u043A \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043D\u0430 \u043F\u0440\u043E\u0448\u043B\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E"
|
|
168
|
+
},
|
|
169
|
+
/**
|
|
170
|
+
* ⚠ ЭТО ЕДИНСТВЕННЫЙ ВЫХОД ИЗ ОДНОГО ПОЛОЖЕНИЯ, И ПОТОМУ ОН ЗДЕСЬ, А НЕ ТОЛЬКО
|
|
171
|
+
* ИНСТРУМЕНТОМ. Тело оболочки, которое прошло дымовой прогон (`--version`
|
|
172
|
+
* печатается до `start()`), но падает уже внутри `start()`, оставляет человека
|
|
173
|
+
* без MCP-сессии вовсе — а значит и без инструмента `shell_rollback`. Этот
|
|
174
|
+
* флаг отрабатывает в ПУСКОВОМ файле, до передачи управления телу, то есть
|
|
175
|
+
* работает и тогда, когда тело не поднимается.
|
|
176
|
+
*/
|
|
177
|
+
shellRollback: {
|
|
178
|
+
arg: "--shell-rollback",
|
|
179
|
+
after: "",
|
|
180
|
+
what: "\u0432\u0435\u0440\u043D\u0443\u0442\u044C \u0441\u0430\u043C\u043E \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 \u043D\u0430 \u043F\u0440\u043E\u0448\u043B\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E"
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
function askedFor(args) {
|
|
184
|
+
const order = ["version", "shellRollback", "rollback", "install", "remove"];
|
|
185
|
+
for (const ask of order) {
|
|
186
|
+
if (args.includes(INSTALLER_ARGS[ask].arg)) return ask;
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
function keyRefusal(args) {
|
|
191
|
+
if (!args.includes(KEY_ARG)) return null;
|
|
192
|
+
return `\u041A\u043B\u044E\u0447 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u043C ${KEY_ARG} \u043D\u0435 \u043F\u0440\u0438\u043D\u0438\u043C\u0430\u0435\u0442\u0441\u044F: \u043E\u043D \u0432\u0438\u0434\u0435\u043D \u0432 \u0438\u0441\u0442\u043E\u0440\u0438\u0438 \u043E\u0431\u043E\u043B\u043E\u0447\u043A\u0438 \u0438 \u0432
|
|
193
|
+
\u0441\u043F\u0438\u0441\u043A\u0435 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u0432, \u0430 \u043D\u0430 \u0437\u0430\u043F\u0438\u0441\u0438 \u044D\u043A\u0440\u0430\u043D\u0430 \u2014 \u0446\u0435\u043B\u0438\u043A\u043E\u043C.
|
|
194
|
+
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0437\u0430\u0434\u0430\u0439 \u043A\u043B\u044E\u0447 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u0439 \u0441\u0440\u0435\u0434\u044B NAPARNIK_API_KEY \u2014 \u0438\u043B\u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438
|
|
195
|
+
\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0443 \u0431\u0435\u0437 \u044D\u0442\u043E\u0433\u043E \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u0430 \u0438 \u043E\u0442\u0432\u0435\u0442\u044C \u043D\u0430 \u0432\u043E\u043F\u0440\u043E\u0441 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0449\u0438\u043A\u0430: \u0432\u0432\u043E\u0434 \u043D\u0435
|
|
196
|
+
\u043F\u043E\u043A\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F.
|
|
197
|
+
`;
|
|
198
|
+
}
|
|
199
|
+
async function keyForInstall(env, ask) {
|
|
200
|
+
const given = fromHost(env["NAPARNIK_API_KEY"]);
|
|
201
|
+
return given !== "" ? given : await ask();
|
|
202
|
+
}
|
|
203
|
+
function helpText() {
|
|
204
|
+
const width = Math.max(
|
|
205
|
+
...Object.values(INSTALLER_ARGS).map((one) => `${one.arg}${one.after}`.length)
|
|
206
|
+
);
|
|
207
|
+
const lines = Object.values(INSTALLER_ARGS).map((one) => {
|
|
208
|
+
const left = `${one.arg}${one.after}`;
|
|
209
|
+
return ` ${left.padEnd(width)} ${one.what}`;
|
|
210
|
+
});
|
|
211
|
+
return `\u041D\u0435 \u043F\u043E\u043D\u044F\u043B \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u044B. \u0423\u043C\u0435\u044E:
|
|
212
|
+
${lines.join("\n")}
|
|
213
|
+
\u0411\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u2014 \u044D\u0442\u043E MCP-\u0441\u0435\u0440\u0432\u0435\u0440, \u0435\u0433\u043E \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u0435\u0442 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0430, \u0430 \u043D\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A.
|
|
214
|
+
`;
|
|
215
|
+
}
|
|
5
216
|
function log(message) {
|
|
6
217
|
process.stderr.write(`[naparnik-mcp] ${message}
|
|
7
218
|
`);
|
|
8
219
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
220
|
+
function theFile() {
|
|
221
|
+
return fileURLToPath(import.meta.url);
|
|
222
|
+
}
|
|
223
|
+
async function askKey() {
|
|
224
|
+
if (process.stdin.isTTY !== true) return void 0;
|
|
225
|
+
const { createInterface } = await import('readline/promises');
|
|
226
|
+
const lines = createInterface({ input: process.stdin, output: process.stdout, terminal: true });
|
|
227
|
+
lines._writeToOutput = () => {
|
|
228
|
+
};
|
|
229
|
+
try {
|
|
230
|
+
process.stdout.write(
|
|
231
|
+
// ⚠ ЗДЕСЬ ОБЕЩАЛИСЬ ЛЕНТА РИЛСОВ, РАСПАКОВКА БРЕНДА И ГЕНЕРАЦИЯ. Этих
|
|
232
|
+
// инструментов нет с 2026-09-02: полка данных убрана вместе с гашением
|
|
233
|
+
// монолита. Человек вводил ключ за то, чего в расширении не будет.
|
|
234
|
+
`${WHERE_TO_GET_KEY}
|
|
235
|
+
\u041F\u043E \u043D\u0435\u043C\u0443 \u043F\u0440\u043E\u0432\u0435\u0440\u044F\u0435\u0442\u0441\u044F \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u0438 \u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u0434\u0432\u0438\u0436\u043E\u043A \u043C\u043E\u043D\u0442\u0430\u0436\u0430. \u0411\u0435\u0437 \u043A\u043B\u044E\u0447\u0430
|
|
236
|
+
\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u0438 \u0437\u0430\u0431\u0440\u0430\u0442\u044C \u0443\u0436\u0435 \u0433\u043E\u0442\u043E\u0432\u043E\u0435.
|
|
237
|
+
\u041A\u043B\u044E\u0447: `
|
|
238
|
+
);
|
|
239
|
+
const response = (await lines.question("")).trim();
|
|
240
|
+
process.stdout.write("\n");
|
|
241
|
+
return response === "" ? void 0 : response;
|
|
242
|
+
} finally {
|
|
243
|
+
lines.close();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
async function installer(args) {
|
|
247
|
+
if (args.length === 0) return false;
|
|
248
|
+
const leak = keyRefusal(args);
|
|
249
|
+
if (leak !== null) {
|
|
250
|
+
process.stderr.write(leak);
|
|
251
|
+
process.exitCode = 2;
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
const ask = askedFor(args);
|
|
255
|
+
if (ask === "version") {
|
|
256
|
+
process.stdout.write(`${VERSION}
|
|
257
|
+
`);
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
if (ask === "rollback") {
|
|
261
|
+
const result = rollback(new Engine());
|
|
262
|
+
process.stdout.write(`${result.text}
|
|
263
|
+
`);
|
|
264
|
+
if (!result.ok) process.exitCode = 1;
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
if (ask === "shellRollback") {
|
|
268
|
+
const result = rollbackShell(new Engine().home());
|
|
269
|
+
process.stdout.write(`${result.text}
|
|
270
|
+
`);
|
|
271
|
+
if (!result.ok) process.exitCode = 1;
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
const where = args.indexOf(INSTALLER_ARGS.install.arg);
|
|
275
|
+
const strip = args.indexOf(INSTALLER_ARGS.remove.arg);
|
|
276
|
+
const target = where !== -1 ? args[where + 1] : strip !== -1 ? args[strip + 1] : void 0;
|
|
277
|
+
if (ask === null) {
|
|
278
|
+
process.stderr.write(helpText());
|
|
279
|
+
process.exitCode = 2;
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
if (target !== "codex") {
|
|
283
|
+
process.stderr.write(
|
|
284
|
+
`\u0423\u043C\u0435\u044E \u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0442\u043E\u043B\u044C\u043A\u043E \u0432 codex, \u0430 \u043F\u0440\u043E\u0441\u044F\u0442 \xAB${target ?? ""}\xBB.
|
|
285
|
+
Claude Desktop \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F \u043F\u0435\u0440\u0435\u0442\u0430\u0441\u043A\u0438\u0432\u0430\u043D\u0438\u0435\u043C \u0444\u0430\u0439\u043B\u0430 .mcpb, Claude Code \u2014 \u043A\u043E\u043C\u0430\u043D\u0434\u043E\u0439
|
|
286
|
+
\`claude mcp add\`. \u0420\u0443\u043A\u0430\u043C\u0438 \u043A\u043E\u043D\u0444\u0438\u0433 \u0442\u0430\u043C \u043F\u0440\u0430\u0432\u0438\u0442\u044C \u043D\u0435 \u043D\u0443\u0436\u043D\u043E.
|
|
287
|
+
`
|
|
288
|
+
);
|
|
289
|
+
process.exitCode = 2;
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
try {
|
|
293
|
+
if (strip !== -1) {
|
|
294
|
+
process.stdout.write(`${remove().words}
|
|
295
|
+
`);
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
const file = theFile();
|
|
299
|
+
if (fromNpxCache(file)) {
|
|
300
|
+
process.stderr.write(
|
|
301
|
+
`\u0417\u0430\u043F\u0443\u0449\u0435\u043D\u043E \u0447\u0435\u0440\u0435\u0437 npx \u2014 \u043F\u0440\u043E\u043F\u0438\u0441\u044B\u0432\u0430\u0442\u044C \u0432 \u043A\u043E\u043D\u0444\u0438\u0433 \u043D\u0435\u0447\u0435\u0433\u043E.
|
|
302
|
+
\u042D\u0442\u043E\u0442 \u0444\u0430\u0439\u043B \u043B\u0435\u0436\u0438\u0442 \u0432\u043E \u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u043C \u043A\u044D\u0448\u0435 npx (${file}), \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0441\u043D\u043E\u0441\u044F\u0442 \u0447\u0438\u0441\u0442\u043A\u0430 npm,
|
|
303
|
+
\u0443\u0431\u043E\u0440\u0449\u0438\u043A\u0438 \u0434\u0438\u0441\u043A\u0430 \u0438 \u043A\u043E\u0440\u043F\u043E\u0440\u0430\u0442\u0438\u0432\u043D\u044B\u0435 \u043F\u043E\u043B\u0438\u0442\u0438\u043A\u0438. Codex \u043F\u043E\u0441\u043B\u0435 \u044D\u0442\u043E\u0433\u043E \u0431\u0443\u0434\u0435\u0442 \u0432\u0435\u0447\u043D\u043E
|
|
304
|
+
\u0441\u043E\u043E\u0431\u0449\u0430\u0442\u044C, \u0447\u0442\u043E \u0441\u0435\u0440\u0432\u0435\u0440 \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u043B\u0441\u044F.
|
|
305
|
+
|
|
306
|
+
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0441\u0442\u0430\u0432\u044C\u0442\u0435 \u043F\u0430\u043A\u0435\u0442 \u043F\u043E\u0441\u0442\u043E\u044F\u043D\u043D\u043E \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435
|
|
307
|
+
npm i -g @naparnik/mcp
|
|
308
|
+
naparnik-mcp --install codex
|
|
309
|
+
`
|
|
310
|
+
);
|
|
311
|
+
process.exitCode = 2;
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
const key = await keyForInstall(process.env, askKey);
|
|
315
|
+
const result = install({ entryFile: file, ...key !== void 0 ? { key } : {} });
|
|
316
|
+
process.stdout.write(`${result.words}
|
|
317
|
+
`);
|
|
318
|
+
const forEngine = key ?? keyFromBlock(readFileSync(result.file, "utf8"));
|
|
319
|
+
const engine = new Engine();
|
|
320
|
+
const outcome = await prepareEngine(engine, {
|
|
321
|
+
key: forEngine,
|
|
322
|
+
baseUrl: serverAddress(readConfig()),
|
|
323
|
+
tell: (line) => process.stdout.write(`${line}
|
|
324
|
+
`)
|
|
325
|
+
});
|
|
326
|
+
if (outcome.worked && !outcome.ok) {
|
|
327
|
+
process.stdout.write(
|
|
328
|
+
"\u0414\u0432\u0438\u0436\u043E\u043A \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u0441\u0435\u0439\u0447\u0430\u0441 \u043D\u0435 \u0432\u044B\u0448\u043B\u043E. \u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 Codex \u0438 \u0441\u043A\u0430\u0436\u0438\u0442\u0435\n\xAB\u043F\u0440\u043E\u0432\u0435\u0440\u044C, \u0432\u0441\u0451 \u043B\u0438 \u0433\u043E\u0442\u043E\u0432\u043E \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430\xBB \u2014 \u0434\u043E\u043A\u0430\u0447\u0430\u044E \u043E\u0442\u0442\u0443\u0434\u0430.\n"
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
} catch (trouble) {
|
|
332
|
+
process.stderr.write(`${trouble instanceof ForeignBlockError ? trouble.message : String(trouble)}
|
|
333
|
+
`);
|
|
334
|
+
process.exitCode = 1;
|
|
335
|
+
}
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
function serverAddress(state) {
|
|
339
|
+
return state.ok ? state.config.baseUrl : state.baseUrl;
|
|
340
|
+
}
|
|
341
|
+
async function newPayload(engine, baseUrl, key) {
|
|
342
|
+
if (engine.variable("NAPARNIK_NO_UPDATE") !== void 0) return null;
|
|
343
|
+
if (engine.place() === null) return null;
|
|
344
|
+
if (engine.pathSetByHand()) return null;
|
|
345
|
+
if (!timeToCheck2(engine)) return null;
|
|
346
|
+
try {
|
|
347
|
+
const url = engine.variable("NAPARNIK_UPDATE_MANIFEST") ?? manifestUrlFor(baseUrl);
|
|
348
|
+
const outcome = await fetchManifest(url, void 0, key);
|
|
349
|
+
markChecked2(engine);
|
|
350
|
+
const decision = decide(engine.freshVersion(), outcome.ok ? outcome.manifest : null);
|
|
351
|
+
if (decision.what !== "newer_available") return null;
|
|
352
|
+
return aboutNewPayload(
|
|
353
|
+
engine.freshVersion(),
|
|
354
|
+
decision.manifest.version,
|
|
355
|
+
decision.manifest.bytes / 1024 / 1024
|
|
356
|
+
);
|
|
357
|
+
} catch {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
async function newShell(engine, baseUrl, key) {
|
|
362
|
+
if (engine.variable("NAPARNIK_NO_UPDATE") !== void 0) return null;
|
|
363
|
+
const home = engine.home();
|
|
364
|
+
const dir = shellDir(home);
|
|
365
|
+
if (!timeToCheck(dir)) return null;
|
|
366
|
+
try {
|
|
367
|
+
const url = engine.variable("NAPARNIK_BUNDLE_MANIFEST") ?? bundleUrlFor(baseUrl);
|
|
368
|
+
const outcome = await fetchShellManifest(url, void 0, key);
|
|
369
|
+
markChecked(dir);
|
|
370
|
+
const decision = decideShell(installedShell(home), outcome.ok ? outcome.manifest : null);
|
|
371
|
+
if (decision.what !== "newer_available") return null;
|
|
372
|
+
return aboutNewShell(
|
|
373
|
+
installedShell(home),
|
|
374
|
+
decision.manifest.version,
|
|
375
|
+
decision.manifest.notes
|
|
376
|
+
);
|
|
377
|
+
} catch {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
async function start() {
|
|
382
|
+
const state = readConfig();
|
|
383
|
+
const engineForVersion = new Engine();
|
|
384
|
+
const client = apiClientFor(state, void 0, () => engineForVersion.currentVersion());
|
|
385
|
+
const basics = state.ok ? configuredInstructions(state.config.baseUrl) : notConfiguredInstructions(state.problem, state.message);
|
|
386
|
+
const engine = new Engine();
|
|
387
|
+
const [passport, aboutUpdate, aboutShell] = await Promise.all([
|
|
388
|
+
engine.passport(),
|
|
389
|
+
newPayload(engine, serverAddress(state), state.ok ? state.config.apiKey : void 0),
|
|
390
|
+
newShell(engine, serverAddress(state), state.ok ? state.config.apiKey : void 0)
|
|
391
|
+
]);
|
|
392
|
+
const news = [aboutUpdate, aboutShell].filter((one) => one !== null);
|
|
393
|
+
const server = new McpServer(void 0, {
|
|
394
|
+
instructions: news.length === 0 ? basics : `${basics}
|
|
395
|
+
|
|
396
|
+
${news.join("\n\n")}`,
|
|
397
|
+
// ⚠ ПРЕДСТАВЛЯЕМСЯ СВОИМ ИМЕНЕМ, А НЕ ИМЕНЕМ ЯДРА. В Claude Desktop имя
|
|
398
|
+
// берётся из манифеста расширения и подмена незаметна, а в Codex человек
|
|
399
|
+
// видит ровно это — и читал «@naparnik/super-agent-core 0.1.0» вместо
|
|
400
|
+
// названия расширения, которое сам поставил.
|
|
401
|
+
serverInfo: { name: "@naparnik/mcp", version: VERSION }
|
|
402
|
+
});
|
|
403
|
+
const tools = buildAll(
|
|
404
|
+
client,
|
|
405
|
+
engine,
|
|
406
|
+
passport,
|
|
407
|
+
state.ok ? state.config.apiKey : void 0,
|
|
408
|
+
serverAddress(state)
|
|
409
|
+
);
|
|
14
410
|
for (const tool of tools) server.addTool(tool);
|
|
411
|
+
for (const r of buildResources()) server.addResource(r.resource, r.contents);
|
|
15
412
|
const transport = new StdioServerTransport();
|
|
16
413
|
transport.onClose((error) => {
|
|
17
414
|
if (error !== void 0) log(`\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0437\u0430\u043A\u0440\u044B\u0442\u043E \u0441 \u043E\u0448\u0438\u0431\u043A\u043E\u0439: ${error.message}`);
|
|
@@ -19,18 +416,55 @@ async function main() {
|
|
|
19
416
|
});
|
|
20
417
|
await transport.connect();
|
|
21
418
|
await server.start(transport);
|
|
22
|
-
|
|
419
|
+
const aboutMontage = engine.place() !== null ? `\u0434\u0432\u0438\u0436\u043E\u043A \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043D\u0430\u0439\u0434\u0435\u043D: ${engine.place()?.engine}` : "\u0434\u0432\u0438\u0436\u043E\u043A \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043D\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D \u2014 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043E\u0431\u044A\u044F\u0441\u043D\u044F\u0442 \u044D\u0442\u043E \u0441\u043B\u043E\u0432\u0430\u043C\u0438";
|
|
420
|
+
if (state.ok) {
|
|
421
|
+
log(`\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0451\u043D \u043A ${state.config.baseUrl}, \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u0432: ${tools.length}; ${aboutMontage}`);
|
|
422
|
+
} else {
|
|
423
|
+
log(
|
|
424
|
+
`${state.message} \u0418\u043D\u0441\u0442\u0440\u0443\u043A\u0446\u0438\u044F \u043F\u043E \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u043D\u0430 \u043A\u043B\u0438\u0435\u043D\u0442\u0443. \u041C\u043E\u043D\u0442\u0430\u0436 \u0431\u0435\u0437 \u043A\u043B\u044E\u0447\u0430 \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0441\u044F, \u043D\u043E \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u043C\u043E\u0436\u043D\u043E: ${aboutMontage}.`
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
if (state.ok) {
|
|
428
|
+
void prepareEngine(engine, {
|
|
429
|
+
key: state.config.apiKey,
|
|
430
|
+
baseUrl: state.config.baseUrl,
|
|
431
|
+
tell: log
|
|
432
|
+
}).catch((trouble) => {
|
|
433
|
+
log(`\u0434\u0432\u0438\u0436\u043E\u043A \u0434\u043E\u043A\u0430\u0447\u0430\u0442\u044C \u043D\u0435 \u0432\u044B\u0448\u043B\u043E: ${trouble instanceof Error ? trouble.message : String(trouble)}`);
|
|
434
|
+
});
|
|
435
|
+
}
|
|
23
436
|
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
24
437
|
process.on(signal, () => {
|
|
25
438
|
void server.stop().finally(() => process.exit(0));
|
|
26
439
|
});
|
|
27
440
|
}
|
|
28
441
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
442
|
+
async function run() {
|
|
443
|
+
const args = process.argv.slice(2);
|
|
444
|
+
if (args.length === 0) {
|
|
445
|
+
const engine = new Engine();
|
|
446
|
+
if (engine.variable("NAPARNIK_NO_BODY") === void 0) {
|
|
447
|
+
const choice = chooseBody({ home: engine.home(), ownFile: theFile() });
|
|
448
|
+
if (await handOverToBody(choice, log)) return;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (await installer(args)) return;
|
|
452
|
+
await start();
|
|
453
|
+
}
|
|
454
|
+
function launchedDirectly() {
|
|
455
|
+
const started = process.argv[1];
|
|
456
|
+
if (started === void 0) return false;
|
|
457
|
+
try {
|
|
458
|
+
return realpathSync(started) === realpathSync(theFile());
|
|
459
|
+
} catch {
|
|
460
|
+
return started === theFile();
|
|
33
461
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
462
|
+
}
|
|
463
|
+
if (launchedDirectly()) {
|
|
464
|
+
run().catch((err) => {
|
|
465
|
+
log(`\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C\u0441\u044F: ${err instanceof Error ? err.message : String(err)}`);
|
|
466
|
+
process.exit(1);
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export { installer, start };
|