@naparnik/mcp 0.10.43 → 0.10.48
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 +25 -0
- package/dist/{chunk-DQDZKXDU.js → chunk-Q7HJ7ROV.js} +763 -139
- package/dist/cli.js +5 -5
- package/dist/index.d.ts +80 -6
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -2,10 +2,12 @@ import { execFile, spawn, execFileSync } from 'child_process';
|
|
|
2
2
|
import { createHash, randomBytes, randomUUID } from 'crypto';
|
|
3
3
|
import { existsSync, readFileSync, closeSync, mkdirSync, openSync, readdirSync, statSync, rmSync, writeFileSync, renameSync, symlinkSync, chmodSync, lstatSync, realpathSync, mkdtempSync, linkSync, readlinkSync, appendFileSync, fstatSync, readSync, fsyncSync } from 'fs';
|
|
4
4
|
import { platform, homedir, arch, release, userInfo, tmpdir } from 'os';
|
|
5
|
-
import { win32, join, dirname, sep, resolve, relative, isAbsolute,
|
|
5
|
+
import { win32, join, dirname, sep, resolve, basename, relative, isAbsolute, extname } from 'path';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
7
8
|
import { gunzipSync } from 'zlib';
|
|
8
9
|
import { pathToFileURL, fileURLToPath } from 'url';
|
|
10
|
+
import { Worker } from 'worker_threads';
|
|
9
11
|
import { readFile } from 'fs/promises';
|
|
10
12
|
|
|
11
13
|
var __defProp = Object.defineProperty;
|
|
@@ -728,7 +730,7 @@ function parsePositiveInt(raw, fallback) {
|
|
|
728
730
|
}
|
|
729
731
|
|
|
730
732
|
// src/version.ts
|
|
731
|
-
var VERSION = "0.10.
|
|
733
|
+
var VERSION = "0.10.48";
|
|
732
734
|
var USER_AGENT = `naparnik-mcp/${VERSION}`;
|
|
733
735
|
var MIN_ENGINE = "2026.09.24-466";
|
|
734
736
|
var LAUNCHER_PROTOCOL = 1;
|
|
@@ -1548,7 +1550,65 @@ var Engine = class {
|
|
|
1548
1550
|
}
|
|
1549
1551
|
/** Python подготовки кандидата — намеренно без fallback на venv старого пака. */
|
|
1550
1552
|
bootstrapPython() {
|
|
1551
|
-
return this.
|
|
1553
|
+
return this.bootstrapPythons()[0] ?? (platform() === "win32" ? "python" : "python3");
|
|
1554
|
+
}
|
|
1555
|
+
/**
|
|
1556
|
+
* Чем собирать окружение новой версии — по порядку, до первого, кто сумеет.
|
|
1557
|
+
*
|
|
1558
|
+
* ⚠ БАЗОВЫЙ ПИТОН РАБОЧЕЙ ВЕРСИИ СТОИТ ВПЕРЕДИ «python3» ИЗ PATH, И ЭТО
|
|
1559
|
+
* ПОЧИНКА, А НЕ ВКУС. Claude Desktop на маке запускает нас без
|
|
1560
|
+
* `/opt/homebrew/bin` в PATH, и «python3» там — `/usr/bin/python3`, питон
|
|
1561
|
+
* Xcode 3.9. Он собирает venv только ссылками («This build of python cannot
|
|
1562
|
+
* create venvs without using symlinks»), а ссылка на интерпретатор вне версии
|
|
1563
|
+
* не проходит сверку `candidateVenvTrouble`. Обновление 2026.09.24-467 у
|
|
1564
|
+
* владельца встало ровно на этом, хотя рабочая версия собрана Homebrew 3.14
|
|
1565
|
+
* копиями и работает. Движок при первой установке ищет питон сам
|
|
1566
|
+
* (`setup/python_finder.py`) и пишет, какой взял, в `pyvenv.cfg` окружения —
|
|
1567
|
+
* этот и берём: он уже однажды собрал здесь рабочее окружение копиями.
|
|
1568
|
+
*
|
|
1569
|
+
* ⚠ НЕ ПИТОН САМОГО VENV. Окружение старой версии удаляется уборкой после
|
|
1570
|
+
* обновления, и кандидат, собранный его питоном, остался бы без интерпретатора
|
|
1571
|
+
* (`engine-candidate.test.ts`). База из `pyvenv.cfg` лежит вне версий.
|
|
1572
|
+
*/
|
|
1573
|
+
bootstrapPythons() {
|
|
1574
|
+
const found = [
|
|
1575
|
+
this.ourPython(),
|
|
1576
|
+
this.workingBasePython(),
|
|
1577
|
+
platform() === "win32" ? "python" : "python3"
|
|
1578
|
+
].filter((one) => one !== null);
|
|
1579
|
+
return [...new Set(found)];
|
|
1580
|
+
}
|
|
1581
|
+
/**
|
|
1582
|
+
* Базовый интерпретатор окружения рабочей версии — из её `pyvenv.cfg`.
|
|
1583
|
+
*
|
|
1584
|
+
* `home` раньше `executable`: у Homebrew `executable` указывает в папку
|
|
1585
|
+
* конкретного выпуска (`Cellar/python@3.14/3.14.7/…`), и после `brew upgrade`
|
|
1586
|
+
* её уже нет, а `home` (`/opt/homebrew/opt/python@3.14/bin`) переживает
|
|
1587
|
+
* обновление. Нет файла или записанного питона на диске — `null`.
|
|
1588
|
+
*/
|
|
1589
|
+
workingBasePython() {
|
|
1590
|
+
const place = this.place();
|
|
1591
|
+
if (place === null) return null;
|
|
1592
|
+
let text2;
|
|
1593
|
+
try {
|
|
1594
|
+
text2 = readFileSync(join(place.pack, ".venv", "pyvenv.cfg"), "utf8");
|
|
1595
|
+
} catch {
|
|
1596
|
+
return null;
|
|
1597
|
+
}
|
|
1598
|
+
const value = (key) => {
|
|
1599
|
+
const found = new RegExp(`^\\s*${key}\\s*=\\s*(.+?)\\s*$`, "m").exec(text2);
|
|
1600
|
+
return found?.[1] ?? null;
|
|
1601
|
+
};
|
|
1602
|
+
const home = value("home");
|
|
1603
|
+
if (home !== null) {
|
|
1604
|
+
const names = platform() === "win32" ? ["python.exe"] : ["python3", "python"];
|
|
1605
|
+
for (const name of names) {
|
|
1606
|
+
const candidate = join(home, name);
|
|
1607
|
+
if (existsSync(candidate)) return candidate;
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
const executable = value("executable");
|
|
1611
|
+
return executable !== null && existsSync(executable) ? executable : null;
|
|
1552
1612
|
}
|
|
1553
1613
|
/** Python ровно названного кандидата, а не текущей версии. */
|
|
1554
1614
|
candidatePython(place) {
|
|
@@ -1676,6 +1736,45 @@ var Engine = class {
|
|
|
1676
1736
|
env: montageEnv(this.pythonEnv(), key)
|
|
1677
1737
|
});
|
|
1678
1738
|
}
|
|
1739
|
+
/**
|
|
1740
|
+
* То же, что `command`, но строки stderr уходят в `onLine` по мере печати.
|
|
1741
|
+
*
|
|
1742
|
+
* ⚠ РАДИ СКАЧИВАНИЯ НАЧИНКИ. `deliver` печатает «Скачано 3 МБ из 6 (50%)» в
|
|
1743
|
+
* stderr по ходу, а `command` отдаёт всё разом в конце — и полоса обновления
|
|
1744
|
+
* стояла без единой цифры, пока архив качался (владелец 2026-09-24: «как
|
|
1745
|
+
* будто завис»). Строки те же, что у задач движка, и полоса разбирает их тем
|
|
1746
|
+
* же `DOWNLOAD` (`job-report.ts`).
|
|
1747
|
+
*/
|
|
1748
|
+
async commandLive(args, { timeout = 3e5, key }, onLine) {
|
|
1749
|
+
const place = this.place();
|
|
1750
|
+
if (place === null) return { ok: false, text: this.whyNoEngine() };
|
|
1751
|
+
const trouble = await this.pythonTrouble();
|
|
1752
|
+
if (trouble !== null) return { ok: false, text: trouble };
|
|
1753
|
+
try {
|
|
1754
|
+
const { stdout, stderr } = await new Promise((done, fail) => {
|
|
1755
|
+
const child = execFile(this.enginePython(), [place.consolePy, ...args], {
|
|
1756
|
+
cwd: existsSync(place.pack) ? place.pack : place.engine,
|
|
1757
|
+
maxBuffer: 8 << 20,
|
|
1758
|
+
timeout,
|
|
1759
|
+
encoding: "utf8",
|
|
1760
|
+
env: montageEnv(this.pythonEnv(), key)
|
|
1761
|
+
}, (err, out, errOut) => {
|
|
1762
|
+
if (err !== null) fail(Object.assign(err, { stdout: out, stderr: errOut }));
|
|
1763
|
+
else done({ stdout: out, stderr: errOut });
|
|
1764
|
+
});
|
|
1765
|
+
let rest = "";
|
|
1766
|
+
child.stderr?.on("data", (chunk) => {
|
|
1767
|
+
rest += String(chunk);
|
|
1768
|
+
const lines = rest.split(/\r?\n|\r/);
|
|
1769
|
+
rest = lines.pop() ?? "";
|
|
1770
|
+
for (const line of lines) if (line.trim() !== "") onLine(line.trim());
|
|
1771
|
+
});
|
|
1772
|
+
});
|
|
1773
|
+
return { ok: true, text: (stdout + stderr).trim() };
|
|
1774
|
+
} catch (err) {
|
|
1775
|
+
return parseFailure(err, "\u041A\u043E\u043C\u0430\u043D\u0434\u0430 \u043D\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u043B\u0430\u0441\u044C");
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1679
1778
|
/** Одна строка вывода команды — например, номер заведённого задания. */
|
|
1680
1779
|
async asString(place, args, key) {
|
|
1681
1780
|
const { stdout } = await this.run(place, args, {
|
|
@@ -13793,6 +13892,29 @@ async function askPointer(opts) {
|
|
|
13793
13892
|
clearTimeout(timer);
|
|
13794
13893
|
}
|
|
13795
13894
|
}
|
|
13895
|
+
var scope = new AsyncLocalStorage();
|
|
13896
|
+
function noteInstallFault(stage, trouble) {
|
|
13897
|
+
scope.getStore()?.push({ stage, trouble });
|
|
13898
|
+
}
|
|
13899
|
+
async function collectInstallFaults(work) {
|
|
13900
|
+
const faults = [];
|
|
13901
|
+
const value = await scope.run(faults, work);
|
|
13902
|
+
return { value, faults };
|
|
13903
|
+
}
|
|
13904
|
+
var JOBS_KEPT = 10;
|
|
13905
|
+
var byJob = /* @__PURE__ */ new Map();
|
|
13906
|
+
function collectJobInstallFaults(id, work) {
|
|
13907
|
+
const faults = [];
|
|
13908
|
+
byJob.delete(id);
|
|
13909
|
+
byJob.set(id, faults);
|
|
13910
|
+
while (byJob.size > JOBS_KEPT) byJob.delete(byJob.keys().next().value);
|
|
13911
|
+
return scope.run(faults, work);
|
|
13912
|
+
}
|
|
13913
|
+
function jobInstallFaults(id) {
|
|
13914
|
+
return byJob.get(id) ?? [];
|
|
13915
|
+
}
|
|
13916
|
+
|
|
13917
|
+
// src/update.ts
|
|
13796
13918
|
var MANIFEST_PATH = "/download/engine/manifest.json";
|
|
13797
13919
|
function manifestUrlFor(baseUrl) {
|
|
13798
13920
|
return pointerUrl(baseUrl, MANIFEST_PATH);
|
|
@@ -13846,6 +13968,7 @@ async function deploy(engine, manifest, trial = probe, key, hooks = {}) {
|
|
|
13846
13968
|
return await withVersionLock(dir, async () => deployLocked(engine, manifest, trial, key, hooks));
|
|
13847
13969
|
} catch (trouble) {
|
|
13848
13970
|
if (trouble instanceof VersionLockError) return { ok: false, text: trouble.message };
|
|
13971
|
+
noteInstallFault("deploy", trouble);
|
|
13849
13972
|
return {
|
|
13850
13973
|
ok: false,
|
|
13851
13974
|
text: `\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0434\u043E \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F current: ${describeFailure(trouble)}. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup.`
|
|
@@ -13880,20 +14003,20 @@ async function deployLocked(engine, manifest, trial, key, hooks) {
|
|
|
13880
14003
|
if (!existsSync(dest)) {
|
|
13881
14004
|
const stage = createVersionStage(dir, manifest.version);
|
|
13882
14005
|
try {
|
|
13883
|
-
const
|
|
13884
|
-
|
|
13885
|
-
|
|
13886
|
-
|
|
13887
|
-
|
|
13888
|
-
|
|
13889
|
-
|
|
13890
|
-
|
|
13891
|
-
|
|
13892
|
-
|
|
13893
|
-
|
|
13894
|
-
|
|
13895
|
-
|
|
13896
|
-
);
|
|
14006
|
+
const deliverArgs = [
|
|
14007
|
+
"deliver",
|
|
14008
|
+
"--url",
|
|
14009
|
+
manifest.url,
|
|
14010
|
+
"--dest",
|
|
14011
|
+
stage.payload,
|
|
14012
|
+
"--sha256",
|
|
14013
|
+
manifest.sha256,
|
|
14014
|
+
"--byte",
|
|
14015
|
+
String(manifest.bytes)
|
|
14016
|
+
];
|
|
14017
|
+
const deliverOpts = { timeout: 30 * 6e4, ...key !== void 0 ? { key } : {} };
|
|
14018
|
+
const say = hooks.line;
|
|
14019
|
+
const delivery = say !== void 0 && engine.commandLive !== void 0 ? await engine.commandLive(deliverArgs, deliverOpts, (text2) => say(text2)) : await engine.command(deliverArgs, deliverOpts);
|
|
13897
14020
|
if (!delivery.ok) {
|
|
13898
14021
|
return { ok: false, text: `\u041D\u0430\u0447\u0438\u043D\u043A\u0443 \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C, \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043C\u0435\u043D\u044F\u043B.
|
|
13899
14022
|
${delivery.text}` };
|
|
@@ -13935,6 +14058,7 @@ ${delivery.text}` };
|
|
|
13935
14058
|
discardVersionStage(stage);
|
|
13936
14059
|
}
|
|
13937
14060
|
}
|
|
14061
|
+
hooks.downloaded?.();
|
|
13938
14062
|
if (candidateDeps(engine)) return activatePreparedCandidateLocked(engine, manifest, trial);
|
|
13939
14063
|
const smoke = await dryRun(engine, dest, manifest.version, trial);
|
|
13940
14064
|
if (smoke !== null) {
|
|
@@ -14014,6 +14138,7 @@ async function continuePreparedCandidate(engine, expected, bootstrap, trial = pr
|
|
|
14014
14138
|
});
|
|
14015
14139
|
} catch (trouble) {
|
|
14016
14140
|
if (trouble instanceof VersionLockError) return { ok: false, text: trouble.message };
|
|
14141
|
+
noteInstallFault("activate", trouble);
|
|
14017
14142
|
return {
|
|
14018
14143
|
ok: false,
|
|
14019
14144
|
text: `\u041A\u0430\u043D\u0434\u0438\u0434\u0430\u0442 \u043D\u0435 \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0435\u043D: ${describeFailure(trouble)}. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0438\u0441\u043F\u0440\u0430\u0432\u044C\u0442\u0435 \u043F\u0440\u0438\u0447\u0438\u043D\u0443 \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup.`
|
|
@@ -14172,13 +14297,7 @@ async function prepareCopiedCandidateVenv(engine, dir, version2, place) {
|
|
|
14172
14297
|
if (engine.prepareCandidateVenv !== void 0) {
|
|
14173
14298
|
await engine.prepareCandidateVenv(place);
|
|
14174
14299
|
} else {
|
|
14175
|
-
|
|
14176
|
-
const { promisify: promisify3 } = await import('util');
|
|
14177
|
-
await promisify3(execFile4)(engine.bootstrapPython(), ["-m", "venv", "--copies", venv], {
|
|
14178
|
-
timeout: 10 * 6e4,
|
|
14179
|
-
encoding: "utf8",
|
|
14180
|
-
env: { ...engine.pythonEnv(), PYTHONDONTWRITEBYTECODE: "1" }
|
|
14181
|
-
});
|
|
14300
|
+
await copiedVenv(engine, venv);
|
|
14182
14301
|
}
|
|
14183
14302
|
}
|
|
14184
14303
|
const createdTrouble = candidateVenvTrouble(dir, version2, place, true);
|
|
@@ -14188,17 +14307,41 @@ async function prepareCopiedCandidateVenv(engine, dir, version2, place) {
|
|
|
14188
14307
|
throw new Error("\u0448\u0442\u0430\u0442\u043D\u044B\u0439 .venv \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u0441\u043E\u0437\u0434\u0430\u043D \u0431\u0435\u0437 \u0440\u0430\u0431\u043E\u0447\u0435\u0433\u043E pip");
|
|
14189
14308
|
}
|
|
14190
14309
|
}
|
|
14310
|
+
var SYMLINKS_ONLY = "cannot create venvs without using symlinks";
|
|
14311
|
+
async function copiedVenv(engine, venv) {
|
|
14312
|
+
const { execFile: execFile3 } = await import('child_process');
|
|
14313
|
+
const { promisify: promisify2 } = await import('util');
|
|
14314
|
+
const pythons = engine.bootstrapPythons?.() ?? [engine.bootstrapPython()];
|
|
14315
|
+
const refusals = [];
|
|
14316
|
+
for (const python of pythons) {
|
|
14317
|
+
try {
|
|
14318
|
+
await promisify2(execFile3)(python, ["-m", "venv", "--copies", venv], {
|
|
14319
|
+
timeout: 10 * 6e4,
|
|
14320
|
+
encoding: "utf8",
|
|
14321
|
+
env: { ...engine.pythonEnv(), PYTHONDONTWRITEBYTECODE: "1" }
|
|
14322
|
+
});
|
|
14323
|
+
return;
|
|
14324
|
+
} catch (trouble) {
|
|
14325
|
+
rmSync(venv, { recursive: true, force: true });
|
|
14326
|
+
const said = `${String(trouble.stderr ?? "")} ${describeFailure(trouble)}`;
|
|
14327
|
+
refusals.push(said.includes(SYMLINKS_ONLY) ? `${python}: \u0441\u043E\u0431\u0438\u0440\u0430\u0435\u0442 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u0442\u043E\u043B\u044C\u043A\u043E \u0441\u0441\u044B\u043B\u043A\u0430\u043C\u0438` : `${python}: ${lastLine(said.trim())}`);
|
|
14328
|
+
}
|
|
14329
|
+
}
|
|
14330
|
+
throw new Error(
|
|
14331
|
+
`\u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0441\u043E\u0431\u0440\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u043C \u2014 ${refusals.join("; ")}. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0441\u0442\u0430\u0432\u044C Python \u0441 python.org/downloads \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438 \xAB\u043E\u0431\u043D\u043E\u0432\u0438\xBB.`
|
|
14332
|
+
);
|
|
14333
|
+
}
|
|
14191
14334
|
async function candidatePipReady(engine, python) {
|
|
14192
14335
|
if (engine.candidatePipReady !== void 0) return engine.candidatePipReady(python);
|
|
14193
|
-
const { execFile:
|
|
14194
|
-
const { promisify:
|
|
14336
|
+
const { execFile: execFile3 } = await import('child_process');
|
|
14337
|
+
const { promisify: promisify2 } = await import('util');
|
|
14195
14338
|
const env = { ...engine.pythonEnv(), PYTHONDONTWRITEBYTECODE: "1" };
|
|
14196
14339
|
delete env["PYTHONHOME"];
|
|
14197
14340
|
delete env["PYTHONPATH"];
|
|
14198
14341
|
delete env["VIRTUAL_ENV"];
|
|
14199
14342
|
delete env["__PYVENV_LAUNCHER__"];
|
|
14200
14343
|
try {
|
|
14201
|
-
await
|
|
14344
|
+
await promisify2(execFile3)(python, ["-B", "-m", "pip", "--version"], {
|
|
14202
14345
|
timeout: 6e4,
|
|
14203
14346
|
encoding: "utf8",
|
|
14204
14347
|
env
|
|
@@ -14304,6 +14447,7 @@ async function activatePreparedCandidateLocked(engine, manifest, trial, extras =
|
|
|
14304
14447
|
const installedVenvTrouble = candidateVenvTrouble(dir, candidate.version, place, true);
|
|
14305
14448
|
if (installedVenvTrouble !== null) throw new Error(installedVenvTrouble);
|
|
14306
14449
|
} catch (trouble) {
|
|
14450
|
+
noteInstallFault("env", trouble);
|
|
14307
14451
|
return blockCandidate(dir, candidate, `\u041E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435 \u0433\u043E\u0442\u043E\u0432\u043E \u2014 current \u043D\u0435 \u043C\u0435\u043D\u044F\u043B.
|
|
14308
14452
|
${commandWords(trouble)}`);
|
|
14309
14453
|
}
|
|
@@ -14345,6 +14489,7 @@ ${smoke}`);
|
|
|
14345
14489
|
{ timeout: 5 * 6e4 }
|
|
14346
14490
|
);
|
|
14347
14491
|
} catch (trouble) {
|
|
14492
|
+
noteInstallFault("env-check", trouble);
|
|
14348
14493
|
return blockCandidate(
|
|
14349
14494
|
dir,
|
|
14350
14495
|
candidate,
|
|
@@ -14510,9 +14655,9 @@ async function dryRun(engine, build, expected, trial) {
|
|
|
14510
14655
|
}
|
|
14511
14656
|
}
|
|
14512
14657
|
async function probe(engine, consolePy) {
|
|
14513
|
-
const { execFile:
|
|
14514
|
-
const { promisify:
|
|
14515
|
-
return
|
|
14658
|
+
const { execFile: execFile3 } = await import('child_process');
|
|
14659
|
+
const { promisify: promisify2 } = await import('util');
|
|
14660
|
+
return promisify2(execFile3)(engine.enginePython(), [consolePy, "version"], {
|
|
14516
14661
|
timeout: 6e4,
|
|
14517
14662
|
encoding: "utf8",
|
|
14518
14663
|
env: engine.pythonEnv()
|
|
@@ -14941,50 +15086,100 @@ function removePublication(dir, version2) {
|
|
|
14941
15086
|
function publicationMatchesManifest(publication, manifest) {
|
|
14942
15087
|
return publication.version === manifest.version && publication.artifactSha256 === manifest.body?.sha256 && publication.artifactBytes === manifest.body.bytes;
|
|
14943
15088
|
}
|
|
15089
|
+
var PROBE_TIMEOUT_MS = 6e4;
|
|
15090
|
+
var REQUIRED_TOOLS = ["setup", "render", "wait"];
|
|
15091
|
+
var PROBE_THREAD = `
|
|
15092
|
+
const { parentPort, workerData } = require('node:worker_threads')
|
|
15093
|
+
import(workerData.entry).then((body) => {
|
|
15094
|
+
if (typeof body.start !== 'function') throw new Error('\u0432\u0445\u043E\u0434 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435 \u043E\u0442\u0434\u0430\u0451\u0442 start()')
|
|
15095
|
+
return body.start()
|
|
15096
|
+
}).catch((trouble) => {
|
|
15097
|
+
parentPort.postMessage(trouble instanceof Error
|
|
15098
|
+
? { message: trouble.name + ': ' + String(trouble.message).split('\\n')[0], stack: String(trouble.stack || '') }
|
|
15099
|
+
: { message: String(trouble), stack: '' })
|
|
15100
|
+
})
|
|
15101
|
+
`;
|
|
14944
15102
|
var probeShell = async (entry) => {
|
|
14945
15103
|
const probeHome = mkdtempSync(join(tmpdir(), "naparnik-shell-probe-"));
|
|
14946
|
-
const env = {
|
|
14947
|
-
|
|
14948
|
-
|
|
14949
|
-
|
|
14950
|
-
|
|
14951
|
-
|
|
15104
|
+
const env = {};
|
|
15105
|
+
for (const [name, value] of Object.entries(process.env)) {
|
|
15106
|
+
if (value !== void 0 && name !== "NAPARNIK_API_KEY") env[name] = value;
|
|
15107
|
+
}
|
|
15108
|
+
Object.assign(env, { NAPARNIK_HOME: probeHome, NAPARNIK_NO_BODY: "1", NAPARNIK_NO_UPDATE: "1" });
|
|
15109
|
+
const thread = new Worker(PROBE_THREAD, {
|
|
15110
|
+
eval: true,
|
|
15111
|
+
argv: [],
|
|
15112
|
+
env,
|
|
15113
|
+
stdin: true,
|
|
15114
|
+
stdout: true,
|
|
15115
|
+
stderr: true,
|
|
15116
|
+
workerData: { entry: pathToFileURL(entry).href }
|
|
15117
|
+
});
|
|
14952
15118
|
try {
|
|
14953
|
-
const
|
|
14954
|
-
timeout: 6e4,
|
|
14955
|
-
encoding: "utf8",
|
|
14956
|
-
env
|
|
14957
|
-
});
|
|
14958
|
-
await new Promise((resolve5, reject) => {
|
|
14959
|
-
const child = spawn(process.execPath, [entry], { stdio: ["pipe", "pipe", "pipe"], env });
|
|
15119
|
+
const named = await new Promise((resolve5, reject) => {
|
|
14960
15120
|
let output = "";
|
|
14961
15121
|
let errors = "";
|
|
14962
15122
|
let finished = false;
|
|
14963
|
-
const timer = setTimeout(
|
|
14964
|
-
|
|
15123
|
+
const timer = setTimeout(
|
|
15124
|
+
() => finish(failure(`\u0442\u0435\u043B\u043E \u043D\u0435 \u043E\u0442\u0432\u0435\u0442\u0438\u043B\u043E \u043D\u0430 initialize/tools-list \u0437\u0430 ${PROBE_TIMEOUT_MS / 1e3} \u0441`)),
|
|
15125
|
+
PROBE_TIMEOUT_MS
|
|
15126
|
+
);
|
|
15127
|
+
const finish = (trouble, said) => {
|
|
14965
15128
|
if (finished) return;
|
|
14966
15129
|
finished = true;
|
|
14967
15130
|
clearTimeout(timer);
|
|
14968
|
-
|
|
14969
|
-
if (trouble === void 0) resolve5();
|
|
15131
|
+
if (trouble === null) resolve5(said ?? "");
|
|
14970
15132
|
else reject(trouble);
|
|
14971
15133
|
};
|
|
14972
15134
|
const send = (message) => {
|
|
14973
|
-
|
|
15135
|
+
thread.stdin?.write(`${JSON.stringify(message)}
|
|
14974
15136
|
`);
|
|
14975
15137
|
};
|
|
14976
|
-
|
|
14977
|
-
|
|
14978
|
-
|
|
15138
|
+
const failure = (text2, stack = "") => {
|
|
15139
|
+
const trouble = new Error(text2);
|
|
15140
|
+
const said = errors.trim();
|
|
15141
|
+
trouble.stack = [text2, stack, said === "" ? "" : `stderr \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430:
|
|
15142
|
+
${said.slice(-4e3)}`].filter((part) => part !== "").join("\n");
|
|
15143
|
+
return trouble;
|
|
15144
|
+
};
|
|
15145
|
+
thread.on("message", (message) => {
|
|
15146
|
+
finish(failure(`\u0442\u0435\u043B\u043E \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u043B\u043E\u0441\u044C: ${String(message.message)}`, String(message.stack ?? "")));
|
|
15147
|
+
});
|
|
15148
|
+
thread.on("error", (trouble) => {
|
|
15149
|
+
finish(failure(`\u0442\u0435\u043B\u043E \u0443\u043F\u0430\u043B\u043E: ${describeFailure(trouble)}`, trouble.stack ?? ""));
|
|
14979
15150
|
});
|
|
14980
|
-
|
|
14981
|
-
finish(
|
|
15151
|
+
thread.on("exit", (code) => {
|
|
15152
|
+
finish(failure(`\u0442\u0435\u043B\u043E \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043B\u043E\u0441\u044C \u0441 \u043A\u043E\u0434\u043E\u043C ${String(code)}`));
|
|
14982
15153
|
});
|
|
14983
|
-
|
|
14984
|
-
|
|
15154
|
+
thread.stderr.setEncoding("utf8");
|
|
15155
|
+
thread.stderr.on("data", (chunk) => {
|
|
15156
|
+
errors += chunk;
|
|
14985
15157
|
});
|
|
14986
|
-
|
|
14987
|
-
|
|
15158
|
+
let version2 = null;
|
|
15159
|
+
const answer = (reply) => {
|
|
15160
|
+
if (reply.error !== void 0) {
|
|
15161
|
+
finish(failure(`MCP-\u043F\u0440\u043E\u0431\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u0430 \u043E\u0442\u043A\u0430\u0437: ${JSON.stringify(reply.error)}`));
|
|
15162
|
+
} else if (reply.id === 1) {
|
|
15163
|
+
const named2 = reply.result?.serverInfo?.version;
|
|
15164
|
+
if (typeof named2 !== "string" || named2 === "") {
|
|
15165
|
+
finish(failure("initialize \u043D\u0435 \u043D\u0430\u0437\u0432\u0430\u043B \u0432\u0435\u0440\u0441\u0438\u044E \u0442\u0435\u043B\u0430"));
|
|
15166
|
+
return;
|
|
15167
|
+
}
|
|
15168
|
+
version2 = named2;
|
|
15169
|
+
send({ jsonrpc: "2.0", method: "notifications/initialized" });
|
|
15170
|
+
send({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} });
|
|
15171
|
+
} else if (reply.id === 2 && version2 !== null) {
|
|
15172
|
+
const names = new Set((reply.result?.tools ?? []).map((tool) => tool.name));
|
|
15173
|
+
const missing = REQUIRED_TOOLS.filter((name) => !names.has(name));
|
|
15174
|
+
if (missing.length > 0) {
|
|
15175
|
+
finish(failure(`tools/list \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B: ${missing.join(", ")}`));
|
|
15176
|
+
return;
|
|
15177
|
+
}
|
|
15178
|
+
finish(null, version2);
|
|
15179
|
+
}
|
|
15180
|
+
};
|
|
15181
|
+
thread.stdout.setEncoding("utf8");
|
|
15182
|
+
thread.stdout.on("data", (chunk) => {
|
|
14988
15183
|
output += chunk;
|
|
14989
15184
|
for (; ; ) {
|
|
14990
15185
|
const end = output.indexOf("\n");
|
|
@@ -14992,36 +15187,14 @@ var probeShell = async (entry) => {
|
|
|
14992
15187
|
const line = output.slice(0, end).trim();
|
|
14993
15188
|
output = output.slice(end + 1);
|
|
14994
15189
|
if (line === "") continue;
|
|
14995
|
-
let
|
|
15190
|
+
let reply;
|
|
14996
15191
|
try {
|
|
14997
|
-
|
|
15192
|
+
reply = JSON.parse(line);
|
|
14998
15193
|
} catch {
|
|
14999
|
-
finish(
|
|
15000
|
-
return;
|
|
15001
|
-
}
|
|
15002
|
-
if (response.error !== void 0) {
|
|
15003
|
-
finish(new Error(`MCP-\u043F\u0440\u043E\u0431\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u0430 \u043E\u0442\u043A\u0430\u0437: ${JSON.stringify(response.error)}`));
|
|
15194
|
+
finish(failure(`\u0442\u0435\u043B\u043E \u043D\u0430\u043F\u0435\u0447\u0430\u0442\u0430\u043B\u043E \u043D\u0435 JSON: ${line.slice(0, 200)}`));
|
|
15004
15195
|
return;
|
|
15005
15196
|
}
|
|
15006
|
-
|
|
15007
|
-
const expected = version2.stdout.trim();
|
|
15008
|
-
if (response.result?.serverInfo?.version !== expected) {
|
|
15009
|
-
finish(new Error(
|
|
15010
|
-
`initialize \u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043B \u0442\u0435\u043B\u043E \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \xAB${String(response.result?.serverInfo?.version)}\xBB, \u0430 --version \u043E\u0442\u0432\u0435\u0442\u0438\u043B \xAB${expected}\xBB`
|
|
15011
|
-
));
|
|
15012
|
-
return;
|
|
15013
|
-
}
|
|
15014
|
-
send({ jsonrpc: "2.0", method: "notifications/initialized" });
|
|
15015
|
-
send({ jsonrpc: "2.0", id: 2, method: "tools/list", params: {} });
|
|
15016
|
-
} else if (response.id === 2) {
|
|
15017
|
-
const names = new Set((response.result?.tools ?? []).map((tool) => tool.name));
|
|
15018
|
-
const missing = ["setup", "render", "wait"].filter((name) => !names.has(name));
|
|
15019
|
-
if (missing.length > 0) {
|
|
15020
|
-
finish(new Error(`tools/list \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u0442 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u044B: ${missing.join(", ")}`));
|
|
15021
|
-
return;
|
|
15022
|
-
}
|
|
15023
|
-
finish();
|
|
15024
|
-
}
|
|
15197
|
+
answer(reply);
|
|
15025
15198
|
}
|
|
15026
15199
|
});
|
|
15027
15200
|
send({
|
|
@@ -15031,8 +15204,10 @@ var probeShell = async (entry) => {
|
|
|
15031
15204
|
params: { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "update-probe", version: "1" } }
|
|
15032
15205
|
});
|
|
15033
15206
|
});
|
|
15034
|
-
return
|
|
15207
|
+
return { stdout: `${named}
|
|
15208
|
+
` };
|
|
15035
15209
|
} finally {
|
|
15210
|
+
await thread.terminate();
|
|
15036
15211
|
rmSync(probeHome, { recursive: true, force: true, maxRetries: 3 });
|
|
15037
15212
|
}
|
|
15038
15213
|
};
|
|
@@ -15183,9 +15358,14 @@ async function dryRun2(build, expected, trial) {
|
|
|
15183
15358
|
const { stdout } = await trial(entry);
|
|
15184
15359
|
const line = stdout.trim().split("\n").pop() ?? "";
|
|
15185
15360
|
const said = versionFrom(line);
|
|
15186
|
-
if (said !== expected)
|
|
15361
|
+
if (said !== expected) {
|
|
15362
|
+
const trouble = `\u0441\u0431\u043E\u0440\u043A\u0430 \u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043B\u0430\u0441\u044C \u0432\u0435\u0440\u0441\u0438\u0435\u0439 \xAB${said}\xBB, \u0430 \u0436\u0434\u0430\u043B\u0438 \xAB${expected}\xBB`;
|
|
15363
|
+
noteInstallFault("shell-probe", new Error(trouble));
|
|
15364
|
+
return trouble;
|
|
15365
|
+
}
|
|
15187
15366
|
return null;
|
|
15188
15367
|
} catch (trouble) {
|
|
15368
|
+
noteInstallFault("shell-probe", trouble);
|
|
15189
15369
|
return describeFailure(trouble);
|
|
15190
15370
|
}
|
|
15191
15371
|
}
|
|
@@ -15830,6 +16010,7 @@ function empty() {
|
|
|
15830
16010
|
eta: "",
|
|
15831
16011
|
file: "",
|
|
15832
16012
|
outcome: "",
|
|
16013
|
+
say: "",
|
|
15833
16014
|
trouble: "",
|
|
15834
16015
|
advice: "",
|
|
15835
16016
|
complaints: [],
|
|
@@ -15840,18 +16021,18 @@ function startedJob(o) {
|
|
|
15840
16021
|
return { ...empty(), id: o.id, what: o.what, ahead: o.ahead, message: o.message };
|
|
15841
16022
|
}
|
|
15842
16023
|
var INSTALL_TITLES = {
|
|
15843
|
-
all: "\
|
|
16024
|
+
all: "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430",
|
|
15844
16025
|
check: "\u041F\u0440\u043E\u0432\u0435\u0440\u044F\u044E",
|
|
15845
|
-
python: "\
|
|
15846
|
-
ffmpeg: "\
|
|
15847
|
-
env: "\
|
|
15848
|
-
model: "\
|
|
15849
|
-
browser: "\
|
|
15850
|
-
cutout: "\
|
|
15851
|
-
voice: "\
|
|
16026
|
+
python: "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430",
|
|
16027
|
+
ffmpeg: "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430",
|
|
16028
|
+
env: "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430",
|
|
16029
|
+
model: "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044B",
|
|
16030
|
+
browser: "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0433\u0440\u0430\u0444\u0438\u043A\u0443",
|
|
16031
|
+
cutout: "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0437\u0430\u043C\u0435\u043D\u0443 \u0444\u043E\u043D\u0430",
|
|
16032
|
+
voice: "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0447\u0438\u0441\u0442\u043A\u0443 \u0433\u043E\u043B\u043E\u0441\u0430"
|
|
15852
16033
|
};
|
|
15853
16034
|
function installTitle(step) {
|
|
15854
|
-
return INSTALL_TITLES[step] ?? "\
|
|
16035
|
+
return INSTALL_TITLES[step] ?? "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430";
|
|
15855
16036
|
}
|
|
15856
16037
|
var INSTALL_HEAD = /^установка: (\S+)$/;
|
|
15857
16038
|
var HEAD = /^Задание (\S+): ?(.*)$/;
|
|
@@ -15862,6 +16043,7 @@ var DONE = /^Готово за (\d+(?:[.,]\d+)?) с\.$/;
|
|
|
15862
16043
|
var FILE = /^Файл: (.+)$/;
|
|
15863
16044
|
var FAILED = /^Не получилось за (\d+(?:[.,]\d+)?) с: (.*)$/;
|
|
15864
16045
|
var ADVICE = /^Что делать: (.+)$/;
|
|
16046
|
+
var SAY = /^Человеку: (.+)$/;
|
|
15865
16047
|
var ABORTED = /^Работа прервалась/;
|
|
15866
16048
|
var ABORTED_SEC = /Прошло (\d+(?:[.,]\d+)?) с\./;
|
|
15867
16049
|
var WAITING = /^Ждёт очереди/;
|
|
@@ -15943,7 +16125,7 @@ function readJob(text2) {
|
|
|
15943
16125
|
if (failed !== null) {
|
|
15944
16126
|
job.status = "error";
|
|
15945
16127
|
job.sec = seconds(failed[1]);
|
|
15946
|
-
job.trouble = failed[2] ?? "";
|
|
16128
|
+
job.trouble = withoutPaths(failed[2] ?? "");
|
|
15947
16129
|
tail2 = null;
|
|
15948
16130
|
continue;
|
|
15949
16131
|
}
|
|
@@ -15960,15 +16142,20 @@ function readJob(text2) {
|
|
|
15960
16142
|
tail2 = null;
|
|
15961
16143
|
continue;
|
|
15962
16144
|
}
|
|
16145
|
+
const say = SAY.exec(line);
|
|
16146
|
+
if (say !== null) {
|
|
16147
|
+
job.say = say[1] ?? "";
|
|
16148
|
+
continue;
|
|
16149
|
+
}
|
|
15963
16150
|
if (WAITING.test(line)) {
|
|
15964
16151
|
job.status = "waiting";
|
|
15965
16152
|
job.message = line;
|
|
15966
16153
|
continue;
|
|
15967
16154
|
}
|
|
15968
|
-
const
|
|
15969
|
-
if (
|
|
16155
|
+
const running2 = RUNNING.exec(line);
|
|
16156
|
+
if (running2 !== null) {
|
|
15970
16157
|
job.status = "running";
|
|
15971
|
-
job.sec = seconds(
|
|
16158
|
+
job.sec = seconds(running2[1]);
|
|
15972
16159
|
continue;
|
|
15973
16160
|
}
|
|
15974
16161
|
if (tail2 !== null) {
|
|
@@ -15987,6 +16174,9 @@ function readJob(text2) {
|
|
|
15987
16174
|
}
|
|
15988
16175
|
return job;
|
|
15989
16176
|
}
|
|
16177
|
+
function withoutPaths(text2) {
|
|
16178
|
+
return text2.replace(/(^|[\s(«"])(?:[A-Za-z]:\\|~?\/)[^\s,;()«»"]*/g, "$1").replace(/\(\s*\)/g, "").replace(/\s{2,}/g, " ").replace(/\s+([.,;:])/g, "$1").trim();
|
|
16179
|
+
}
|
|
15990
16180
|
function seconds(text2) {
|
|
15991
16181
|
if (text2 === void 0) return 0;
|
|
15992
16182
|
const value = Number(text2.replace(",", "."));
|
|
@@ -16001,6 +16191,8 @@ var FLUSH_EVERY_MS = 6e4;
|
|
|
16001
16191
|
var SEND_TIMEOUT_MS = 3e3;
|
|
16002
16192
|
var JOB_LOG_TAIL = 64 * 1024;
|
|
16003
16193
|
var PYTHON_TRACEBACK = "Traceback (most recent call last):";
|
|
16194
|
+
var SUPPORT_TOPIC = "https://t.me/c/3763431875/10";
|
|
16195
|
+
var WORDS_GRACE_MS = 1e3;
|
|
16004
16196
|
var CrashReporter = class {
|
|
16005
16197
|
#deps;
|
|
16006
16198
|
#now;
|
|
@@ -16039,9 +16231,31 @@ var CrashReporter = class {
|
|
|
16039
16231
|
noteHost(host) {
|
|
16040
16232
|
if (host !== null) this.#host = host;
|
|
16041
16233
|
}
|
|
16042
|
-
/**
|
|
16234
|
+
/**
|
|
16235
|
+
* Отправить отчёт. Ответ инструмента ждёт итог через {@link wordsFor}, а
|
|
16236
|
+
* всё прочее — нет; для тестов и смоука — `settled()`.
|
|
16237
|
+
*/
|
|
16043
16238
|
submit(crash) {
|
|
16044
|
-
this.#
|
|
16239
|
+
const delivery = this.#deliver(crash).catch(() => "none");
|
|
16240
|
+
this.#track(delivery.then(() => void 0));
|
|
16241
|
+
return delivery;
|
|
16242
|
+
}
|
|
16243
|
+
/**
|
|
16244
|
+
* Итог отправки для слов человеку — не дольше таймаута отправки с запасом.
|
|
16245
|
+
* Не успела — отчёт ещё в пути и либо уйдёт, либо ляжет в очередь: «уйдёт»
|
|
16246
|
+
* правда в обоих случаях.
|
|
16247
|
+
*/
|
|
16248
|
+
async outcome(delivery) {
|
|
16249
|
+
let timer;
|
|
16250
|
+
const late = new Promise((done) => {
|
|
16251
|
+
timer = setTimeout(() => done("queued"), (this.#deps.timeoutMs ?? SEND_TIMEOUT_MS) + WORDS_GRACE_MS);
|
|
16252
|
+
timer.unref?.();
|
|
16253
|
+
});
|
|
16254
|
+
try {
|
|
16255
|
+
return await Promise.race([delivery, late]);
|
|
16256
|
+
} finally {
|
|
16257
|
+
clearTimeout(timer);
|
|
16258
|
+
}
|
|
16045
16259
|
}
|
|
16046
16260
|
/**
|
|
16047
16261
|
* Процесс падает: отчёт кладётся на диск СИНХРОННО и уходит на следующем
|
|
@@ -16091,10 +16305,19 @@ var CrashReporter = class {
|
|
|
16091
16305
|
}
|
|
16092
16306
|
async #deliver(crash) {
|
|
16093
16307
|
const report = this.#build(crash);
|
|
16094
|
-
if (report === null) return;
|
|
16308
|
+
if (report === null) return this.#queuedAlready(fingerprintOf2(crash.errorType, crash.frames)) ? "queued" : "sent";
|
|
16095
16309
|
report.versions.ffmpeg = await this.#ffmpegVersion();
|
|
16096
16310
|
const verdict = await this.#send(report);
|
|
16097
|
-
if (verdict === "
|
|
16311
|
+
if (verdict === "sent") return "sent";
|
|
16312
|
+
if (verdict === "drop") return "none";
|
|
16313
|
+
return this.#enqueue(report) ? "queued" : "none";
|
|
16314
|
+
}
|
|
16315
|
+
#queuedAlready(fingerprint) {
|
|
16316
|
+
try {
|
|
16317
|
+
return readdirSync(this.#queueDir()).some((f) => f.endsWith(`-${fingerprint}.json`));
|
|
16318
|
+
} catch {
|
|
16319
|
+
return false;
|
|
16320
|
+
}
|
|
16098
16321
|
}
|
|
16099
16322
|
async #flush() {
|
|
16100
16323
|
const dir = this.#queueDir();
|
|
@@ -16191,6 +16414,7 @@ var CrashReporter = class {
|
|
|
16191
16414
|
recent_calls: recentCalls(this.#deps.home)
|
|
16192
16415
|
};
|
|
16193
16416
|
}
|
|
16417
|
+
/** Положить отчёт в очередь. `false` — диск не принял, отчёт пропал. */
|
|
16194
16418
|
#enqueue(report) {
|
|
16195
16419
|
try {
|
|
16196
16420
|
const dir = this.#queueDir();
|
|
@@ -16203,7 +16427,9 @@ var CrashReporter = class {
|
|
|
16203
16427
|
for (const old of files.slice(0, Math.max(0, files.length - QUEUE_CAP))) {
|
|
16204
16428
|
rmSync(join(dir, old), { force: true });
|
|
16205
16429
|
}
|
|
16430
|
+
return true;
|
|
16206
16431
|
} catch {
|
|
16432
|
+
return false;
|
|
16207
16433
|
}
|
|
16208
16434
|
}
|
|
16209
16435
|
#queueDir() {
|
|
@@ -16252,49 +16478,83 @@ function withCrashReport(crashes) {
|
|
|
16252
16478
|
crashes.noteHost(host);
|
|
16253
16479
|
crashes.noteSecrets(secretsOf(input));
|
|
16254
16480
|
let result;
|
|
16481
|
+
let faults;
|
|
16255
16482
|
try {
|
|
16256
|
-
result = await original(input, ...rest);
|
|
16483
|
+
({ value: result, faults } = await collectInstallFaults(() => original(input, ...rest)));
|
|
16257
16484
|
} catch (trouble) {
|
|
16258
16485
|
const crash = fromThrown(trouble, "tool", tool.name, input, host);
|
|
16259
|
-
crashes.submit(crash);
|
|
16260
|
-
|
|
16486
|
+
return toolError(await brokenWords(crash, crashes, crashes.submit(crash)));
|
|
16487
|
+
}
|
|
16488
|
+
const install2 = firstInstallCrash(faults);
|
|
16489
|
+
if (install2 !== null) {
|
|
16490
|
+
const crash = { ...install2, where: "tool", tool: tool.name, secrets: secretsOf(input), host };
|
|
16491
|
+
return withNotice(result, await brokenWords(crash, crashes, crashes.submit(crash)));
|
|
16261
16492
|
}
|
|
16262
16493
|
return caught(result, tool.name, input, host, crashes);
|
|
16263
16494
|
}
|
|
16264
16495
|
};
|
|
16265
16496
|
};
|
|
16266
16497
|
}
|
|
16267
|
-
function
|
|
16498
|
+
async function reportInstallFaults(crashes, work) {
|
|
16499
|
+
const { value, faults } = await collectInstallFaults(work);
|
|
16500
|
+
const install2 = firstInstallCrash(faults);
|
|
16501
|
+
if (install2 !== null) {
|
|
16502
|
+
void crashes.submit({ ...install2, stage: `${install2.stage ?? ""} (\u0444\u043E\u043D\u043E\u043C \u043D\u0430 \u0441\u0442\u0430\u0440\u0442\u0435)`, where: "tool", tool: null, secrets: [], host: null });
|
|
16503
|
+
}
|
|
16504
|
+
return value;
|
|
16505
|
+
}
|
|
16506
|
+
function firstInstallCrash(faults) {
|
|
16507
|
+
for (const fault of faults) {
|
|
16508
|
+
const parsed = installCrash(fault);
|
|
16509
|
+
if (parsed !== null) return parsed;
|
|
16510
|
+
}
|
|
16511
|
+
return null;
|
|
16512
|
+
}
|
|
16513
|
+
function withNotice(result, notice) {
|
|
16514
|
+
if (result.type === "error") return { ...result, error: `${result.error}
|
|
16515
|
+
|
|
16516
|
+
${notice}` };
|
|
16517
|
+
return typeof result.content === "string" ? { ...result, content: `${result.content}
|
|
16518
|
+
|
|
16519
|
+
${notice}` } : { ...result, content: [...result.content, { type: "text", text: notice }] };
|
|
16520
|
+
}
|
|
16521
|
+
async function caught(result, name, input, host, crashes) {
|
|
16268
16522
|
if (result.type === "error") {
|
|
16269
16523
|
const parsed2 = pythonCrash(result.error);
|
|
16270
16524
|
if (parsed2 === null) return result;
|
|
16271
16525
|
const crash2 = { ...parsed2, where: "tool", tool: name, stage: null, secrets: secretsOf(input), host };
|
|
16272
|
-
crashes.submit(crash2);
|
|
16273
|
-
return toolError(brokenWords(crash2, crashes));
|
|
16526
|
+
return toolError(await brokenWords(crash2, crashes, crashes.submit(crash2)));
|
|
16274
16527
|
}
|
|
16275
16528
|
const job = result.structured;
|
|
16276
16529
|
if (job === void 0 || job["contract"] !== JOB_CONTRACT || job["status"] !== "error") return result;
|
|
16277
16530
|
const id = typeof job["id"] === "string" ? job["id"] : "";
|
|
16278
16531
|
if (!/^[\w.-]{1,80}$/.test(id) || crashes.jobSeen(id)) return result;
|
|
16279
|
-
const
|
|
16532
|
+
const fromLog = pythonCrash(jobLogTail(crashes.home, id));
|
|
16533
|
+
const install2 = fromLog === null ? firstInstallCrash(jobInstallFaults(id)) : null;
|
|
16534
|
+
const parsed = fromLog ?? install2;
|
|
16280
16535
|
if (parsed === null) return result;
|
|
16281
16536
|
crashes.rememberJob(id);
|
|
16282
|
-
const stage = typeof job["now"] === "string" && job["now"] !== "" ? job["now"] : null;
|
|
16537
|
+
const stage = install2?.stage ?? (typeof job["now"] === "string" && job["now"] !== "" ? job["now"] : null);
|
|
16283
16538
|
const crash = { ...parsed, where: "job", tool: name, stage, secrets: secretsOf(input), host };
|
|
16284
|
-
crashes.submit(crash);
|
|
16285
|
-
const notice = `
|
|
16286
|
-
|
|
16287
|
-
${brokenWords(crash, crashes)}`;
|
|
16288
|
-
return typeof result.content === "string" ? { ...result, content: result.content + notice } : { ...result, content: [...result.content, { type: "text", text: notice.trim() }] };
|
|
16539
|
+
return withNotice(result, await brokenWords(crash, crashes, crashes.submit(crash)));
|
|
16289
16540
|
}
|
|
16290
|
-
function brokenWords(crash, crashes) {
|
|
16541
|
+
async function brokenWords(crash, crashes, delivery) {
|
|
16291
16542
|
const essence = head(scrub(head(crash.essence, 600), crashes.scrubContext(crash.secrets)), 300);
|
|
16543
|
+
const fate = crashes.canSend ? await crashes.outcome(delivery) : "none";
|
|
16292
16544
|
return [
|
|
16293
|
-
|
|
16294
|
-
crashes.canSend ? `\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0441\u043A\u0430\u0436\u0438, \u0447\u0442\u043E \u0442\u0435\u0445\u043D\u0438\u0447\u0435\u0441\u043A\u0438\u0439 \u043E\u0442\u0447\u0451\u0442 \u0443\u0445\u043E\u0434\u0438\u0442 \u043D\u0430\u043C \u0441\u0430\u043C \u0438 \u0440\u0430\u0441\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0442\u044C \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043D\u0443\u0436\u043D\u043E, \u0438 \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439 \u0435\u0449\u0451 \u0440\u0430\u0437. \u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0441\u044F \u2014 \u043F\u0443\u0441\u0442\u044C \u043D\u0430\u043F\u0438\u0448\u0435\u0442 \u043D\u0430\u043C \u0432 \u0431\u043E\u0442 ${KEY_SOURCE_BOT}.` : `\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u043F\u0440\u043E\u0431\u0443\u0439 \u0435\u0449\u0451 \u0440\u0430\u0437. \u041F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0441\u044F \u2014 \u043F\u0443\u0441\u0442\u044C \u043D\u0430\u043F\u0438\u0448\u0435\u0442 \u043D\u0430\u043C \u0432 \u0431\u043E\u0442 ${KEY_SOURCE_BOT}.`,
|
|
16545
|
+
`\u0421\u043A\u0430\u0436\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u0442\u0430\u043A, \u0441\u0432\u043E\u0438\u043C\u0438 \u0441\u043B\u043E\u0432\u0430\u043C\u0438 \u043D\u0435 \u043C\u0435\u043D\u044F\u0439: \xAB${humanWords(fate)}\xBB`,
|
|
16295
16546
|
`\u0421\u0443\u0442\u044C \u0434\u043B\u044F \u0442\u0435\u0431\u044F, \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u043D\u0435 \u0437\u0430\u0447\u0438\u0442\u044B\u0432\u0430\u0439: ${essence}`
|
|
16296
16547
|
].join("\n");
|
|
16297
16548
|
}
|
|
16549
|
+
function humanWords(fate) {
|
|
16550
|
+
if (fate === "sent") {
|
|
16551
|
+
return `\u041F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430. \u041E\u0442\u0447\u0451\u0442 \u0443\u0436\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u0430\u043C \u2014 \u043C\u044B \u0435\u0451 \u0438\u0441\u043F\u0440\u0430\u0432\u0438\u043C. \u0415\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u043E \u0441\u0440\u043E\u0447\u043D\u043E \u2014 \u043D\u0430\u043F\u0438\u0448\u0438 \u043D\u0430\u043C: ${SUPPORT_TOPIC}`;
|
|
16552
|
+
}
|
|
16553
|
+
if (fate === "queued") {
|
|
16554
|
+
return `\u041F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430. \u041E\u0442\u0447\u0451\u0442 \u0441\u043E\u0445\u0440\u0430\u043D\u0451\u043D \u0438 \u0443\u0439\u0434\u0451\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u0430\u043C, \u043A\u0430\u043A \u043F\u043E\u044F\u0432\u0438\u0442\u0441\u044F \u0441\u0432\u044F\u0437\u044C, \u2014 \u043C\u044B \u0435\u0451 \u0438\u0441\u043F\u0440\u0430\u0432\u0438\u043C. \u0415\u0441\u043B\u0438 \u043D\u0443\u0436\u043D\u043E \u0441\u0440\u043E\u0447\u043D\u043E \u2014 \u043D\u0430\u043F\u0438\u0448\u0438 \u043D\u0430\u043C: ${SUPPORT_TOPIC}`;
|
|
16555
|
+
}
|
|
16556
|
+
return `\u041F\u0440\u043E\u0438\u0437\u043E\u0448\u043B\u0430 \u043E\u0448\u0438\u0431\u043A\u0430. \u041D\u0430\u043F\u0438\u0448\u0438 \u043D\u0430\u043C, \u043C\u044B \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043C\u0441\u044F: ${SUPPORT_TOPIC}`;
|
|
16557
|
+
}
|
|
16298
16558
|
function watchProcessCrashes(crashes, proc = process, exit = (code) => process.exit(code)) {
|
|
16299
16559
|
const fall = (trouble) => {
|
|
16300
16560
|
crashes.persist(fromThrown(trouble, "process", null, {}, null));
|
|
@@ -16329,6 +16589,95 @@ function fromThrown(trouble, where, tool, input, host) {
|
|
|
16329
16589
|
essence: `${errorType}: ${error40.message}${frames[0] ? ` \u2014 ${frames[0].file}` : ""}`
|
|
16330
16590
|
};
|
|
16331
16591
|
}
|
|
16592
|
+
function installCrash(fault) {
|
|
16593
|
+
const { stage, trouble } = fault;
|
|
16594
|
+
if (machineCause(trouble)) return null;
|
|
16595
|
+
const said = commandOutput(trouble);
|
|
16596
|
+
if (said.includes(PYTHON_TRACEBACK)) {
|
|
16597
|
+
const parsed = pythonCrash(said);
|
|
16598
|
+
return parsed === null ? null : { ...parsed, stage };
|
|
16599
|
+
}
|
|
16600
|
+
const error40 = trouble instanceof Error ? trouble : new Error(String(trouble));
|
|
16601
|
+
const reason = lastMeaningfulLine(said) ?? lastMeaningfulLine(error40.message) ?? error40.name;
|
|
16602
|
+
const command = typeof trouble.cmd === "string" ? trouble.cmd : "";
|
|
16603
|
+
const trace = [
|
|
16604
|
+
command === "" ? "" : `\u043A\u043E\u043C\u0430\u043D\u0434\u0430: ${command}`,
|
|
16605
|
+
said.trim() === "" ? "" : `\u0432\u044B\u0432\u043E\u0434 \u043A\u043E\u043C\u0430\u043D\u0434\u044B:
|
|
16606
|
+
${said.trim().slice(-4e3)}`,
|
|
16607
|
+
error40.stack ?? `${error40.name}: ${error40.message}`
|
|
16608
|
+
].filter((part) => part !== "").join("\n\n");
|
|
16609
|
+
return {
|
|
16610
|
+
stage,
|
|
16611
|
+
errorType: "InstallError",
|
|
16612
|
+
message: `${stage}: ${reason}`,
|
|
16613
|
+
trace,
|
|
16614
|
+
keep: "head",
|
|
16615
|
+
// ⚠ ПРИЧИНА В ОТПЕЧАТКЕ — БЕЗ ПУТЕЙ И ЧИСЕЛ. Иначе все беды шага склеились
|
|
16616
|
+
// бы в один отпечаток, а сервер пишет в бот про отпечаток раз в час: вторая,
|
|
16617
|
+
// другая беда того же шага промолчала бы. А с путями и версиями одна и та
|
|
16618
|
+
// же беда у двух покупателей считалась бы двумя.
|
|
16619
|
+
frames: [`install:${stage}`, reason.replace(/(?:[A-Za-z]:)?[\\/][^\s'"]*/g, "<path>").replace(/\d+/g, "0").slice(0, 160)],
|
|
16620
|
+
python: /python@?(\d)\.(\d{1,2})\b/i.exec(command)?.slice(1, 3).join(".") ?? null,
|
|
16621
|
+
essence: `\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430, \u0448\u0430\u0433 ${stage}: ${reason}`
|
|
16622
|
+
};
|
|
16623
|
+
}
|
|
16624
|
+
function machineCause(trouble) {
|
|
16625
|
+
const t = trouble ?? {};
|
|
16626
|
+
if (typeof t.code === "string" && MACHINE_CODES.has(t.code)) return true;
|
|
16627
|
+
if (t.code === 2) return true;
|
|
16628
|
+
if (t.killed === true || typeof t.signal === "string" && t.signal !== "") return true;
|
|
16629
|
+
const text2 = `${typeof t.message === "string" ? t.message : String(trouble)}
|
|
16630
|
+
${commandOutput(trouble)}`;
|
|
16631
|
+
return MACHINE_WORDS.test(text2);
|
|
16632
|
+
}
|
|
16633
|
+
var MACHINE_CODES = /* @__PURE__ */ new Set([
|
|
16634
|
+
"ENOSPC",
|
|
16635
|
+
"EDQUOT",
|
|
16636
|
+
"EACCES",
|
|
16637
|
+
"EPERM",
|
|
16638
|
+
"EROFS",
|
|
16639
|
+
"EBUSY",
|
|
16640
|
+
"ENOTFOUND",
|
|
16641
|
+
"EAI_AGAIN",
|
|
16642
|
+
"ECONNRESET",
|
|
16643
|
+
"ECONNREFUSED",
|
|
16644
|
+
"ETIMEDOUT",
|
|
16645
|
+
"ENETUNREACH",
|
|
16646
|
+
"ENETDOWN",
|
|
16647
|
+
"EHOSTUNREACH"
|
|
16648
|
+
]);
|
|
16649
|
+
var MACHINE_WORDS = new RegExp([
|
|
16650
|
+
"No space left on device",
|
|
16651
|
+
"Disk quota exceeded",
|
|
16652
|
+
"Permission denied",
|
|
16653
|
+
"Operation not permitted",
|
|
16654
|
+
"Read-only file system",
|
|
16655
|
+
"Access is denied",
|
|
16656
|
+
"Temporary failure in name resolution",
|
|
16657
|
+
"Name or service not known",
|
|
16658
|
+
"nodename nor servname",
|
|
16659
|
+
"getaddrinfo",
|
|
16660
|
+
"Network is unreachable",
|
|
16661
|
+
"No route to host",
|
|
16662
|
+
"Connection refused",
|
|
16663
|
+
"Connection reset",
|
|
16664
|
+
"Connection aborted",
|
|
16665
|
+
"timed out",
|
|
16666
|
+
"Max retries exceeded",
|
|
16667
|
+
"NewConnectionError",
|
|
16668
|
+
"ConnectTimeoutError",
|
|
16669
|
+
"ReadTimeoutError",
|
|
16670
|
+
"ProxyError",
|
|
16671
|
+
"CERTIFICATE_VERIFY_FAILED"
|
|
16672
|
+
].map((one) => one.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|"), "i");
|
|
16673
|
+
function commandOutput(trouble) {
|
|
16674
|
+
const t = trouble ?? {};
|
|
16675
|
+
return [t.stderr, t.stdout].filter((one) => typeof one === "string" && one.trim() !== "").join("\n");
|
|
16676
|
+
}
|
|
16677
|
+
function lastMeaningfulLine(text2) {
|
|
16678
|
+
const lines = text2.split("\n").map((one) => one.trim()).filter((one) => one !== "" && !/^Command failed:/.test(one));
|
|
16679
|
+
return lines[lines.length - 1] ?? null;
|
|
16680
|
+
}
|
|
16332
16681
|
function jsFrames(stack) {
|
|
16333
16682
|
const frames = [];
|
|
16334
16683
|
for (const line of stack.split("\n")) {
|
|
@@ -16526,7 +16875,6 @@ function readReadiness(stdout) {
|
|
|
16526
16875
|
var NOT_A_ROW = /* @__PURE__ */ new Set(["system"]);
|
|
16527
16876
|
var TITLE_READY = "\u0412\u0441\u0451 \u0433\u043E\u0442\u043E\u0432\u043E \u2014 \u043C\u043E\u0436\u043D\u043E \u043D\u0430\u0447\u0438\u043D\u0430\u0442\u044C \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C :)";
|
|
16528
16877
|
var TITLE_UNKNOWN = "\u041F\u0440\u043E\u0432\u0435\u0440\u044F\u044E, \u0447\u0442\u043E \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E";
|
|
16529
|
-
var TITLE_UPDATING = "\u041E\u0431\u043D\u043E\u0432\u043B\u044F\u044E \u043C\u043E\u043D\u0442\u0430\u0436";
|
|
16530
16878
|
function weight(mb) {
|
|
16531
16879
|
if (mb >= 1e3) return `${(mb / 1024).toFixed(1).replace(".", ",")} \u0413\u0411`;
|
|
16532
16880
|
return `${mb} \u041C\u0411`;
|
|
@@ -16547,11 +16895,23 @@ function refusalWords(status) {
|
|
|
16547
16895
|
if (status === 403) return `\u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u0437\u0430\u043A\u043E\u043D\u0447\u0438\u043B\u0430\u0441\u044C. \u041F\u0440\u043E\u0434\u043B\u0438 \u0435\u0451 \u0432 \u0442\u0435\u043B\u0435\u0433\u0440\u0430\u043C-\u0431\u043E\u0442\u0435 ${KEY_SOURCE_HANDLE}.`;
|
|
16548
16896
|
return "";
|
|
16549
16897
|
}
|
|
16898
|
+
function exactWeight(mb) {
|
|
16899
|
+
if (mb >= 1e3) return weight(mb);
|
|
16900
|
+
return `${mb.toFixed(1).replace(".", ",")} \u041C\u0411`;
|
|
16901
|
+
}
|
|
16902
|
+
function whatIsNew(shell, engine) {
|
|
16903
|
+
const parts = [];
|
|
16904
|
+
for (const [news, name] of [[engine, "\u0434\u0432\u0438\u0436\u043E\u043A"], [shell, "\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435"]]) {
|
|
16905
|
+
if (!news?.fresh) continue;
|
|
16906
|
+
parts.push(news.mb > 0 ? `${name} \xB7 ${exactWeight(news.mb)}` : name);
|
|
16907
|
+
}
|
|
16908
|
+
return parts.join(" \u0438 ");
|
|
16909
|
+
}
|
|
16550
16910
|
function updateWords(shell, engine) {
|
|
16551
16911
|
if (!shell?.fresh && !engine?.fresh) return "";
|
|
16552
16912
|
const notes = shell?.fresh ? firstPhrase(shell.notes) : "";
|
|
16553
16913
|
return [
|
|
16554
|
-
`\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0451\u0440\u0430.${notes ? ` \u041F\u043E\u044F\u0432\u0438\u043B\u043E\u0441\u044C: ${notes}` : ""}`,
|
|
16914
|
+
`\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0451\u0440\u0430: ${whatIsNew(shell, engine)}.${notes ? ` \u041F\u043E\u044F\u0432\u0438\u043B\u043E\u0441\u044C: ${notes}` : ""}`,
|
|
16555
16915
|
"\u041E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0434\u043E \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438?",
|
|
16556
16916
|
"\u041F\u0440\u043E\u0441\u0442\u043E \u043D\u0430\u043F\u0438\u0448\u0438 \xAB\u043E\u0431\u043D\u043E\u0432\u0438\xBB."
|
|
16557
16917
|
].join("\n");
|
|
@@ -17370,10 +17730,19 @@ function runbarWidgetHtml() {
|
|
|
17370
17730
|
document.body.classList.remove('bad');
|
|
17371
17731
|
if (!good) document.body.classList.add('bad');
|
|
17372
17732
|
|
|
17373
|
-
if (good) {
|
|
17733
|
+
if (good && data.file) {
|
|
17374
17734
|
show('endTitle', '\u0413\u043E\u0442\u043E\u0432\u043E \u0437\u0430 ' + howLong(data.sec));
|
|
17375
|
-
show('endHint',
|
|
17376
|
-
show('path', data.file
|
|
17735
|
+
show('endHint', '\u0420\u043E\u043B\u0438\u043A \u0433\u043E\u0442\u043E\u0432:');
|
|
17736
|
+
show('path', data.file);
|
|
17737
|
+
} else if (good) {
|
|
17738
|
+
// \u26A0 \u0423 \u0420\u0410\u0411\u041E\u0422\u042B \u0411\u0415\u0417 \u0424\u0410\u0419\u041B\u0410 \u2014 \u0424\u0420\u0410\u0417\u0410, \u0410 \u041D\u0415 \u041E\u0422\u0427\u0401\u0422 (\u0432\u043B\u0430\u0434\u0435\u043B\u0435\u0446 2026-09-24). \u041E\u0442\u0447\u0451\u0442
|
|
17739
|
+
// \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438 \u2014 \u0441\u0442\u0440\u043E\u043A\u0438 \u0434\u0432\u0438\u0436\u043A\u0430 \u0441 \u043F\u0443\u0442\u044F\u043C\u0438 \u0438 \u0438\u043C\u0435\u043D\u0430\u043C\u0438 \u0448\u0430\u0433\u043E\u0432, \u043E\u043D \u0434\u043B\u044F \u043C\u043E\u0434\u0435\u043B\u0438.
|
|
17740
|
+
// \xAB\u0413\u043E\u0442\u043E\u0432\u043E. \u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438 Claude \u2014 \u2026\xBB \u0434\u0435\u043B\u0438\u0442\u0441\u044F \u043D\u0430 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A \u0438 \u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0443.
|
|
17741
|
+
var say = data.say || '\u0413\u043E\u0442\u043E\u0432\u043E \u2014 \u043C\u043E\u0436\u043D\u043E \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C.';
|
|
17742
|
+
var cut = /^(.+?)[.!]\\s+(.+)$/.exec(say);
|
|
17743
|
+
show('endTitle', cut ? cut[1] : say.replace(/[.]$/, ''));
|
|
17744
|
+
show('endHint', cut ? cut[2] : '');
|
|
17745
|
+
show('path', '');
|
|
17377
17746
|
} else {
|
|
17378
17747
|
show('endTitle', data.status === 'aborted' ? '\u0420\u0430\u0431\u043E\u0442\u0430 \u043F\u0440\u0435\u0440\u0432\u0430\u043B\u0430\u0441\u044C' : '\u041D\u0435 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u043E\u0441\u044C');
|
|
17379
17748
|
show('endHint', data.trouble || '\u0427\u0442\u043E-\u0442\u043E \u0441\u043B\u043E\u043C\u0430\u043B\u043E\u0441\u044C. \u041D\u0430\u043F\u0438\u0448\u0438 \u041A\u043B\u043E\u0434\u0443 \xAB\u0447\u0442\u043E \u0441\u043B\u0443\u0447\u0438\u043B\u043E\u0441\u044C\xBB.');
|
|
@@ -17723,6 +18092,226 @@ function nameOrRefusal(candidate) {
|
|
|
17723
18092
|
};
|
|
17724
18093
|
}
|
|
17725
18094
|
|
|
18095
|
+
// src/setup-job.ts
|
|
18096
|
+
var SETUP_JOB_MARK = "setup-";
|
|
18097
|
+
function isSetupJob(id) {
|
|
18098
|
+
return id.startsWith(SETUP_JOB_MARK);
|
|
18099
|
+
}
|
|
18100
|
+
var TITLE_UPDATE = "\u041E\u0431\u043D\u043E\u0432\u043B\u044F\u044E \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430";
|
|
18101
|
+
var TITLE_INSTALL = "\u0423\u0441\u0442\u0430\u043D\u0430\u0432\u043B\u0438\u0432\u0430\u044E \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430";
|
|
18102
|
+
var SAY_RESTART = "\u0413\u043E\u0442\u043E\u0432\u043E. \u041F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438 Claude \u2014 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0437\u0430\u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043F\u043E\u0441\u043B\u0435 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0430.";
|
|
18103
|
+
var SAY_NOTHING = "\u0412\u0441\u0451 \u0443\u0436\u0435 \u0441\u0442\u043E\u0438\u0442 \u2014 \u043C\u043E\u0436\u043D\u043E \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C.";
|
|
18104
|
+
var SAY_INSTALLED = "\u0413\u043E\u0442\u043E\u0432\u043E \u2014 \u043C\u043E\u0436\u043D\u043E \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C.";
|
|
18105
|
+
var ADVICE_ASK = "\u041D\u0430\u043F\u0438\u0448\u0438 \u041A\u043B\u043E\u0434\u0443 \xAB\u0447\u0442\u043E \u0441\u043B\u0443\u0447\u0438\u043B\u043E\u0441\u044C\xBB \u2014 \u043E\u043D \u0440\u0430\u0441\u0441\u043A\u0430\u0436\u0435\u0442, \u0447\u0442\u043E \u043F\u043E\u0448\u043B\u043E \u043D\u0435 \u0442\u0430\u043A.";
|
|
18106
|
+
var CHECK = "\u041F\u0440\u043E\u0432\u0435\u0440\u044F\u044E, \u0447\u0442\u043E \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C";
|
|
18107
|
+
var INSTALL_NEW = "\u0421\u0442\u0430\u0432\u043B\u044E \u043D\u043E\u0432\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E";
|
|
18108
|
+
var MISSING = "\u0421\u0442\u0430\u0432\u043B\u044E \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u044E\u0449\u0435\u0435";
|
|
18109
|
+
var works = /* @__PURE__ */ new Map();
|
|
18110
|
+
function running() {
|
|
18111
|
+
for (const work of works.values()) if (work.ended === null) return work;
|
|
18112
|
+
return null;
|
|
18113
|
+
}
|
|
18114
|
+
function startSetupJob(what, run, clock = Date.now) {
|
|
18115
|
+
const already = running();
|
|
18116
|
+
if (already !== null) return already.id;
|
|
18117
|
+
const started = clock();
|
|
18118
|
+
const id = `${SETUP_JOB_MARK}${new Date(started).toISOString().replace(/[:.]/g, "-")}`;
|
|
18119
|
+
const work = {
|
|
18120
|
+
id,
|
|
18121
|
+
what,
|
|
18122
|
+
started,
|
|
18123
|
+
stages: [CHECK],
|
|
18124
|
+
at: 1,
|
|
18125
|
+
message: "",
|
|
18126
|
+
ended: null,
|
|
18127
|
+
done: Promise.resolve()
|
|
18128
|
+
};
|
|
18129
|
+
const control = {
|
|
18130
|
+
plan(stages) {
|
|
18131
|
+
work.stages = stages;
|
|
18132
|
+
work.at = Math.min(work.at, stages.length);
|
|
18133
|
+
},
|
|
18134
|
+
go(stage) {
|
|
18135
|
+
const index = work.stages.indexOf(stage);
|
|
18136
|
+
if (index >= 0) work.at = index + 1;
|
|
18137
|
+
work.message = "";
|
|
18138
|
+
},
|
|
18139
|
+
line(text2) {
|
|
18140
|
+
work.message = text2;
|
|
18141
|
+
}
|
|
18142
|
+
};
|
|
18143
|
+
works.set(id, work);
|
|
18144
|
+
work.done = collectJobInstallFaults(id, () => run(control).catch((trouble) => {
|
|
18145
|
+
noteInstallFault("update-job", trouble);
|
|
18146
|
+
return {
|
|
18147
|
+
ok: false,
|
|
18148
|
+
trouble: "\u0427\u0442\u043E-\u0442\u043E \u0441\u043B\u043E\u043C\u0430\u043B\u043E\u0441\u044C \u043F\u043E\u0441\u0440\u0435\u0434\u0438 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u2014 \u043F\u0440\u0435\u0436\u043D\u044F\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u043D\u0430 \u043C\u0435\u0441\u0442\u0435, \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043C\u043E\u0436\u043D\u043E.",
|
|
18149
|
+
advice: ADVICE_ASK,
|
|
18150
|
+
report: String(trouble instanceof Error ? trouble.message : trouble)
|
|
18151
|
+
};
|
|
18152
|
+
})).then((ending) => {
|
|
18153
|
+
work.ended = { at: clock(), ending };
|
|
18154
|
+
});
|
|
18155
|
+
return id;
|
|
18156
|
+
}
|
|
18157
|
+
function quiet(line) {
|
|
18158
|
+
return line.replace(/^⚠\s*/, "").replace(/^Что делать:/, "\u0421\u043E\u0432\u0435\u0442:");
|
|
18159
|
+
}
|
|
18160
|
+
function setupJobText(id, clock = Date.now) {
|
|
18161
|
+
const work = works.get(id);
|
|
18162
|
+
if (work === void 0) return null;
|
|
18163
|
+
const head2 = `\u0417\u0430\u0434\u0430\u043D\u0438\u0435 ${work.id}: ${work.what}`;
|
|
18164
|
+
if (work.ended === null) {
|
|
18165
|
+
const sec2 = Math.max(0, Math.round((clock() - work.started) / 1e3));
|
|
18166
|
+
return [
|
|
18167
|
+
head2,
|
|
18168
|
+
`\u042D\u0442\u0430\u043F ${work.at} \u0438\u0437 ${work.stages.length}: ${work.stages[work.at - 1] ?? CHECK}`,
|
|
18169
|
+
...work.message === "" ? [] : [work.message],
|
|
18170
|
+
`\u0415\u0449\u0451 \u0441\u0447\u0438\u0442\u0430\u0435\u0442, ${sec2} \u0441.`
|
|
18171
|
+
].join("\n");
|
|
18172
|
+
}
|
|
18173
|
+
const sec = Math.max(0, Math.round((work.ended.at - work.started) / 1e3));
|
|
18174
|
+
const ending = work.ended.ending;
|
|
18175
|
+
const report = ending.report.split("\n").map((line) => line.trim()).filter((line) => line !== "").map(quiet);
|
|
18176
|
+
if (ending.ok) {
|
|
18177
|
+
return [head2, `\u0413\u043E\u0442\u043E\u0432\u043E \u0437\u0430 ${sec} \u0441.`, `\u0427\u0435\u043B\u043E\u0432\u0435\u043A\u0443: ${ending.say}`, ...report].join("\n");
|
|
18178
|
+
}
|
|
18179
|
+
return [
|
|
18180
|
+
head2,
|
|
18181
|
+
...report,
|
|
18182
|
+
`\u041D\u0435 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u043E\u0441\u044C \u0437\u0430 ${sec} \u0441: ${ending.trouble}`,
|
|
18183
|
+
`\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: ${ending.advice}`
|
|
18184
|
+
].join("\n");
|
|
18185
|
+
}
|
|
18186
|
+
function setupJobReport(id) {
|
|
18187
|
+
const text2 = setupJobText(id);
|
|
18188
|
+
return text2 === null ? null : readJob(text2);
|
|
18189
|
+
}
|
|
18190
|
+
function weightExact(bytes) {
|
|
18191
|
+
const mb = bytes / 1024 / 1024;
|
|
18192
|
+
if (mb >= 1e3) return `${(mb / 1024).toFixed(1).replace(".", ",")} \u0413\u0411`;
|
|
18193
|
+
return `${mb.toFixed(1).replace(".", ",")} \u041C\u0411`;
|
|
18194
|
+
}
|
|
18195
|
+
async function runUpdate(job, deps) {
|
|
18196
|
+
const { engine, key, baseUrl, what } = deps;
|
|
18197
|
+
const home = engine.home();
|
|
18198
|
+
const wantShell = what !== "engine";
|
|
18199
|
+
const hasEngine = engine.place() !== null;
|
|
18200
|
+
const wantEngine = what !== "shell" && hasEngine && !engine.pathSetByHand();
|
|
18201
|
+
const shellUrl = engine.variable("NAPARNIK_BUNDLE_MANIFEST") ?? bundleUrlFor(baseUrl);
|
|
18202
|
+
const [shellAsk, engineAsk] = await Promise.all([
|
|
18203
|
+
wantShell ? fetchShellManifest(shellUrl, deps.pointerMs, key) : Promise.resolve(null),
|
|
18204
|
+
wantEngine ? fetchManifest(manifestUrl(engine, baseUrl), deps.pointerMs, key) : Promise.resolve(null)
|
|
18205
|
+
]);
|
|
18206
|
+
const shellWas = installedShell(home);
|
|
18207
|
+
const shell = decideShell(shellWas, shellAsk?.ok === true ? shellAsk.manifest : null);
|
|
18208
|
+
const engineWas = engine.freshVersion();
|
|
18209
|
+
const fresh = decide(engineWas, engineAsk?.ok === true ? engineAsk.manifest : null);
|
|
18210
|
+
const shellStage = shell.what === "newer_available" ? `\u0421\u043A\u0430\u0447\u0438\u0432\u0430\u044E \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 \xB7 ${weightExact(shell.manifest.body?.bytes ?? 0)}` : null;
|
|
18211
|
+
const engineStage = fresh.what === "newer_available" ? `\u0421\u043A\u0430\u0447\u0438\u0432\u0430\u044E \u0434\u0432\u0438\u0436\u043E\u043A \xB7 ${weightExact(fresh.manifest.bytes)}` : null;
|
|
18212
|
+
const missing = what === "all" && engineStage === null;
|
|
18213
|
+
job.plan([
|
|
18214
|
+
CHECK,
|
|
18215
|
+
...shellStage === null ? [] : [shellStage],
|
|
18216
|
+
...engineStage === null ? [] : [engineStage, INSTALL_NEW],
|
|
18217
|
+
...missing ? [MISSING] : []
|
|
18218
|
+
]);
|
|
18219
|
+
const steps = [];
|
|
18220
|
+
let updated = false;
|
|
18221
|
+
let installed = false;
|
|
18222
|
+
for (const [ask2, whose] of [[shellAsk, "\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F"], [engineAsk, "\u0434\u0432\u0438\u0436\u043A\u0430"]]) {
|
|
18223
|
+
if (ask2 === null || ask2.ok) continue;
|
|
18224
|
+
const refusal = refusalWords(ask2.status ?? 0);
|
|
18225
|
+
steps.push({
|
|
18226
|
+
report: `\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043F\u0440\u043E\u0441\u0438\u0442\u044C, \u0435\u0441\u0442\u044C \u043B\u0438 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F ${whose}: ${ask2.why}.`,
|
|
18227
|
+
trouble: refusal !== "" ? refusal : "\u041D\u0435 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u043E\u0441\u044C \u0441\u0432\u044F\u0437\u0430\u0442\u044C\u0441\u044F \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043E\u043C \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0439."
|
|
18228
|
+
});
|
|
18229
|
+
}
|
|
18230
|
+
if (shellAsk?.ok === true && shell.what === "nothing") {
|
|
18231
|
+
steps.push({ report: `\u0423 \u0432\u0430\u0441 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430 \u0441\u0430\u043C\u0430\u044F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u2014 ${shellWas}.` });
|
|
18232
|
+
}
|
|
18233
|
+
if (shell.what === "launcher_too_old") {
|
|
18234
|
+
steps.push({
|
|
18235
|
+
report: `\u041D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F ${shell.manifest.version} \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043D\u043E\u0432\u043E\u0433\u043E \u0444\u0430\u0439\u043B\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F.`,
|
|
18236
|
+
trouble: `\u0414\u043B\u044F \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043D\u0443\u0436\u0435\u043D \u043D\u043E\u0432\u044B\u0439 \u0444\u0430\u0439\u043B \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F. \u0412\u043E\u0437\u044C\u043C\u0438 \u0435\u0433\u043E \u0432 \u0442\u0435\u043B\u0435\u0433\u0440\u0430\u043C-\u0431\u043E\u0442\u0435 ${KEY_SOURCE_BOT}.`
|
|
18237
|
+
});
|
|
18238
|
+
}
|
|
18239
|
+
if (fresh.what === "shell_too_old") {
|
|
18240
|
+
steps.push({
|
|
18241
|
+
report: `\u041D\u043E\u0432\u0430\u044F \u043D\u0430\u0447\u0438\u043D\u043A\u0430 ${fresh.manifest.version} \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u043D\u0435 \u0441\u0442\u0430\u0440\u0448\u0435 ${fresh.manifest.minShellVersion}.`,
|
|
18242
|
+
trouble: "\u041D\u043E\u0432\u043E\u043C\u0443 \u0434\u0432\u0438\u0436\u043A\u0443 \u043D\u0443\u0436\u043D\u043E \u043D\u043E\u0432\u043E\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 \u2014 \u0435\u0433\u043E \u043F\u043E\u043A\u0430 \u043D\u0435\u0442 \u043D\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435."
|
|
18243
|
+
});
|
|
18244
|
+
}
|
|
18245
|
+
if (shell.what === "newer_available" && shellStage !== null) {
|
|
18246
|
+
job.go(shellStage);
|
|
18247
|
+
const outcome = await installShell({ home, manifest: shell.manifest, key: key ?? null });
|
|
18248
|
+
if (outcome.ok) {
|
|
18249
|
+
updated = true;
|
|
18250
|
+
steps.push({ report: outcome.text });
|
|
18251
|
+
} else {
|
|
18252
|
+
steps.push({ report: outcome.text, trouble: "\u041D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u043D\u0435 \u0432\u0441\u0442\u0430\u043B\u0430 \u2014 \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043F\u0440\u0435\u0436\u043D\u044F\u044F." });
|
|
18253
|
+
}
|
|
18254
|
+
}
|
|
18255
|
+
if (fresh.what === "newer_available" && engineStage !== null) {
|
|
18256
|
+
job.go(engineStage);
|
|
18257
|
+
const outcome = await deploy(engine, fresh.manifest, void 0, key, {
|
|
18258
|
+
line: (text2) => job.line(text2),
|
|
18259
|
+
downloaded: () => {
|
|
18260
|
+
job.go(INSTALL_NEW);
|
|
18261
|
+
job.line("\u0421\u043E\u0431\u0438\u0440\u0430\u044E \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u2014 \u044D\u0442\u043E \u0434\u043E \u043F\u0430\u0440\u044B \u043C\u0438\u043D\u0443\u0442.");
|
|
18262
|
+
}
|
|
18263
|
+
});
|
|
18264
|
+
if (outcome.ok) {
|
|
18265
|
+
updated = true;
|
|
18266
|
+
steps.push({ report: outcome.text });
|
|
18267
|
+
} else {
|
|
18268
|
+
steps.push({
|
|
18269
|
+
report: outcome.text,
|
|
18270
|
+
trouble: `\u041D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0434\u0432\u0438\u0436\u043A\u0430 \u043D\u0435 \u0432\u0441\u0442\u0430\u043B\u0430 \u2014 \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043F\u0440\u0435\u0436\u043D\u044F\u044F${engineWas === null ? "" : ` ${engineWas}`}, \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043C\u043E\u0436\u043D\u043E.`
|
|
18271
|
+
});
|
|
18272
|
+
}
|
|
18273
|
+
}
|
|
18274
|
+
if (missing) {
|
|
18275
|
+
job.go(MISSING);
|
|
18276
|
+
const step = await deliverMissing(job, deps);
|
|
18277
|
+
if (step.trouble === void 0 && step.installed) installed = true;
|
|
18278
|
+
steps.push(step);
|
|
18279
|
+
}
|
|
18280
|
+
const report = steps.map((step) => step.report).join("\n");
|
|
18281
|
+
const trouble = steps.find((step) => step.trouble !== void 0)?.trouble;
|
|
18282
|
+
if (trouble !== void 0) return { ok: false, trouble, advice: ADVICE_ASK, report };
|
|
18283
|
+
if (updated) return { ok: true, say: SAY_RESTART, report };
|
|
18284
|
+
return { ok: true, say: installed ? SAY_INSTALLED : SAY_NOTHING, report };
|
|
18285
|
+
}
|
|
18286
|
+
async function deliverMissing(job, deps) {
|
|
18287
|
+
const answer = await deps.installMissing();
|
|
18288
|
+
if (answer.type === "error") {
|
|
18289
|
+
return { report: answer.error, trouble: "\u041D\u0435 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u043E\u0441\u044C \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u044E\u0449\u0435\u0435.", installed: false };
|
|
18290
|
+
}
|
|
18291
|
+
const words = typeof answer.content === "string" ? answer.content : answer.content.map((block) => block.type === "text" ? block.text : "").join("\n");
|
|
18292
|
+
const id = typeof answer.structured?.["id"] === "string" ? answer.structured["id"] : "";
|
|
18293
|
+
if (id === "") return { report: words, installed: false };
|
|
18294
|
+
const pace = deps.pace ?? realPace;
|
|
18295
|
+
let state = await deps.engine.command(["job", id]);
|
|
18296
|
+
while (state.ok && stillWorking(state.text)) {
|
|
18297
|
+
const now = readJob(state.text);
|
|
18298
|
+
if (now !== null) job.line(now.message !== "" ? now.message : now.now);
|
|
18299
|
+
await pace.rest(POLL_EVERY_MS);
|
|
18300
|
+
state = await deps.engine.command(["job", id]);
|
|
18301
|
+
}
|
|
18302
|
+
const end = state.ok ? readJob(state.text) : null;
|
|
18303
|
+
if (end === null || end.status !== "done") {
|
|
18304
|
+
return {
|
|
18305
|
+
report: `${words}
|
|
18306
|
+
${state.text}`,
|
|
18307
|
+
trouble: end?.trouble !== void 0 && end.trouble !== "" ? end.trouble : "\u041D\u0435 \u043F\u043E\u043B\u0443\u0447\u0438\u043B\u043E\u0441\u044C \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u044E\u0449\u0435\u0435.",
|
|
18308
|
+
installed: false
|
|
18309
|
+
};
|
|
18310
|
+
}
|
|
18311
|
+
return { report: `${words}
|
|
18312
|
+
${state.text}`, installed: true };
|
|
18313
|
+
}
|
|
18314
|
+
|
|
17726
18315
|
// src/setup-tool.ts
|
|
17727
18316
|
var ASKED_POINTER_MS = 15e3;
|
|
17728
18317
|
var NEWS_POINTER_MS = 5e3;
|
|
@@ -17876,6 +18465,9 @@ ${EXTRAS_LATER}`), later]);
|
|
|
17876
18465
|
})
|
|
17877
18466
|
);
|
|
17878
18467
|
}
|
|
18468
|
+
function tenths(bytes) {
|
|
18469
|
+
return Math.round(bytes / 1024 / 1024 * 10) / 10;
|
|
18470
|
+
}
|
|
17879
18471
|
async function updateEngine(engine, consent, key, baseUrl, timeoutMs = ASKED_POINTER_MS, seen = () => {
|
|
17880
18472
|
}) {
|
|
17881
18473
|
if (engine.pathSetByHand()) {
|
|
@@ -17893,7 +18485,7 @@ async function updateEngine(engine, consent, key, baseUrl, timeoutMs = ASKED_POI
|
|
|
17893
18485
|
seen({
|
|
17894
18486
|
installed: engine.freshVersion(),
|
|
17895
18487
|
fresh: decision.what === "nothing" ? null : decision.manifest.version,
|
|
17896
|
-
mb: decision.what === "nothing" ? 0 :
|
|
18488
|
+
mb: decision.what === "nothing" ? 0 : tenths(decision.manifest.bytes),
|
|
17897
18489
|
status: outcome.ok ? 0 : outcome.status ?? 0,
|
|
17898
18490
|
notes: ""
|
|
17899
18491
|
});
|
|
@@ -17928,7 +18520,7 @@ async function updateShell(engine, consent, key, baseUrl, timeoutMs = ASKED_POIN
|
|
|
17928
18520
|
seen({
|
|
17929
18521
|
installed,
|
|
17930
18522
|
fresh: decision.what === "nothing" ? null : decision.manifest.version,
|
|
17931
|
-
mb: decision.what === "nothing" ? 0 :
|
|
18523
|
+
mb: decision.what === "nothing" ? 0 : tenths(decision.manifest.body?.bytes ?? 0),
|
|
17932
18524
|
status: outcome.ok ? 0 : outcome.status ?? 0,
|
|
17933
18525
|
notes: decision.what === "nothing" ? "" : decision.manifest.notes ?? ""
|
|
17934
18526
|
});
|
|
@@ -17939,7 +18531,7 @@ async function updateShell(engine, consent, key, baseUrl, timeoutMs = ASKED_POIN
|
|
|
17939
18531
|
);
|
|
17940
18532
|
}
|
|
17941
18533
|
return toolSuccess(
|
|
17942
|
-
outcome.manifest.body === null ? `\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E ${installed}; \u043D\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 ${outcome.manifest.version}, \u043D\u043E \u0444\u0430\u0439\u043B\u0430 \u0434\u043B\u044F \u0441\u0430\u043C\u043E\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u0442\u0430\u043C \u043F\u043E\u043A\u0430 \u043D\u0435\u0442. \u041D\u0438\u0447\u0435\u0433\u043E \u0434\u0435\u043B\u0430\u0442\u044C \u043D\u0435 \u043D\u0443\u0436\u043D\u043E, \u043E\u043D \u043F\u043E\u044F\u0432\u0438\u0442\u0441\u044F \u0441 \u0431\u043B\u0438\u0436\u0430\u0439\u0448\u0438\u043C \u0432\u044B\u043A\u0430\u0442\u043E\u043C.` : `\
|
|
18534
|
+
outcome.manifest.body === null ? `\u0423\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E ${installed}; \u043D\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 ${outcome.manifest.version}, \u043D\u043E \u0444\u0430\u0439\u043B\u0430 \u0434\u043B\u044F \u0441\u0430\u043C\u043E\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u0442\u0430\u043C \u043F\u043E\u043A\u0430 \u043D\u0435\u0442. \u041D\u0438\u0447\u0435\u0433\u043E \u0434\u0435\u043B\u0430\u0442\u044C \u043D\u0435 \u043D\u0443\u0436\u043D\u043E, \u043E\u043D \u043F\u043E\u044F\u0432\u0438\u0442\u0441\u044F \u0441 \u0431\u043B\u0438\u0436\u0430\u0439\u0448\u0438\u043C \u0432\u044B\u043A\u0430\u0442\u043E\u043C.` : `\u0423 \u0432\u0430\u0441 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0430 \u0441\u0430\u043C\u0430\u044F \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u044F\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u2014 ${installed}.`
|
|
17943
18535
|
);
|
|
17944
18536
|
}
|
|
17945
18537
|
if (decision.what === "launcher_too_old") {
|
|
@@ -17972,7 +18564,7 @@ function setupTool(engine, passport, key, baseUrl) {
|
|
|
17972
18564
|
return defineTool({
|
|
17973
18565
|
name: "setup",
|
|
17974
18566
|
title: "\u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0432\u0441\u0451 \u0434\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430",
|
|
17975
|
-
description: "\u0412\u0441\u0451, \u0447\u0435\u043C \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043D\u0430 \u044D\u0442\u043E\u043C \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435, \u2014 \u043E\u0434\u043D\u0438\u043C \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u043C. \u0411\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u041F\u0420\u041E\u0412\u0415\u0420\u042F\u0415\u0422 \u0434\u0435\u043B\u043E\u043C: \u0447\u0442\u043E \u0441\u0442\u043E\u0438\u0442 \u0438 \u0447\u0435\u0433\u043E \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u0447\u0442\u043E \u0434\u043E\u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u043F\u043E \u043F\u0440\u043E\u0441\u044C\u0431\u0435 \u0438 \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0432\u0435\u0441\u0438\u0442, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442 \u043C\u043E\u043D\u0442\u0430\u0436 (\u0448\u0430\u0433\u0438, \u0432\u043E\u043F\u0440\u043E\u0441\u044B \u0434\u043B\u044F \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A choose_variant, \u0447\u0435\u0439 \u0440\u0435\u0446\u0435\u043F\u0442 \u0438 \u0447\u0435\u0439 \u0441\u0442\u0438\u043B\u044C) \u0438 \u0432\u044B\u0448\u043B\u0430 \u043B\u0438 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0434\u0432\u0438\u0436\u043A\u0430 \u0438\u043B\u0438 \u0441\u0430\u043C\u043E\u0433\u043E \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F. \u0417\u043E\u0432\u0438 \u041F\u0415\u0420\u0412\u042B\u041C, \u0434\u043E \u043B\u044E\u0431\u043E\u0439 \u0440\u0430\u0431\u043E\u0442\u044B \u0441 \u0432\u0438\u0434\u0435\u043E, \u0438 \u0438\u0437 \u0441\u0432\u043E\u0435\u0439 \u043F\u0430\u043C\u044F\u0442\u0438 \u043E\u0431 \u044D\u0442\u043E\u043C \u043D\u0435 \u0440\u0430\u0441\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439.\n\u0421\u0442\u0430\u0432\u0438\u0442 \u0438 \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u0442 \u0441 what, \u043D\u043E \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0441\u043B\u0435 \xAB\u0434\u0430\xBB \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430: \u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u043A\u0430\u0436\u0438 \u0435\u043C\u0443 \u0441\u043B\u043E\u0432\u0430\u043C\u0438, \u0447\u0442\u043E \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0448\u044C \u0438 \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u044D\u0442\u043E \u0432\u0435\u0441\u0438\u0442, \u043F\u043E\u0442\u043E\u043C \u0437\u043E\u0432\u0438 \u0441 \u0442\u0435\u043C \u0436\u0435 what \u0438 consent=true. \xAB\u0421\u043A\u0430\u0447\u0430\u0439\xBB \u0438 \xAB\u043E\u0431\u043D\u043E\u0432\u0438\xBB \u2014 \u0442\u043E \u0436\u0435 \xAB\u0434\u0430\xBB \u043D\u0430 \u0442\u043E, \u0447\u0442\u043E \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u0443\u0436\u0435 \u043D\u0430\u0437\u0432\u0430\u043B\u0430 \u0441 \u0432\u0435\u0441\u043E\u043C: \u0437\u043E\u0432\u0438 what=all \u0441 consent=true. \u0411\u0435\u0437 consent \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u2014 \u043F\u0440\u0438\u0434\u0443\u0442 \u0432\u0435\u0441 \u0438 \u0432\u043E\u043F\u0440\u043E\u0441. \u0422\u044F\u0436\u0451\u043B\u043E\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0434 \u043F\u0440\u043E\u0441\u044C\u0431\u0443: \u043D\u0435 \u043F\u0440\u043E\u0441\u0438\u043B\u0438 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044B \u2014 \u043D\u0435 \u0441\u0442\u0430\u0432\u044C speech, \u043D\u0435 \u043F\u0440\u043E\u0441\u0438\u043B\u0438 \u043D\u043E\u0432\u044B\u0439 \u0444\u043E\u043D \u2014 \u043D\u0435 \u0441\u0442\u0430\u0432\u044C cutout.\n\u0414\u043E\u043B\u0433\u0430\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0434\u043E\u0436\u0434\u0438\u0441\u044C \u0435\u0451 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u043C wait. \u041D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0434\u0432\u0438\u0436\u043A\u0430 \u0438\u043B\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u0437\u0430\u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \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, \u0441\u043A\u0430\u0436\u0438 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443. \u0421\u043B\u043E\u043C\u0430\u043B\u043E\u0441\u044C \u043F\u043E\u0441\u043B\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u2014 rollback. \u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u043D\u0435 \u043D\u0443\u0436\u043D\u0430: \u0443\u0437\u043D\u0430\u0442\u044C, \u0437\u0430 \u0447\u0442\u043E \u043F\u043B\u0430\u0442\u044F\u0442, \u043C\u043E\u0436\u043D\u043E \u0434\u043E \u043E\u043F\u043B\u0430\u0442\u044B, \u0430 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u0435 \u0441\u0430\u043C\u043E \u0443\u043F\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u0432 \u043A\u043B\u044E\u0447 \u043D\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0435.",
|
|
18567
|
+
description: "\u0412\u0441\u0451, \u0447\u0435\u043C \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043D\u0430 \u044D\u0442\u043E\u043C \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435, \u2014 \u043E\u0434\u043D\u0438\u043C \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u043C. \u0411\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u041F\u0420\u041E\u0412\u0415\u0420\u042F\u0415\u0422 \u0434\u0435\u043B\u043E\u043C: \u0447\u0442\u043E \u0441\u0442\u043E\u0438\u0442 \u0438 \u0447\u0435\u0433\u043E \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u0447\u0442\u043E \u0434\u043E\u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u043F\u043E \u043F\u0440\u043E\u0441\u044C\u0431\u0435 \u0438 \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0432\u0435\u0441\u0438\u0442, \u0447\u0442\u043E \u0443\u043C\u0435\u0435\u0442 \u043C\u043E\u043D\u0442\u0430\u0436 (\u0448\u0430\u0433\u0438, \u0432\u043E\u043F\u0440\u043E\u0441\u044B \u0434\u043B\u044F \u043A\u0430\u0440\u0442\u043E\u0447\u0435\u043A choose_variant, \u0447\u0435\u0439 \u0440\u0435\u0446\u0435\u043F\u0442 \u0438 \u0447\u0435\u0439 \u0441\u0442\u0438\u043B\u044C) \u0438 \u0432\u044B\u0448\u043B\u0430 \u043B\u0438 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0434\u0432\u0438\u0436\u043A\u0430 \u0438\u043B\u0438 \u0441\u0430\u043C\u043E\u0433\u043E \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F. \u0417\u043E\u0432\u0438 \u041F\u0415\u0420\u0412\u042B\u041C, \u0434\u043E \u043B\u044E\u0431\u043E\u0439 \u0440\u0430\u0431\u043E\u0442\u044B \u0441 \u0432\u0438\u0434\u0435\u043E, \u0438 \u0438\u0437 \u0441\u0432\u043E\u0435\u0439 \u043F\u0430\u043C\u044F\u0442\u0438 \u043E\u0431 \u044D\u0442\u043E\u043C \u043D\u0435 \u0440\u0430\u0441\u0441\u043A\u0430\u0437\u044B\u0432\u0430\u0439.\n\u0421\u0442\u0430\u0432\u0438\u0442 \u0438 \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u0442 \u0441 what, \u043D\u043E \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0441\u043B\u0435 \xAB\u0434\u0430\xBB \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430: \u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u043A\u0430\u0436\u0438 \u0435\u043C\u0443 \u0441\u043B\u043E\u0432\u0430\u043C\u0438, \u0447\u0442\u043E \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0448\u044C \u0438 \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u044D\u0442\u043E \u0432\u0435\u0441\u0438\u0442, \u043F\u043E\u0442\u043E\u043C \u0437\u043E\u0432\u0438 \u0441 \u0442\u0435\u043C \u0436\u0435 what \u0438 consent=true. \xAB\u0421\u043A\u0430\u0447\u0430\u0439\xBB \u0438 \xAB\u043E\u0431\u043D\u043E\u0432\u0438\xBB \u2014 \u0442\u043E \u0436\u0435 \xAB\u0434\u0430\xBB \u043D\u0430 \u0442\u043E, \u0447\u0442\u043E \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u0443\u0436\u0435 \u043D\u0430\u0437\u0432\u0430\u043B\u0430 \u0441 \u0432\u0435\u0441\u043E\u043C: \u0437\u043E\u0432\u0438 what=all \u0441 consent=true \u041E\u0414\u0418\u041D \u0440\u0430\u0437 \u2014 \u043E\u0442\u0432\u0435\u0442 \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0437\u0430\u0434\u0430\u0447\u0438, \u0434\u0430\u043B\u044C\u0448\u0435 wait, setup \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u043D\u0435 \u0437\u043E\u0432\u0438. \u0411\u0435\u0437 consent \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u2014 \u043F\u0440\u0438\u0434\u0443\u0442 \u0432\u0435\u0441 \u0438 \u0432\u043E\u043F\u0440\u043E\u0441. \u0422\u044F\u0436\u0451\u043B\u043E\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0434 \u043F\u0440\u043E\u0441\u044C\u0431\u0443: \u043D\u0435 \u043F\u0440\u043E\u0441\u0438\u043B\u0438 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u044B \u2014 \u043D\u0435 \u0441\u0442\u0430\u0432\u044C speech, \u043D\u0435 \u043F\u0440\u043E\u0441\u0438\u043B\u0438 \u043D\u043E\u0432\u044B\u0439 \u0444\u043E\u043D \u2014 \u043D\u0435 \u0441\u0442\u0430\u0432\u044C cutout.\n\u0414\u043E\u043B\u0433\u0430\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u0434\u043E\u0436\u0434\u0438\u0441\u044C \u0435\u0451 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u043E\u043C wait. \u041D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u0434\u0432\u0438\u0436\u043A\u0430 \u0438\u043B\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F \u0437\u0430\u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \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, \u0441\u043A\u0430\u0436\u0438 \u044D\u0442\u043E \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443. \u0421\u043B\u043E\u043C\u0430\u043B\u043E\u0441\u044C \u043F\u043E\u0441\u043B\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F \u2014 rollback. \u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u043D\u0435 \u043D\u0443\u0436\u043D\u0430: \u0443\u0437\u043D\u0430\u0442\u044C, \u0437\u0430 \u0447\u0442\u043E \u043F\u043B\u0430\u0442\u044F\u0442, \u043C\u043E\u0436\u043D\u043E \u0434\u043E \u043E\u043F\u043B\u0430\u0442\u044B, \u0430 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u0435 \u0441\u0430\u043C\u043E \u0443\u043F\u0438\u0440\u0430\u0435\u0442\u0441\u044F \u0432 \u043A\u043B\u044E\u0447 \u043D\u0430 \u0440\u0430\u0437\u0434\u0430\u0447\u0435.",
|
|
17976
18568
|
// Полоса хода работы в ленте: установка качает десятки минут, и человек
|
|
17977
18569
|
// видит, что качается и сколько уже скачано. ⚠ Ожидание задачи — у
|
|
17978
18570
|
// отдельного инструмента `wait`, без полосы: полоса объявлена на
|
|
@@ -18024,9 +18616,6 @@ function setupTool(engine, passport, key, baseUrl) {
|
|
|
18024
18616
|
engine: news.engine ?? { installed: engine.freshVersion(), fresh: null, mb: 0, status: 0, notes: "" },
|
|
18025
18617
|
shell: news.shell,
|
|
18026
18618
|
note: firstLine(said),
|
|
18027
|
-
// Проверки здесь не было, а работа была: «Проверяю, что установлено»
|
|
18028
|
-
// над ответом «поставил новую версию» соврало бы о том, что идёт.
|
|
18029
|
-
...args.consent === true && args.what !== void 0 && UPDATES.has(args.what) ? { title: TITLE_UPDATING } : {},
|
|
18030
18619
|
shellVersion: VERSION
|
|
18031
18620
|
}));
|
|
18032
18621
|
}
|
|
@@ -18037,6 +18626,7 @@ function setupTool(engine, passport, key, baseUrl) {
|
|
|
18037
18626
|
const consent = args.consent === true;
|
|
18038
18627
|
const what = args.what;
|
|
18039
18628
|
if (what === void 0) return lookAround(engine, args.model, key, baseUrl);
|
|
18629
|
+
if (consent && UPDATES.has(what)) return startUpdate(engine, what, key, baseUrl);
|
|
18040
18630
|
if (what === "engine") {
|
|
18041
18631
|
return updateEngine(engine, consent, key, baseUrl, ASKED_POINTER_MS, (seen) => {
|
|
18042
18632
|
if (!consent) news.engine = seen;
|
|
@@ -18048,7 +18638,7 @@ function setupTool(engine, passport, key, baseUrl) {
|
|
|
18048
18638
|
});
|
|
18049
18639
|
}
|
|
18050
18640
|
if (what === "all") {
|
|
18051
|
-
return
|
|
18641
|
+
return lookAround(engine, args.model, key, baseUrl);
|
|
18052
18642
|
}
|
|
18053
18643
|
const step = HEAVY_STEPS[what];
|
|
18054
18644
|
return consent ? installStep(engine, { step, model: args.model, consent: true }, key, baseUrl, tell) : askBeforeHeavy(engine, step, args.model, key, baseUrl);
|
|
@@ -18094,7 +18684,20 @@ async function lookAround(engine, model, key, baseUrl) {
|
|
|
18094
18684
|
updateEngine(engine, false, key, baseUrl, NEWS_POINTER_MS, toEngine),
|
|
18095
18685
|
shell
|
|
18096
18686
|
]);
|
|
18097
|
-
return card(
|
|
18687
|
+
return card(
|
|
18688
|
+
together([newsForModel(shellNews, engineNews), machine.result, news, own]),
|
|
18689
|
+
{ readiness: machine.readiness }
|
|
18690
|
+
);
|
|
18691
|
+
}
|
|
18692
|
+
function newsForModel(shell, engine) {
|
|
18693
|
+
if (!shell?.fresh && !engine?.fresh) return toolSuccess("");
|
|
18694
|
+
const numbers = [
|
|
18695
|
+
engine?.fresh ? `\u0434\u0432\u0438\u0436\u043E\u043A ${engine.installed ?? "\u043D\u0435\u0442"} \u2192 ${engine.fresh}` : "",
|
|
18696
|
+
shell?.fresh ? `\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 ${shell.installed ?? VERSION} \u2192 ${shell.fresh}` : ""
|
|
18697
|
+
].filter((one) => one !== "").join(", ");
|
|
18698
|
+
return toolSuccess(
|
|
18699
|
+
`\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u043D\u043E\u0432\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0451\u0440\u0430: ${whatIsNew(shell, engine)} (${numbers}). \u0421\u043A\u0430\u0436\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443, \u0447\u0442\u043E \u0438\u043C\u0435\u043D\u043D\u043E \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u0441\u044F \u0438 \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0432\u0435\u0441\u0438\u0442. \xAB\u041E\u0431\u043D\u043E\u0432\u0438\xBB \u2014 \u044D\u0442\u043E \xAB\u0434\u0430\xBB: \u043E\u0434\u0438\u043D \u0432\u044B\u0437\u043E\u0432 setup \u0441 what=all \u0438 consent=true, \u0434\u0430\u043B\u044C\u0448\u0435 wait \u043F\u043E \u043D\u043E\u043C\u0435\u0440\u0443 \u0437\u0430\u0434\u0430\u0447\u0438.`
|
|
18700
|
+
);
|
|
18098
18701
|
}
|
|
18099
18702
|
function withCard(result, card) {
|
|
18100
18703
|
if (result.type !== "success" || result.structured !== void 0) return result;
|
|
@@ -18104,11 +18707,22 @@ function firstLine(result) {
|
|
|
18104
18707
|
const text2 = result.type === "success" ? wordsOf(result.content) : result.error;
|
|
18105
18708
|
return text2.split("\n").map((line) => line.trim()).find((line) => line !== "") ?? "";
|
|
18106
18709
|
}
|
|
18107
|
-
|
|
18108
|
-
const
|
|
18109
|
-
|
|
18110
|
-
|
|
18111
|
-
|
|
18710
|
+
function startUpdate(engine, what, key, baseUrl) {
|
|
18711
|
+
const title = engine.place() === null ? TITLE_INSTALL : TITLE_UPDATE;
|
|
18712
|
+
const id = startSetupJob(title, (job) => runUpdate(job, {
|
|
18713
|
+
engine,
|
|
18714
|
+
key,
|
|
18715
|
+
baseUrl,
|
|
18716
|
+
what,
|
|
18717
|
+
pointerMs: ASKED_POINTER_MS,
|
|
18718
|
+
installMissing: () => installMissing(engine, key, baseUrl, void 0)
|
|
18719
|
+
}));
|
|
18720
|
+
const report = setupJobReport(id);
|
|
18721
|
+
return toolSuccess(
|
|
18722
|
+
`\u0417\u0430\u0434\u0430\u0447\u0430 ${id}: ${report?.what ?? title}.
|
|
18723
|
+
\u0418\u0434\u0451\u0442 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F: \u043F\u0440\u043E\u0432\u0435\u0440\u044E, \u0447\u0442\u043E \u0432\u044B\u0448\u043B\u043E, \u0441\u043A\u0430\u0447\u0430\u044E \u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E. \u041F\u043E\u043B\u043E\u0441\u0430 \u0443 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u0441\u0430\u043C\u0430. \u041F\u043E\u0437\u043E\u0432\u0438 wait \u0441 job "` + id + '" \u2014 \u0434\u043E\u0436\u0434\u0451\u0442\u0441\u044F \u0438 \u0441\u043A\u0430\u0436\u0435\u0442, \u0447\u0435\u043C \u043A\u043E\u043D\u0447\u0438\u043B\u043E\u0441\u044C; setup \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u043D\u0435 \u0437\u043E\u0432\u0438. \u0413\u043E\u0442\u043E\u0432\u043E \u2014 \u043F\u0435\u0440\u0435\u0441\u043A\u0430\u0436\u0438 \u0441\u0442\u0440\u043E\u043A\u0443 \xAB\u0427\u0435\u043B\u043E\u0432\u0435\u043A\u0443\xBB.',
|
|
18724
|
+
report ?? void 0
|
|
18725
|
+
);
|
|
18112
18726
|
}
|
|
18113
18727
|
async function installMissing(engine, key, baseUrl, tell) {
|
|
18114
18728
|
const place = engine.place();
|
|
@@ -18241,7 +18855,14 @@ var RENDER_LADDER = [
|
|
|
18241
18855
|
];
|
|
18242
18856
|
var TRIALS_STEP = "\u041F\u043E\u0442\u043E\u043C \u0441\u043E\u0431\u0435\u0440\u0443 \u0432\u0435\u0440\u0441\u0438\u0438 \u0434\u043B\u044F \u043F\u0440\u043E\u0431\u043D\u043E\u0433\u043E \u0440\u0435\u0436\u0438\u043C\u0430 \u043F\u043E \u043E\u0434\u043D\u043E\u0439: \u0440\u0435\u0447\u044C \u0438 \u0437\u0432\u0443\u043A \u0442\u0435 \u0436\u0435, \u0434\u0440\u0443\u0433\u043E\u0435 \u0434\u0432\u0438\u0436\u0435\u043D\u0438\u0435, \u043C\u0435\u0441\u0442\u0430 \u0438 \u043A\u0440\u0443\u043F\u043D\u043E\u0441\u0442\u044C.";
|
|
18243
18857
|
async function followWork(engine, asked, pace = realPace, tell) {
|
|
18244
|
-
const ask2 = () =>
|
|
18858
|
+
const ask2 = async () => {
|
|
18859
|
+
if (!isSetupJob(asked.job)) return engine.command(["job", asked.job]);
|
|
18860
|
+
const text2 = setupJobText(asked.job);
|
|
18861
|
+
return text2 !== null ? { ok: true, text: text2 } : {
|
|
18862
|
+
ok: false,
|
|
18863
|
+
text: `\u0417\u0430\u0434\u0430\u0447\u0438 ${asked.job} \u043D\u0435\u0442: \u0435\u0451 \u0432\u0451\u043B \u043F\u0440\u0435\u0436\u043D\u0438\u0439 \u0437\u0430\u043F\u0443\u0441\u043A \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0437\u043E\u0432\u0438 setup \u2014 \u043E\u043D \u0441\u043A\u0430\u0436\u0435\u0442, \u0447\u0442\u043E \u0441\u0442\u043E\u0438\u0442 \u0441\u0435\u0439\u0447\u0430\u0441.`
|
|
18864
|
+
};
|
|
18865
|
+
};
|
|
18245
18866
|
const seconds2 = waitSeconds(asked.seconds ?? WAIT_LIMIT_SECONDS);
|
|
18246
18867
|
if (seconds2 === 0) return asJobResult(await ask2());
|
|
18247
18868
|
const state = await followJob({
|
|
@@ -18391,6 +19012,9 @@ function waitTool(engine, pace = realPace) {
|
|
|
18391
19012
|
}),
|
|
18392
19013
|
readOnly: true,
|
|
18393
19014
|
async execute(args, ctx) {
|
|
19015
|
+
if (args.job !== void 0 && isSetupJob(args.job)) {
|
|
19016
|
+
return followWork(engine, { job: args.job, seconds: args.seconds }, pace, ctx?.emitProgress);
|
|
19017
|
+
}
|
|
18394
19018
|
const place = engine.place();
|
|
18395
19019
|
if (place === null) return toolError(engine.whyNoEngine());
|
|
18396
19020
|
if (args.job === void 0) {
|
|
@@ -22541,4 +23165,4 @@ ${inTable}`, file2);
|
|
|
22541
23165
|
};
|
|
22542
23166
|
}
|
|
22543
23167
|
|
|
22544
|
-
export { CrashReporter, DEFAULT_HOME, DeliveryError, Engine, ForeignBlockError, INSIDE_PYTHON, INSTALL_STEPS, KEEP_COPIES, KEEP_VERSIONS, LONG_STEPS, MANIFEST_TIMEOUT_MS, MANIFEST_URL, MARKER, MIN_ENGINE, McpServer, NaparnikApiClient, NaparnikAuthError, NaparnikClientError, NaparnikConfigError, NaparnikError, NaparnikInsufficientBalanceError, NaparnikScopeError, NaparnikServerError, NaparnikTimeoutError, PAUSE_HOURS, SERVER_NAME, SOURCES_FILE, START_SEC, StdioServerTransport, TOOL_SEC, USER_AGENT, VERSION, WHERE_TO_GET_KEY, Wakefulness, buildAll, buildBlock, buildResources, bundleUrlFor, chooseBody, compare, configPath, currentMachineFingerprint, decide, decideShell, defineTool, deploy, downloadFile, fetchManifest, fetchShellManifest, fileOrRefusal, findBlock, fromHost, fromNpxCache, handOverToBody, inside, install, installPayload, installPython, installStep, installedShell, jsonSchemaOf, keyFromBlock, keyInTable, lastLine, loadConfig, manifestUrlFor, markChecked, markChecked2, markCurrent2 as markCurrent, parseEngineManifest, parseFailure, path, platformKey, previousVersion2 as previousVersion, probe, pythonSource, readConfig, realPace, refusalFor, remove, rollback, rollbackShell, shellDir, systemBlocker, tarEntries, tidyOld2 as tidyOld, timeToCheck, timeToCheck2, unpackArchive, updateEngine, watchProcessCrashes, withArgs };
|
|
23168
|
+
export { CrashReporter, DEFAULT_HOME, DeliveryError, Engine, ForeignBlockError, INSIDE_PYTHON, INSTALL_STEPS, KEEP_COPIES, KEEP_VERSIONS, LONG_STEPS, MANIFEST_TIMEOUT_MS, MANIFEST_URL, MARKER, MIN_ENGINE, McpServer, NaparnikApiClient, NaparnikAuthError, NaparnikClientError, NaparnikConfigError, NaparnikError, NaparnikInsufficientBalanceError, NaparnikScopeError, NaparnikServerError, NaparnikTimeoutError, PAUSE_HOURS, SERVER_NAME, SOURCES_FILE, START_SEC, StdioServerTransport, TOOL_SEC, USER_AGENT, VERSION, WHERE_TO_GET_KEY, Wakefulness, buildAll, buildBlock, buildResources, bundleUrlFor, chooseBody, compare, configPath, currentMachineFingerprint, decide, decideShell, defineTool, deploy, downloadFile, fetchManifest, fetchShellManifest, fileOrRefusal, findBlock, fromHost, fromNpxCache, handOverToBody, inside, install, installPayload, installPython, installStep, installedShell, jsonSchemaOf, keyFromBlock, keyInTable, lastLine, loadConfig, manifestUrlFor, markChecked, markChecked2, markCurrent2 as markCurrent, parseEngineManifest, parseFailure, path, platformKey, previousVersion2 as previousVersion, probe, pythonSource, readConfig, realPace, refusalFor, remove, reportInstallFaults, rollback, rollbackShell, shellDir, systemBlocker, tarEntries, tidyOld2 as tidyOld, timeToCheck, timeToCheck2, unpackArchive, updateEngine, watchProcessCrashes, withArgs };
|