@naparnik/mcp 0.10.48 → 0.10.50
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 +12 -0
- package/dist/{chunk-Q7HJ7ROV.js → chunk-DH5ID6CT.js} +481 -620
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +56 -85
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
import { createHash, randomUUID, randomBytes } from 'crypto';
|
|
2
|
+
import { existsSync, readFileSync, closeSync, mkdirSync, openSync, rmSync, renameSync, readdirSync, statSync, writeFileSync, symlinkSync, chmodSync, lstatSync, realpathSync, mkdtempSync, linkSync, readlinkSync, appendFileSync, fstatSync, readSync, fsyncSync } from 'fs';
|
|
3
|
+
import { win32, join, dirname, sep, resolve, basename, relative, isAbsolute, extname } from 'path';
|
|
4
|
+
import { gunzipSync } from 'zlib';
|
|
1
5
|
import { execFile, spawn, execFileSync } from 'child_process';
|
|
2
|
-
import { createHash, randomBytes, randomUUID } from 'crypto';
|
|
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
6
|
import { platform, homedir, arch, release, userInfo, tmpdir } from 'os';
|
|
5
|
-
import { win32, join, dirname, sep, resolve, basename, relative, isAbsolute, extname } from 'path';
|
|
6
7
|
import { promisify } from 'util';
|
|
7
8
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
8
|
-
import { gunzipSync } from 'zlib';
|
|
9
9
|
import { pathToFileURL, fileURLToPath } from 'url';
|
|
10
10
|
import { Worker } from 'worker_threads';
|
|
11
11
|
import { readFile } from 'fs/promises';
|
|
@@ -730,9 +730,9 @@ function parsePositiveInt(raw, fallback) {
|
|
|
730
730
|
}
|
|
731
731
|
|
|
732
732
|
// src/version.ts
|
|
733
|
-
var VERSION = "0.10.
|
|
733
|
+
var VERSION = "0.10.50";
|
|
734
734
|
var USER_AGENT = `naparnik-mcp/${VERSION}`;
|
|
735
|
-
var MIN_ENGINE = "2026.09.24-
|
|
735
|
+
var MIN_ENGINE = "2026.09.24-478";
|
|
736
736
|
var LAUNCHER_PROTOCOL = 1;
|
|
737
737
|
|
|
738
738
|
// src/contracts/sdk-headers.ts
|
|
@@ -1001,6 +1001,258 @@ function describe(err) {
|
|
|
1001
1001
|
function sleep(ms) {
|
|
1002
1002
|
return new Promise((resolve5) => setTimeout(resolve5, ms));
|
|
1003
1003
|
}
|
|
1004
|
+
var DeliveryError = class extends Error {
|
|
1005
|
+
constructor(message) {
|
|
1006
|
+
super(message);
|
|
1007
|
+
this.name = "DeliveryTrouble";
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
async function downloadFile(opts) {
|
|
1011
|
+
const { url: url2, dest, sha256, bytes, timeoutMs = 30 * 6e4, report, key } = opts;
|
|
1012
|
+
if (!/^[a-f0-9]{64}$/.test(sha256)) {
|
|
1013
|
+
throw new DeliveryError(`\u043D\u0435\u0447\u0435\u043C \u0441\u0432\u0435\u0440\u0438\u0442\u044C \u0441\u043A\u0430\u0447\u0430\u043D\u043D\u043E\u0435: \u0441\u0443\u043C\u043C\u0430 \xAB${sha256}\xBB \u043D\u0435 \u043F\u043E\u0445\u043E\u0436\u0430 \u043D\u0430 sha256`);
|
|
1014
|
+
}
|
|
1015
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
1016
|
+
const temp = `${dest}.downloading-${process.pid}-${randomUUID()}`;
|
|
1017
|
+
const guard = new AbortController();
|
|
1018
|
+
const timer = setTimeout(() => {
|
|
1019
|
+
guard.abort();
|
|
1020
|
+
}, timeoutMs);
|
|
1021
|
+
try {
|
|
1022
|
+
const response = await fetch(url2, {
|
|
1023
|
+
signal: guard.signal,
|
|
1024
|
+
redirect: "follow",
|
|
1025
|
+
...key !== null && key !== void 0 ? { headers: { authorization: `Bearer ${key}` } } : {}
|
|
1026
|
+
});
|
|
1027
|
+
const hasKey = key !== null && key !== void 0;
|
|
1028
|
+
if (!response.ok) {
|
|
1029
|
+
if (response.status === 401 || response.status === 403) {
|
|
1030
|
+
if (response.status === 403 && hasKey) {
|
|
1031
|
+
throw new DeliveryError(
|
|
1032
|
+
`${url2} \u043D\u0435 \u043E\u0442\u0434\u0430\u0451\u0442 \u0444\u0430\u0439\u043B: \u043A\u043B\u044E\u0447 \u043F\u0440\u0438\u0437\u043D\u0430\u043D, \u043D\u043E \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438 \u043D\u0430 \u043C\u043E\u043D\u0442\u0430\u0436 \u043D\u0435\u0442. \u0421\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u0435 \u043D\u043E\u0432\u043E\u0433\u043E \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E, \u043F\u043E\u043A\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u0430; \u0432\u0441\u0451, \u0447\u0442\u043E \u0443\u0436\u0435 \u0441\u0442\u043E\u0438\u0442 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435, \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043E\u0442\u0430\u0442\u044C. \u041F\u0440\u043E\u0434\u043B\u0438\u0442\u0435 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0443 \u0432 \u0431\u043E\u0442\u0435 \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435.`
|
|
1033
|
+
);
|
|
1034
|
+
}
|
|
1035
|
+
throw new DeliveryError(
|
|
1036
|
+
!hasKey ? `${url2} \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043A\u043B\u044E\u0447 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430, \u0430 \u043E\u043D \u043D\u0435 \u0437\u0430\u0434\u0430\u043D. \u0412\u043F\u0438\u0448\u0438\u0442\u0435 \u043A\u043B\u044E\u0447 \u0432 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044E MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0441\u0435\u043A\u0446\u0438\u044F env) \u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0443 \u2014 \u041A\u043B\u043E\u0434\u0430 \u0438\u043B\u0438 Codex.` : `${url2} \u043D\u0435 \u043F\u0440\u0438\u043D\u044F\u043B \u043A\u043B\u044E\u0447 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430 (${response.status}). \u0421\u043A\u043E\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043E, \u043A\u043B\u044E\u0447 \u0437\u0430\u043C\u0435\u043D\u0451\u043D \u0431\u043E\u043B\u0435\u0435 \u043D\u043E\u0432\u044B\u043C: \u043D\u043E\u0432\u044B\u0439 \u0444\u0430\u0439\u043B \u0438\u0437 \u0431\u043E\u0442\u0430 \u0443\u0436\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D \u0437\u0434\u0435\u0441\u044C \u0438\u043B\u0438 \u043D\u0430 \u0434\u0440\u0443\u0433\u043E\u043C \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435. \u0412\u043E\u0437\u044C\u043C\u0438\u0442\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0439 \u0444\u0430\u0439\u043B \u0443 \u0431\u043E\u0442\u0430 ${KEY_SOURCE_BOT} \u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u044C\u0442\u0435 \u0435\u0433\u043E.`
|
|
1037
|
+
);
|
|
1038
|
+
}
|
|
1039
|
+
throw new DeliveryError(`${url2} \u043E\u0442\u0432\u0435\u0442\u0438\u043B ${response.status} ${response.statusText}`);
|
|
1040
|
+
}
|
|
1041
|
+
const body = await response.arrayBuffer();
|
|
1042
|
+
const buffer = Buffer.from(body);
|
|
1043
|
+
const sum = createHash("sha256").update(buffer).digest("hex");
|
|
1044
|
+
if (bytes !== void 0 && buffer.length !== bytes) {
|
|
1045
|
+
throw new DeliveryError(
|
|
1046
|
+
looksLikeHtml(buffer) ? `\u043F\u043E \u0430\u0434\u0440\u0435\u0441\u0443 ${url2} \u043B\u0435\u0436\u0438\u0442 \u043D\u0435 \u0430\u0440\u0445\u0438\u0432, \u0430 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u2014 \u0444\u0430\u0439\u043B \u0435\u0449\u0451 \u043D\u0435 \u0432\u044B\u043B\u043E\u0436\u0435\u043D.` : `\u0441\u043A\u0430\u0447\u0430\u043B\u043E\u0441\u044C ${buffer.length} \u0431\u0430\u0439\u0442 \u0432\u043C\u0435\u0441\u0442\u043E ${bytes} \u2014 \u0441\u0432\u044F\u0437\u044C \u043E\u0431\u043E\u0440\u0432\u0430\u043B\u0430\u0441\u044C, \u043F\u043E\u0432\u0442\u043E\u0440\u0438.`
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
if (sum !== sha256) {
|
|
1050
|
+
throw new DeliveryError(
|
|
1051
|
+
looksLikeHtml(buffer) ? `\u043F\u043E \u0430\u0434\u0440\u0435\u0441\u0443 ${url2} \u043B\u0435\u0436\u0438\u0442 \u043D\u0435 \u0430\u0440\u0445\u0438\u0432, \u0430 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u2014 \u0444\u0430\u0439\u043B \u0435\u0449\u0451 \u043D\u0435 \u0432\u044B\u043B\u043E\u0436\u0435\u043D.` : `\u0441\u043A\u0430\u0447\u0430\u043D\u043D\u043E\u0435 \u043D\u0435 \u0441\u043E\u0432\u043F\u0430\u043B\u043E \u0441 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u043E\u0439 \u0441\u0443\u043C\u043C\u043E\u0439.
|
|
1052
|
+
\u0436\u0434\u0430\u043B\u0438 ${sha256}
|
|
1053
|
+
\u0432\u044B\u0448\u043B\u043E ${sum}
|
|
1054
|
+
\u041F\u043E\u0432\u0442\u043E\u0440\u0438; \u0435\u0441\u043B\u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u0442\u0441\u044F \u2014 \u0444\u0430\u0439\u043B \u043F\u043E\u0434\u043C\u0435\u043D\u0451\u043D \u0438\u043B\u0438 \u0431\u0438\u0442\u044B\u0439, \u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0435\u0433\u043E \u043D\u0435\u043B\u044C\u0437\u044F.`
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1057
|
+
writeFileSync(temp, buffer);
|
|
1058
|
+
if (existsSync(dest)) {
|
|
1059
|
+
throw new DeliveryError(
|
|
1060
|
+
`\u0444\u0430\u0439\u043B ${dest} \u0443\u0436\u0435 \u0437\u0430\u043D\u044F\u043B \u0434\u0440\u0443\u0433\u043E\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u2014 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0443\u0434\u0430\u043B\u044F\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044E \u0441 \u043D\u043E\u0432\u044B\u043C staging.`
|
|
1061
|
+
);
|
|
1062
|
+
}
|
|
1063
|
+
renameSync(temp, dest);
|
|
1064
|
+
report?.(`\u0441\u043A\u0430\u0447\u0430\u043D\u043E ${Math.round(buffer.length / 1024 / 1024)} \u041C\u0411`);
|
|
1065
|
+
return { file: dest, bytes: buffer.length, sha256: sum };
|
|
1066
|
+
} catch (trouble) {
|
|
1067
|
+
rmSync(temp, { force: true });
|
|
1068
|
+
if (trouble instanceof DeliveryError) throw trouble;
|
|
1069
|
+
if (guard.signal.aborted) {
|
|
1070
|
+
throw new DeliveryError(`${url2} \u043D\u0435 \u043E\u0442\u0434\u0430\u043B \u0444\u0430\u0439\u043B \u0437\u0430 ${Math.round(timeoutMs / 6e4)} \u043C\u0438\u043D.`);
|
|
1071
|
+
}
|
|
1072
|
+
throw new DeliveryError(`\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043A\u0430\u0447\u0430\u0442\u044C ${url2}: ${describeFailure(trouble)}`);
|
|
1073
|
+
} finally {
|
|
1074
|
+
clearTimeout(timer);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
function looksLikeHtml(buffer) {
|
|
1078
|
+
const start = buffer.subarray(0, 200).toString("latin1").trimStart().toLowerCase();
|
|
1079
|
+
return start.startsWith("<!doctype html") || start.startsWith("<html");
|
|
1080
|
+
}
|
|
1081
|
+
var BLOCK = 512;
|
|
1082
|
+
function tarEntries(data) {
|
|
1083
|
+
const entries = [];
|
|
1084
|
+
let offset = 0;
|
|
1085
|
+
let longName = null;
|
|
1086
|
+
let longTarget = null;
|
|
1087
|
+
while (offset + BLOCK <= data.length) {
|
|
1088
|
+
const header = data.subarray(offset, offset + BLOCK);
|
|
1089
|
+
if (header.every((b) => b === 0)) break;
|
|
1090
|
+
const name = fieldLine(header, 0, 100);
|
|
1091
|
+
const mode = octal(header, 100, 8);
|
|
1092
|
+
const size = fieldSize(header, 124, 12);
|
|
1093
|
+
const type = String.fromCharCode(header[156]);
|
|
1094
|
+
const target = fieldLine(header, 157, 100);
|
|
1095
|
+
const prefix = fieldLine(header, 345, 155);
|
|
1096
|
+
offset += BLOCK;
|
|
1097
|
+
const body = data.subarray(offset, offset + size);
|
|
1098
|
+
offset += Math.ceil(size / BLOCK) * BLOCK;
|
|
1099
|
+
if (type === "L") {
|
|
1100
|
+
longName = body.toString("utf8").replace(/\0+$/, "");
|
|
1101
|
+
continue;
|
|
1102
|
+
}
|
|
1103
|
+
if (type === "K") {
|
|
1104
|
+
longTarget = body.toString("utf8").replace(/\0+$/, "");
|
|
1105
|
+
continue;
|
|
1106
|
+
}
|
|
1107
|
+
if (type === "x") {
|
|
1108
|
+
const fields = parsePax(body);
|
|
1109
|
+
if (fields["path"] !== void 0) longName = fields["path"];
|
|
1110
|
+
if (fields["linkpath"] !== void 0) longTarget = fields["linkpath"];
|
|
1111
|
+
continue;
|
|
1112
|
+
}
|
|
1113
|
+
if (type === "g") continue;
|
|
1114
|
+
const full = longName ?? (prefix !== "" ? `${prefix}/${name}` : name);
|
|
1115
|
+
const linkTarget = longTarget ?? target;
|
|
1116
|
+
longName = null;
|
|
1117
|
+
longTarget = null;
|
|
1118
|
+
const kind = type === "5" ? "dir" : type === "2" ? "symlink" : type === "1" ? "hardlink" : "file";
|
|
1119
|
+
if (type !== "" && type !== "0" && type !== "\0" && kind === "file" && type !== "7") continue;
|
|
1120
|
+
entries.push({ name: full, kind, mode, body, target: linkTarget });
|
|
1121
|
+
}
|
|
1122
|
+
return entries;
|
|
1123
|
+
}
|
|
1124
|
+
function parsePax(body) {
|
|
1125
|
+
const fields = {};
|
|
1126
|
+
let offset = 0;
|
|
1127
|
+
while (offset < body.length) {
|
|
1128
|
+
const space = body.indexOf(32, offset);
|
|
1129
|
+
if (space === -1) break;
|
|
1130
|
+
const length = Number.parseInt(body.subarray(offset, space).toString("ascii"), 10);
|
|
1131
|
+
if (!Number.isFinite(length) || length <= 0 || offset + length > body.length) break;
|
|
1132
|
+
const entry = body.subarray(space + 1, offset + length).toString("utf8").replace(/\n$/, "");
|
|
1133
|
+
const equal = entry.indexOf("=");
|
|
1134
|
+
if (equal > 0) fields[entry.slice(0, equal)] = entry.slice(equal + 1);
|
|
1135
|
+
offset += length;
|
|
1136
|
+
}
|
|
1137
|
+
return fields;
|
|
1138
|
+
}
|
|
1139
|
+
function fieldLine(header, start, length) {
|
|
1140
|
+
const chunk = header.subarray(start, start + length);
|
|
1141
|
+
const end = chunk.indexOf(0);
|
|
1142
|
+
return chunk.subarray(0, end === -1 ? chunk.length : end).toString("utf8");
|
|
1143
|
+
}
|
|
1144
|
+
function octal(header, start, length) {
|
|
1145
|
+
const text2 = fieldLine(header, start, length).trim();
|
|
1146
|
+
const ch = Number.parseInt(text2, 8);
|
|
1147
|
+
return Number.isFinite(ch) ? ch : 0;
|
|
1148
|
+
}
|
|
1149
|
+
function fieldSize(header, start, length) {
|
|
1150
|
+
if ((header[start] & 128) !== 0) {
|
|
1151
|
+
let ch = 0;
|
|
1152
|
+
for (let i = start + 1; i < start + length; i += 1) ch = ch * 256 + header[i];
|
|
1153
|
+
return ch;
|
|
1154
|
+
}
|
|
1155
|
+
return octal(header, start, length);
|
|
1156
|
+
}
|
|
1157
|
+
function inside(root, path2) {
|
|
1158
|
+
if (path2 === "" || path2.startsWith("/") || path2.startsWith("\\")) return false;
|
|
1159
|
+
if (/^[A-Za-z]:/.test(path2)) return false;
|
|
1160
|
+
const target = resolve(root, path2);
|
|
1161
|
+
const bottom = resolve(root);
|
|
1162
|
+
return target === bottom || target.startsWith(bottom + sep);
|
|
1163
|
+
}
|
|
1164
|
+
function unpackArchive(archive, dest) {
|
|
1165
|
+
const entries = tarEntries(gunzipSync(readFileSync(archive)));
|
|
1166
|
+
if (entries.length === 0) throw new DeliveryError(`\u0430\u0440\u0445\u0438\u0432 ${archive} \u043F\u0443\u0441\u0442 \u2014 \u0440\u0430\u0441\u043F\u0430\u043A\u043E\u0432\u044B\u0432\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E`);
|
|
1167
|
+
for (const entry of entries) {
|
|
1168
|
+
if (!inside(dest, entry.name)) throw escapesRoot(archive, entry.name);
|
|
1169
|
+
if (entry.kind === "symlink" || entry.kind === "hardlink") {
|
|
1170
|
+
if (entry.target.startsWith("/") || entry.target.startsWith("\\") || /^[A-Za-z]:/.test(entry.target)) {
|
|
1171
|
+
throw escapesRoot(archive, `${entry.name} \u2192 ${entry.target}`);
|
|
1172
|
+
}
|
|
1173
|
+
const from = entry.kind === "hardlink" ? entry.target : join(dirname(entry.name), entry.target);
|
|
1174
|
+
if (!inside(dest, from)) throw escapesRoot(archive, `${entry.name} \u2192 ${entry.target}`);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
for (const entry of entries) {
|
|
1178
|
+
const path2 = join(dest, entry.name);
|
|
1179
|
+
if (entry.kind === "dir") {
|
|
1180
|
+
mkdirSync(path2, { recursive: true });
|
|
1181
|
+
continue;
|
|
1182
|
+
}
|
|
1183
|
+
mkdirSync(dirname(path2), { recursive: true });
|
|
1184
|
+
if (entry.kind === "symlink") {
|
|
1185
|
+
rmSync(path2, { force: true });
|
|
1186
|
+
symlinkSync(entry.target, path2);
|
|
1187
|
+
continue;
|
|
1188
|
+
}
|
|
1189
|
+
if (entry.kind === "hardlink") {
|
|
1190
|
+
writeFileSync(path2, readFileSync(join(dest, entry.target)));
|
|
1191
|
+
continue;
|
|
1192
|
+
}
|
|
1193
|
+
writeFileSync(path2, entry.body);
|
|
1194
|
+
if ((entry.mode & 73) !== 0) chmodSync(path2, entry.mode & 511);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
function escapesRoot(archive, name) {
|
|
1198
|
+
return new DeliveryError(
|
|
1199
|
+
`\u0430\u0440\u0445\u0438\u0432 ${archive} \u043F\u044B\u0442\u0430\u0435\u0442\u0441\u044F \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u0444\u0430\u0439\u043B \u0437\u0430 \u043F\u0440\u0435\u0434\u0435\u043B\u044B \u043F\u0430\u043F\u043A\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438: \xAB${name}\xBB.
|
|
1200
|
+
\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0440\u0430\u0441\u043F\u0430\u043A\u043E\u0432\u0430\u043D\u043E. \u0421\u043A\u0430\u0447\u0430\u0439 \u0437\u0430\u043D\u043E\u0432\u043E \u2014 \u0432\u0435\u0440\u043E\u044F\u0442\u043D\u0435\u0435 \u0432\u0441\u0435\u0433\u043E, \u0444\u0430\u0439\u043B \u043F\u043E\u0432\u0440\u0435\u0436\u0434\u0451\u043D \u0438\u043B\u0438 \u043F\u043E\u0434\u043C\u0435\u043D\u0451\u043D.`
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
function dirExists(path2) {
|
|
1204
|
+
try {
|
|
1205
|
+
return statSync(path2).isDirectory();
|
|
1206
|
+
} catch {
|
|
1207
|
+
return false;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
var LOCK_FILE = "deps.lock.json";
|
|
1211
|
+
function platformKey(os = process.platform, arch2 = process.arch) {
|
|
1212
|
+
if (os === "darwin") return arch2 === "arm64" ? "Darwin-arm64" : arch2 === "x64" ? "Darwin-x86_64" : null;
|
|
1213
|
+
if (os === "win32") return arch2 === "x64" ? "Windows-AMD64" : null;
|
|
1214
|
+
if (os === "linux") return arch2 === "x64" ? "Linux-x86_64" : arch2 === "arm64" ? "Linux-aarch64" : null;
|
|
1215
|
+
return null;
|
|
1216
|
+
}
|
|
1217
|
+
function depFolderName(entry) {
|
|
1218
|
+
return `${entry.version}-${entry.archives.map((one) => one.sha256.slice(0, 8)).join("")}`;
|
|
1219
|
+
}
|
|
1220
|
+
function lockedPython(engineDir, home, key = platformKey()) {
|
|
1221
|
+
if (key === null) return null;
|
|
1222
|
+
const file2 = join(engineDir, LOCK_FILE);
|
|
1223
|
+
if (!existsSync(file2)) return null;
|
|
1224
|
+
const lock = JSON.parse(readFileSync(file2, "utf8"));
|
|
1225
|
+
const entry = lock.python?.platforms?.[key];
|
|
1226
|
+
const archive = entry?.archives[0];
|
|
1227
|
+
if (entry === void 0 || archive === void 0) return null;
|
|
1228
|
+
const folder = join(home, "deps", "python", depFolderName(entry));
|
|
1229
|
+
return { version: entry.version, archive, folder, executable: join(folder, entry.run) };
|
|
1230
|
+
}
|
|
1231
|
+
async function bringPython(python, report) {
|
|
1232
|
+
if (existsSync(python.executable)) return python.executable;
|
|
1233
|
+
const stage = `${python.folder}.partial-${process.pid}`;
|
|
1234
|
+
rmSync(stage, { recursive: true, force: true });
|
|
1235
|
+
try {
|
|
1236
|
+
const archive = join(stage, "python.tar.gz");
|
|
1237
|
+
await downloadFile({
|
|
1238
|
+
url: python.archive.url,
|
|
1239
|
+
dest: archive,
|
|
1240
|
+
sha256: python.archive.sha256,
|
|
1241
|
+
bytes: python.archive.bytes,
|
|
1242
|
+
key: null,
|
|
1243
|
+
...report !== void 0 ? { report } : {}
|
|
1244
|
+
});
|
|
1245
|
+
unpackArchive(archive, join(stage, "tree"));
|
|
1246
|
+
if (!existsSync(join(stage, "tree", python.executable.slice(python.folder.length + 1)))) {
|
|
1247
|
+
throw new DeliveryError("\u0432 \u0430\u0440\u0445\u0438\u0432\u0435 \u043F\u0438\u0442\u043E\u043D\u0430 \u043D\u0435\u0442 \u0438\u043D\u0442\u0435\u0440\u043F\u0440\u0435\u0442\u0430\u0442\u043E\u0440\u0430, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u043D\u0430\u0437\u0432\u0430\u043B \u0437\u0430\u043C\u043E\u043A");
|
|
1248
|
+
}
|
|
1249
|
+
mkdirSync(dirname(python.folder), { recursive: true });
|
|
1250
|
+
if (!dirExists(python.folder)) renameSync(join(stage, "tree"), python.folder);
|
|
1251
|
+
} finally {
|
|
1252
|
+
rmSync(stage, { recursive: true, force: true });
|
|
1253
|
+
}
|
|
1254
|
+
return python.executable;
|
|
1255
|
+
}
|
|
1004
1256
|
var TAIL_MS = 10 * 6e4;
|
|
1005
1257
|
var AWAY_NOTE = "\u0421\u043A\u0430\u0436\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443: \u043C\u043E\u0436\u043D\u043E \u043E\u0442\u043E\u0439\u0442\u0438, \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440 \u043D\u0435 \u0443\u0441\u043D\u0451\u0442, \u043F\u043E\u043A\u0430 \u0438\u0434\u0451\u0442 \u0440\u0430\u0431\u043E\u0442\u0430. \u0422\u043E\u043B\u044C\u043A\u043E \u043A\u0440\u044B\u0448\u043A\u0443 \u043D\u043E\u0443\u0442\u0431\u0443\u043A\u0430 \u043D\u0435 \u0437\u0430\u043A\u0440\u044B\u0432\u0430\u0442\u044C.";
|
|
1006
1258
|
var realClock = {
|
|
@@ -1315,7 +1567,6 @@ function currentMachineFingerprint() {
|
|
|
1315
1567
|
return cached;
|
|
1316
1568
|
}
|
|
1317
1569
|
var execFileP = promisify(execFile);
|
|
1318
|
-
var INSIDE_PYTHON = ["python.exe", join("bin", "python3"), join("bin", "python")];
|
|
1319
1570
|
var FOREIGN_PYTHON_VARS = [
|
|
1320
1571
|
"PYTHONHOME",
|
|
1321
1572
|
"PYTHONPATH",
|
|
@@ -1521,94 +1772,44 @@ var Engine = class {
|
|
|
1521
1772
|
return null;
|
|
1522
1773
|
}
|
|
1523
1774
|
/**
|
|
1524
|
-
*
|
|
1775
|
+
* Питон по замку начинки (`engine/deps.lock.json`), если он уже в хранилище.
|
|
1525
1776
|
*
|
|
1526
|
-
* ⚠
|
|
1527
|
-
*
|
|
1528
|
-
*
|
|
1529
|
-
*
|
|
1530
|
-
*
|
|
1777
|
+
* ⚠ ТОЛЬКО СВОЙ. До 2026-09-24 здесь был «python3» из PATH на случай, когда
|
|
1778
|
+
* своего нет, а окружение новой версии собиралось перебором «свой → базовый
|
|
1779
|
+
* питон рабочей версии → системный». Claude Desktop подсунул питон Xcode 3.9,
|
|
1780
|
+
* тот не собрал окружение, и обновление у владельца не вставало целый день.
|
|
1781
|
+
* Решение владельца — «как node_modules»: свой питон по замку, чужого нет.
|
|
1531
1782
|
*/
|
|
1532
|
-
ourPython() {
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
if (existsSync(candidate)) return candidate;
|
|
1537
|
-
}
|
|
1538
|
-
return null;
|
|
1783
|
+
ourPython(place = this.place()) {
|
|
1784
|
+
if (place === null) return null;
|
|
1785
|
+
const python = lockedPython(place.engine, this.home());
|
|
1786
|
+
return python !== null && existsSync(python.executable) ? python.executable : null;
|
|
1539
1787
|
}
|
|
1540
1788
|
/**
|
|
1541
|
-
* Python для команд
|
|
1789
|
+
* Python для команд движка: окружение пака, а пока его нет — свой питон по
|
|
1790
|
+
* замку. Нет ни того, ни другого — путь, которого нет: `pythonTrouble`
|
|
1791
|
+
* ответит словами «позови setup», а не «spawn python3 ENOENT».
|
|
1542
1792
|
*
|
|
1543
|
-
*
|
|
1544
|
-
*
|
|
1545
|
-
*
|
|
1546
|
-
* системным python'ом, когда своего ещё нет.
|
|
1793
|
+
* ⚠ «python3» ИЗ PATH — ТОЛЬКО ПРИ `NAPARNIK_SYSTEM_TOOLS=1`: так тесты и
|
|
1794
|
+
* разработка гоняют движок из исходников без хранилища (та же переменная у
|
|
1795
|
+
* движка, `engine/media/ffmpeg.py`). У покупателя её нет.
|
|
1547
1796
|
*/
|
|
1548
1797
|
enginePython() {
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
/** Python подготовки кандидата — намеренно без fallback на venv старого пака. */
|
|
1552
|
-
bootstrapPython() {
|
|
1553
|
-
return this.bootstrapPythons()[0] ?? (platform() === "win32" ? "python" : "python3");
|
|
1798
|
+
const fallback = this.env["NAPARNIK_SYSTEM_TOOLS"] === "1" ? platform() === "win32" ? "python" : "python3" : join(this.home(), "deps", "python", "not-installed");
|
|
1799
|
+
return this.packPython() ?? this.ourPython() ?? fallback;
|
|
1554
1800
|
}
|
|
1555
1801
|
/**
|
|
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`.
|
|
1802
|
+
* Принести питон замка ЭТОГО кандидата (или взять уже лежащий) — им движок
|
|
1803
|
+
* кандидата доводит до замка всё остальное (`env-install --step env`).
|
|
1588
1804
|
*/
|
|
1589
|
-
|
|
1590
|
-
const
|
|
1591
|
-
if (
|
|
1592
|
-
|
|
1593
|
-
try {
|
|
1594
|
-
text2 = readFileSync(join(place.pack, ".venv", "pyvenv.cfg"), "utf8");
|
|
1595
|
-
} catch {
|
|
1596
|
-
return null;
|
|
1805
|
+
async bringPython(place, report) {
|
|
1806
|
+
const python = lockedPython(place.engine, this.home());
|
|
1807
|
+
if (python === null) {
|
|
1808
|
+
throw new Error(`\u043F\u043E\u0434 \u044D\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u0432 \u0437\u0430\u043C\u043A\u0435 \u043D\u0435\u0442 \u0441\u0431\u043E\u0440\u043A\u0438 \u043F\u0438\u0442\u043E\u043D\u0430. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043D\u0430\u043F\u0438\u0448\u0438 \u0431\u043E\u0442\u0443 ${KEY_SOURCE_BOT} \u2014 \u043F\u043E\u0434\u0431\u0435\u0440\u0451\u043C \u0441\u0431\u043E\u0440\u043A\u0443`);
|
|
1597
1809
|
}
|
|
1598
|
-
const
|
|
1599
|
-
|
|
1600
|
-
|
|
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;
|
|
1810
|
+
const executable = await bringPython(python, report);
|
|
1811
|
+
this.forgetPython();
|
|
1812
|
+
return executable;
|
|
1612
1813
|
}
|
|
1613
1814
|
/** Python ровно названного кандидата, а не текущей версии. */
|
|
1614
1815
|
candidatePython(place) {
|
|
@@ -1632,6 +1833,9 @@ var Engine = class {
|
|
|
1632
1833
|
pythonEnv() {
|
|
1633
1834
|
const env = { ...this.env, PYTHONUTF8: "1", PYTHONIOENCODING: "utf-8" };
|
|
1634
1835
|
for (const name of FOREIGN_PYTHON_VARS) delete env[name];
|
|
1836
|
+
for (const [name, value] of Object.entries(env)) {
|
|
1837
|
+
if (value !== void 0 && value.trim() !== "" && fromHost(value) === "") delete env[name];
|
|
1838
|
+
}
|
|
1635
1839
|
delete env["NAPARNIK_API_KEY"];
|
|
1636
1840
|
return env;
|
|
1637
1841
|
}
|
|
@@ -1641,12 +1845,7 @@ var Engine = class {
|
|
|
1641
1845
|
* Весь движок (включая проверку и установку) идёт через запуск python'а.
|
|
1642
1846
|
* Когда его нет, `execFile` бросает ENOENT, и клиентской нейросети
|
|
1643
1847
|
* доставалось «spawn python3 ENOENT» — текст, из которого человеку не понять
|
|
1644
|
-
* ничего.
|
|
1645
|
-
* недостижим по устройству: он сам запускается python'ом.
|
|
1646
|
-
*
|
|
1647
|
-
* На Windows есть отдельная беда: в PATH лежит заглушка Microsoft Store —
|
|
1648
|
-
* `python` там есть, он печатает рекламу магазина и выходит с кодом 9009.
|
|
1649
|
-
* Поэтому проверяем не наличие файла, а ответ на вопрос о версии.
|
|
1848
|
+
* ничего. Проверяем не наличие файла, а ответ на вопрос о версии.
|
|
1650
1849
|
*/
|
|
1651
1850
|
async pythonTrouble() {
|
|
1652
1851
|
if (this.pythonChecked !== void 0) return this.pythonChecked;
|
|
@@ -1662,7 +1861,7 @@ var Engine = class {
|
|
|
1662
1861
|
}
|
|
1663
1862
|
} catch {
|
|
1664
1863
|
}
|
|
1665
|
-
this.pythonChecked = "\
|
|
1864
|
+
this.pythonChecked = "\u0421\u0432\u043E\u0435\u0433\u043E \u043F\u0438\u0442\u043E\u043D\u0430 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043D\u0430 \u044D\u0442\u043E\u043C \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435 \u0435\u0449\u0451 \u043D\u0435\u0442 \u2014 \u043E\u043D \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 \u0434\u0432\u0438\u0436\u043A\u043E\u043C, \u043E\u0434\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u043E\u0439, \u0432 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F.\n\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0437\u043E\u0432\u0438 setup \u0441 what=all \u2014 \u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E \u0434\u0432\u0438\u0436\u043E\u043A \u0438 \u0432\u0441\u0451, \u0447\u0442\u043E \u0435\u043C\u0443 \u043D\u0443\u0436\u043D\u043E.";
|
|
1666
1865
|
return this.pythonChecked;
|
|
1667
1866
|
}
|
|
1668
1867
|
// ─── запуск ─────────────────────────────────────────────────────────────
|
|
@@ -13357,6 +13556,9 @@ function candidateVenvTrouble(dir, version2, place, requirePresent = false) {
|
|
|
13357
13556
|
if (venvStat.isSymbolicLink() || !venvStat.isDirectory()) return ".venv \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u0431\u044B\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u043E\u0439";
|
|
13358
13557
|
if (!realpathSync(venv).startsWith(buildReal + sep)) return ".venv \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u0432\u044B\u0448\u0435\u043B \u0437\u0430 \u043F\u0440\u0435\u0434\u0435\u043B\u044B \u0432\u0435\u0440\u0441\u0438\u0438";
|
|
13359
13558
|
const insideBuild = (path2) => path2 === buildReal || path2.startsWith(buildReal + sep);
|
|
13559
|
+
const store = join(dirname(dir), "deps", "python");
|
|
13560
|
+
const storeReal = existsSync(store) ? realpathSync(store) : null;
|
|
13561
|
+
const insideStore = (path2) => storeReal !== null && path2.startsWith(storeReal + sep);
|
|
13360
13562
|
const inspectedDirectories = /* @__PURE__ */ new Set();
|
|
13361
13563
|
const inspectTree = (folder, insideCriticalParent, insideSitePackages) => {
|
|
13362
13564
|
const folderReal = realpathSync(folder);
|
|
@@ -13370,8 +13572,10 @@ function candidateVenvTrouble(dir, version2, place, requirePresent = false) {
|
|
|
13370
13572
|
const inSitePackages = insideSitePackages || entry.name.toLowerCase() === "site-packages";
|
|
13371
13573
|
const stat = lstatSync(path2);
|
|
13372
13574
|
if (stat.isSymbolicLink()) {
|
|
13373
|
-
|
|
13575
|
+
const interpreter = /^(python(?:3(?:\.\d+)?)?|python\.exe)$/i.test(entry.name);
|
|
13576
|
+
if (inCriticalParent || inSitePackages || interpreter) {
|
|
13374
13577
|
const actual = realpathSync(path2);
|
|
13578
|
+
if (!insideBuild(actual) && interpreter && insideStore(actual)) continue;
|
|
13375
13579
|
if (!insideBuild(actual)) return `${path2} \u0432\u0435\u0434\u0451\u0442 \u0437\u0430 \u043F\u0440\u0435\u0434\u0435\u043B\u044B \u0432\u0435\u0440\u0441\u0438\u0438 \u0432 ${actual}`;
|
|
13376
13580
|
if (statSync(path2).isDirectory()) {
|
|
13377
13581
|
const trouble = inspectTree(path2, inCriticalParent, inSitePackages);
|
|
@@ -13956,7 +14160,7 @@ function tidyOld2(engine) {
|
|
|
13956
14160
|
}
|
|
13957
14161
|
function candidateDeps(engine) {
|
|
13958
14162
|
const value = engine;
|
|
13959
|
-
return typeof value.home === "function" && typeof value.placeForVersion === "function" && typeof value.
|
|
14163
|
+
return typeof value.home === "function" && typeof value.placeForVersion === "function" && typeof value.bringPython === "function" && typeof value.candidatePython === "function" && typeof value.runWith === "function";
|
|
13960
14164
|
}
|
|
13961
14165
|
async function deploy(engine, manifest, trial = probe, key, hooks = {}) {
|
|
13962
14166
|
const place = engine.place();
|
|
@@ -13999,6 +14203,9 @@ async function deployLocked(engine, manifest, trial, key, hooks) {
|
|
|
13999
14203
|
text: `\u041F\u0430\u043F\u043A\u0430 \u0432\u0435\u0440\u0441\u0438\u0438 ${manifest.version} \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u043D\u043E digest \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u0434\u0440\u0443\u0433\u043E\u0439 \u0438\u043B\u0438 \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043D: \u0447\u0443\u0436\u043E\u0439 final \u043D\u0435 \u043F\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043B \u0438 \u043D\u0435 \u0443\u0434\u0430\u043B\u044F\u043B. \u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0438\u0441\u044B\u0432\u0430\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0432\u044B\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u0434\u0440\u0443\u0433\u043E\u0435 \u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0435 \u043F\u043E\u0434 \u043D\u043E\u0432\u044B\u043C \u043D\u043E\u043C\u0435\u0440\u043E\u043C \u0432\u0435\u0440\u0441\u0438\u0438.`
|
|
14000
14204
|
};
|
|
14001
14205
|
}
|
|
14206
|
+
if (candidate.state === "blocked" && currentVersion(dir) !== manifest.version && pollutedPayload(dest, candidate)) {
|
|
14207
|
+
keepBroken(dir, manifest.version, "\u0424\u0430\u0439\u043B\u044B \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0438\u0441\u044C \u043F\u043E\u0441\u043B\u0435 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044F \u2014 \u043E\u043F\u0438\u0441\u044C \u0431\u0430\u0439\u0442\u043E\u0432 \u043D\u0435 \u0441\u043E\u0448\u043B\u0430\u0441\u044C; \u0441\u043A\u0430\u0447\u0430\u043D \u0437\u0430\u043D\u043E\u0432\u043E.");
|
|
14208
|
+
}
|
|
14002
14209
|
}
|
|
14003
14210
|
if (!existsSync(dest)) {
|
|
14004
14211
|
const stage = createVersionStage(dir, manifest.version);
|
|
@@ -14125,16 +14332,12 @@ function recoverPublicationLocked(dir) {
|
|
|
14125
14332
|
}
|
|
14126
14333
|
clearPublication(dir, publication.operationId);
|
|
14127
14334
|
}
|
|
14128
|
-
async function continuePreparedCandidate(engine, expected,
|
|
14335
|
+
async function continuePreparedCandidate(engine, expected, trial = probe, extras = "now") {
|
|
14129
14336
|
try {
|
|
14130
14337
|
return await withVersionLock(engine.versionsDir(), async () => {
|
|
14131
|
-
const checked =
|
|
14338
|
+
const checked = preparedCandidateBeforeActivation(engine, expected);
|
|
14132
14339
|
if (!checked.ok) return checked.outcome;
|
|
14133
|
-
|
|
14134
|
-
const after = preparedCandidateAfterBootstrap(engine, checked.candidate);
|
|
14135
|
-
if (!after.ok) return after.outcome;
|
|
14136
|
-
if (!bootstrapped.ok) return bootstrapped;
|
|
14137
|
-
return activatePreparedCandidateLocked(engine, after.candidate, trial, extras);
|
|
14340
|
+
return activatePreparedCandidateLocked(engine, checked.candidate, trial, extras);
|
|
14138
14341
|
});
|
|
14139
14342
|
} catch (trouble) {
|
|
14140
14343
|
if (trouble instanceof VersionLockError) return { ok: false, text: trouble.message };
|
|
@@ -14145,7 +14348,7 @@ async function continuePreparedCandidate(engine, expected, bootstrap, trial = pr
|
|
|
14145
14348
|
};
|
|
14146
14349
|
}
|
|
14147
14350
|
}
|
|
14148
|
-
function
|
|
14351
|
+
function preparedCandidateBeforeActivation(engine, expected) {
|
|
14149
14352
|
const dir = engine.versionsDir();
|
|
14150
14353
|
const candidate = readCandidate(dir);
|
|
14151
14354
|
if (candidate === null || !sameCandidateState(candidate, expected)) {
|
|
@@ -14153,21 +14356,21 @@ function preparedCandidateBeforeBootstrap(engine, expected) {
|
|
|
14153
14356
|
ok: false,
|
|
14154
14357
|
outcome: {
|
|
14155
14358
|
ok: false,
|
|
14156
|
-
text: "\u041F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043B\u0435\u043D\u043D\u044B\u0439 candidate \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0441\u044F \u0434\u043E
|
|
14359
|
+
text: "\u041F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043B\u0435\u043D\u043D\u044B\u0439 candidate \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0441\u044F \u0434\u043E \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F \u2014 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u043B \u0438 \u043D\u0435 \u0437\u0430\u0442\u0438\u0440\u0430\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup."
|
|
14157
14360
|
}
|
|
14158
14361
|
};
|
|
14159
14362
|
}
|
|
14160
14363
|
const place = engine.placeForVersion(candidate.version);
|
|
14161
14364
|
if (place === null) {
|
|
14162
|
-
return { ok: false, outcome: blockCandidate(dir, candidate, "\u0423 prepared-\u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435\u0442 engine/console.py \u2014
|
|
14365
|
+
return { ok: false, outcome: blockCandidate(dir, candidate, "\u0423 prepared-\u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435\u0442 engine/console.py \u2014 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u043B.") };
|
|
14163
14366
|
}
|
|
14164
14367
|
const proofTrouble = candidateProofTrouble(dir, candidate, place);
|
|
14165
14368
|
if (proofTrouble !== null) {
|
|
14166
|
-
return { ok: false, outcome: blockCandidate(dir, candidate, `${proofTrouble}
|
|
14369
|
+
return { ok: false, outcome: blockCandidate(dir, candidate, `${proofTrouble} \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u043B; current \u043D\u0435 \u043C\u0435\u043D\u044F\u043B.`) };
|
|
14167
14370
|
}
|
|
14168
14371
|
const venvTrouble = candidateVenvTrouble(dir, candidate.version, place, false);
|
|
14169
14372
|
if (venvTrouble !== null) {
|
|
14170
|
-
return { ok: false, outcome: blockCandidate(dir, candidate, `${venvTrouble}
|
|
14373
|
+
return { ok: false, outcome: blockCandidate(dir, candidate, `${venvTrouble} \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u043B; current \u043D\u0435 \u043C\u0435\u043D\u044F\u043B.`) };
|
|
14171
14374
|
}
|
|
14172
14375
|
const current = currentVersion(dir);
|
|
14173
14376
|
if (current !== candidate.baseCurrent) {
|
|
@@ -14175,58 +14378,14 @@ function preparedCandidateBeforeBootstrap(engine, expected) {
|
|
|
14175
14378
|
ok: false,
|
|
14176
14379
|
outcome: {
|
|
14177
14380
|
ok: false,
|
|
14178
|
-
text: `current \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0441\u044F \u0434\u043E
|
|
14381
|
+
text: `current \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0441\u044F \u0434\u043E \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F (${candidate.baseCurrent ?? "\u043D\u0435\u0442"} \u2192 ${current ?? "\u043D\u0435\u0442"}) \u2014 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u043A\u0430\u043B \u0438 \u043D\u0435 \u0437\u0430\u0442\u0438\u0440\u0430\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0437\u0430\u043D\u043E\u0432\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0438\u0442\u0435 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 setup.`
|
|
14179
14382
|
}
|
|
14180
14383
|
};
|
|
14181
14384
|
}
|
|
14182
14385
|
return { ok: true, candidate, place };
|
|
14183
14386
|
}
|
|
14184
|
-
function
|
|
14185
|
-
|
|
14186
|
-
const candidate = readCandidate(dir);
|
|
14187
|
-
if (candidate === null || !sameCandidateState(candidate, before)) {
|
|
14188
|
-
return {
|
|
14189
|
-
ok: false,
|
|
14190
|
-
outcome: {
|
|
14191
|
-
ok: false,
|
|
14192
|
-
text: "candidate \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0441\u044F \u0432\u043E \u0432\u0440\u0435\u043C\u044F bootstrap \u2014 \u0447\u0443\u0436\u043E\u0439 \u0443\u043A\u0430\u0437\u0430\u0442\u0435\u043B\u044C \u043D\u0435 \u0437\u0430\u0442\u0438\u0440\u0430\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup."
|
|
14193
|
-
}
|
|
14194
|
-
};
|
|
14195
|
-
}
|
|
14196
|
-
if (currentVersion(dir) !== before.baseCurrent) {
|
|
14197
|
-
return {
|
|
14198
|
-
ok: false,
|
|
14199
|
-
outcome: {
|
|
14200
|
-
ok: false,
|
|
14201
|
-
text: "current \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0441\u044F \u0432\u043E \u0432\u0440\u0435\u043C\u044F bootstrap \u2014 \u0447\u0443\u0436\u043E\u0439 current \u043D\u0435 \u0437\u0430\u0442\u0438\u0440\u0430\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup."
|
|
14202
|
-
}
|
|
14203
|
-
};
|
|
14204
|
-
}
|
|
14205
|
-
const place = engine.placeForVersion(candidate.version);
|
|
14206
|
-
if (place === null) {
|
|
14207
|
-
return {
|
|
14208
|
-
ok: false,
|
|
14209
|
-
outcome: {
|
|
14210
|
-
ok: false,
|
|
14211
|
-
text: "\u041F\u0443\u0442\u044C prepared-\u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0441\u044F \u0432\u043E \u0432\u0440\u0435\u043C\u044F bootstrap \u2014 current \u043D\u0435 \u043C\u0435\u043D\u044F\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup."
|
|
14212
|
-
}
|
|
14213
|
-
};
|
|
14214
|
-
}
|
|
14215
|
-
const proofTrouble = candidateProofTrouble(dir, candidate, place);
|
|
14216
|
-
const venvTrouble = candidateVenvTrouble(dir, candidate.version, place, false);
|
|
14217
|
-
if (proofTrouble !== null || venvTrouble !== null) {
|
|
14218
|
-
return {
|
|
14219
|
-
ok: false,
|
|
14220
|
-
outcome: {
|
|
14221
|
-
ok: false,
|
|
14222
|
-
text: `${proofTrouble ?? venvTrouble} \u043F\u043E\u0441\u043B\u0435 bootstrap \u2014 candidate \u0438 current \u043D\u0435 \u0437\u0430\u0442\u0438\u0440\u0430\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup \u043F\u043E\u0441\u043B\u0435 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u0444\u0430\u0439\u043B\u043E\u0432 \u043D\u0430 \u0434\u0438\u0441\u043A\u0435.`
|
|
14223
|
-
}
|
|
14224
|
-
};
|
|
14225
|
-
}
|
|
14226
|
-
return { ok: true, candidate, place };
|
|
14227
|
-
}
|
|
14228
|
-
function blockCandidate(dir, candidate, text2) {
|
|
14229
|
-
if (!sameCandidateState(readCandidate(dir), candidate)) {
|
|
14387
|
+
function blockCandidate(dir, candidate, text2) {
|
|
14388
|
+
if (!sameCandidateState(readCandidate(dir), candidate)) {
|
|
14230
14389
|
return {
|
|
14231
14390
|
ok: false,
|
|
14232
14391
|
text: "\u0423\u043A\u0430\u0437\u0430\u0442\u0435\u043B\u044C candidate \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0441\u044F \u0432\u043E \u0432\u0440\u0435\u043C\u044F \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438 \u2014 \u0447\u0443\u0436\u043E\u0439 \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442 \u043D\u0435 \u0437\u0430\u043F\u0438\u0441\u044B\u0432\u0430\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup."
|
|
@@ -14239,7 +14398,7 @@ function blockCandidate(dir, candidate, text2) {
|
|
|
14239
14398
|
text: text2.includes("\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C:") ? `${lead}
|
|
14240
14399
|
${text2}` : `${lead}
|
|
14241
14400
|
${text2}
|
|
14242
|
-
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \
|
|
14401
|
+
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043C\u043E\u043D\u0442\u0438\u0440\u0443\u0439 \u043D\u0430 \u043F\u0440\u0435\u0436\u043D\u0435\u0439. \u0421\u0440\u0430\u0437\u0443 setup \u043D\u0435 \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0439 \u2014 \u043E\u0442\u043A\u0430\u0436\u0435\u0442 \u0442\u0435\u043C \u0436\u0435; \xAB\u043E\u0431\u043D\u043E\u0432\u0438\xBB \u0435\u0449\u0451 \u0440\u0430\u0437 \u2014 \u043F\u043E\u0437\u0436\u0435 \u0438\u043B\u0438 \u043A\u043E\u0433\u0434\u0430 \u0432\u044B\u0439\u0434\u0435\u0442 \u0441\u043B\u0435\u0434\u0443\u044E\u0449\u0430\u044F \u0432\u0435\u0440\u0441\u0438\u044F.`
|
|
14243
14402
|
};
|
|
14244
14403
|
}
|
|
14245
14404
|
function commandWords(trouble) {
|
|
@@ -14260,12 +14419,25 @@ function candidateProofTrouble(dir, candidate, place) {
|
|
|
14260
14419
|
if (pathTrouble !== null) return pathTrouble;
|
|
14261
14420
|
try {
|
|
14262
14421
|
const actual = payloadProof(join(dir, candidate.version));
|
|
14263
|
-
if (!samePayloadProof(candidate.payload, actual))
|
|
14422
|
+
if (!samePayloadProof(candidate.payload, actual)) {
|
|
14423
|
+
const said = "\u0424\u0430\u0439\u043B\u044B \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0438\u0437\u043C\u0435\u043D\u0438\u043B\u0438\u0441\u044C \u043F\u043E\u0441\u043B\u0435 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044F (\u043E\u043F\u0438\u0441\u044C \u0431\u0430\u0439\u0442\u043E\u0432 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430 \u043D\u0435 \u0441\u043E\u0448\u043B\u0430\u0441\u044C).";
|
|
14424
|
+
noteInstallFault("candidate-payload", new Error(said));
|
|
14425
|
+
return said;
|
|
14426
|
+
}
|
|
14264
14427
|
} catch (trouble) {
|
|
14265
|
-
return `\u0424\u0430\
|
|
14428
|
+
return `\u0424\u0430\u0439\u043B\u044B \u043D\u043E\u0432\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C (\u043E\u043F\u0438\u0441\u044C \u0431\u0430\u0439\u0442\u043E\u0432 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442\u0430): ${describeFailure(trouble)}`;
|
|
14266
14429
|
}
|
|
14267
14430
|
return null;
|
|
14268
14431
|
}
|
|
14432
|
+
function pollutedPayload(dest, candidate) {
|
|
14433
|
+
if (candidate.payload === void 0) return false;
|
|
14434
|
+
try {
|
|
14435
|
+
removePythonBytecode(dest);
|
|
14436
|
+
return !samePayloadProof(candidate.payload, payloadProof(dest));
|
|
14437
|
+
} catch {
|
|
14438
|
+
return false;
|
|
14439
|
+
}
|
|
14440
|
+
}
|
|
14269
14441
|
function samePreparedCandidate(actual, expected) {
|
|
14270
14442
|
return actual !== null && actual.version === expected.version && actual.sha256 === expected.sha256 && actual.state === "prepared" && actual.baseCurrent === expected.baseCurrent && actual.environment === expected.environment && actual.mineDigest === expected.mineDigest && actual.payload !== void 0 && expected.payload !== void 0 && samePayloadProof(actual.payload, expected.payload);
|
|
14271
14443
|
}
|
|
@@ -14286,71 +14458,6 @@ async function runCandidateWith(engine, dir, version2, executable, place, args,
|
|
|
14286
14458
|
removePythonBytecode(join(dir, version2));
|
|
14287
14459
|
return result;
|
|
14288
14460
|
}
|
|
14289
|
-
async function prepareCopiedCandidateVenv(engine, dir, version2, place) {
|
|
14290
|
-
const trouble = candidateVenvTrouble(dir, version2, place, false);
|
|
14291
|
-
if (trouble !== null) throw new Error(trouble);
|
|
14292
|
-
const venv = join(place.pack, ".venv");
|
|
14293
|
-
const existingPython = engine.candidatePython(place);
|
|
14294
|
-
const ready = existingPython !== null && await candidatePipReady(engine, existingPython);
|
|
14295
|
-
if (!ready) {
|
|
14296
|
-
rmSync(venv, { recursive: true, force: true });
|
|
14297
|
-
if (engine.prepareCandidateVenv !== void 0) {
|
|
14298
|
-
await engine.prepareCandidateVenv(place);
|
|
14299
|
-
} else {
|
|
14300
|
-
await copiedVenv(engine, venv);
|
|
14301
|
-
}
|
|
14302
|
-
}
|
|
14303
|
-
const createdTrouble = candidateVenvTrouble(dir, version2, place, true);
|
|
14304
|
-
if (createdTrouble !== null) throw new Error(createdTrouble);
|
|
14305
|
-
const python = engine.candidatePython(place);
|
|
14306
|
-
if (python === null || !await candidatePipReady(engine, python)) {
|
|
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");
|
|
14308
|
-
}
|
|
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
|
-
}
|
|
14334
|
-
async function candidatePipReady(engine, python) {
|
|
14335
|
-
if (engine.candidatePipReady !== void 0) return engine.candidatePipReady(python);
|
|
14336
|
-
const { execFile: execFile3 } = await import('child_process');
|
|
14337
|
-
const { promisify: promisify2 } = await import('util');
|
|
14338
|
-
const env = { ...engine.pythonEnv(), PYTHONDONTWRITEBYTECODE: "1" };
|
|
14339
|
-
delete env["PYTHONHOME"];
|
|
14340
|
-
delete env["PYTHONPATH"];
|
|
14341
|
-
delete env["VIRTUAL_ENV"];
|
|
14342
|
-
delete env["__PYVENV_LAUNCHER__"];
|
|
14343
|
-
try {
|
|
14344
|
-
await promisify2(execFile3)(python, ["-B", "-m", "pip", "--version"], {
|
|
14345
|
-
timeout: 6e4,
|
|
14346
|
-
encoding: "utf8",
|
|
14347
|
-
env
|
|
14348
|
-
});
|
|
14349
|
-
return true;
|
|
14350
|
-
} catch {
|
|
14351
|
-
return false;
|
|
14352
|
-
}
|
|
14353
|
-
}
|
|
14354
14461
|
async function compatibilityProof(engine, dir, version2, python, place) {
|
|
14355
14462
|
let output = "";
|
|
14356
14463
|
try {
|
|
@@ -14413,24 +14520,12 @@ async function activatePreparedCandidateLocked(engine, manifest, trial, extras =
|
|
|
14413
14520
|
const resumesReadyBeforeCurrent = candidate.state === "ready" && current !== candidate.version;
|
|
14414
14521
|
if (candidate.environment !== "ready" || resumesReadyBeforeCurrent) {
|
|
14415
14522
|
try {
|
|
14416
|
-
|
|
14417
|
-
await runCandidateWith(
|
|
14418
|
-
engine,
|
|
14419
|
-
dir,
|
|
14420
|
-
candidate.version,
|
|
14421
|
-
engine.bootstrapPython(),
|
|
14422
|
-
place,
|
|
14423
|
-
["env-install", "--pack", place.pack, "--step", "ffmpeg", "--consent"],
|
|
14424
|
-
{ timeout: 60 * 6e4 },
|
|
14425
|
-
false
|
|
14426
|
-
);
|
|
14427
|
-
}
|
|
14428
|
-
await prepareCopiedCandidateVenv(engine, dir, candidate.version, place);
|
|
14523
|
+
const base = await engine.bringPython(place);
|
|
14429
14524
|
await runCandidateWith(
|
|
14430
14525
|
engine,
|
|
14431
14526
|
dir,
|
|
14432
14527
|
candidate.version,
|
|
14433
|
-
|
|
14528
|
+
base,
|
|
14434
14529
|
place,
|
|
14435
14530
|
[
|
|
14436
14531
|
"env-install",
|
|
@@ -14442,7 +14537,7 @@ async function activatePreparedCandidateLocked(engine, manifest, trial, extras =
|
|
|
14442
14537
|
...extras === "later" ? requiredOnly(dir, candidate.version) : []
|
|
14443
14538
|
],
|
|
14444
14539
|
{ timeout: 60 * 6e4 },
|
|
14445
|
-
|
|
14540
|
+
false
|
|
14446
14541
|
);
|
|
14447
14542
|
const installedVenvTrouble = candidateVenvTrouble(dir, candidate.version, place, true);
|
|
14448
14543
|
if (installedVenvTrouble !== null) throw new Error(installedVenvTrouble);
|
|
@@ -14698,212 +14793,6 @@ function rollback(engine) {
|
|
|
14698
14793
|
};
|
|
14699
14794
|
}
|
|
14700
14795
|
}
|
|
14701
|
-
var DeliveryError = class extends Error {
|
|
14702
|
-
constructor(message) {
|
|
14703
|
-
super(message);
|
|
14704
|
-
this.name = "DeliveryTrouble";
|
|
14705
|
-
}
|
|
14706
|
-
};
|
|
14707
|
-
async function downloadFile(opts) {
|
|
14708
|
-
const { url: url2, dest, sha256, bytes, timeoutMs = 30 * 6e4, report, key } = opts;
|
|
14709
|
-
if (!/^[a-f0-9]{64}$/.test(sha256)) {
|
|
14710
|
-
throw new DeliveryError(`\u043D\u0435\u0447\u0435\u043C \u0441\u0432\u0435\u0440\u0438\u0442\u044C \u0441\u043A\u0430\u0447\u0430\u043D\u043D\u043E\u0435: \u0441\u0443\u043C\u043C\u0430 \xAB${sha256}\xBB \u043D\u0435 \u043F\u043E\u0445\u043E\u0436\u0430 \u043D\u0430 sha256`);
|
|
14711
|
-
}
|
|
14712
|
-
mkdirSync(dirname(dest), { recursive: true });
|
|
14713
|
-
const temp = `${dest}.downloading-${process.pid}-${randomUUID()}`;
|
|
14714
|
-
const guard = new AbortController();
|
|
14715
|
-
const timer = setTimeout(() => {
|
|
14716
|
-
guard.abort();
|
|
14717
|
-
}, timeoutMs);
|
|
14718
|
-
try {
|
|
14719
|
-
const response = await fetch(url2, {
|
|
14720
|
-
signal: guard.signal,
|
|
14721
|
-
redirect: "follow",
|
|
14722
|
-
...key !== null && key !== void 0 ? { headers: { authorization: `Bearer ${key}` } } : {}
|
|
14723
|
-
});
|
|
14724
|
-
const hasKey = key !== null && key !== void 0;
|
|
14725
|
-
if (!response.ok) {
|
|
14726
|
-
if (response.status === 401 || response.status === 403) {
|
|
14727
|
-
if (response.status === 403 && hasKey) {
|
|
14728
|
-
throw new DeliveryError(
|
|
14729
|
-
`${url2} \u043D\u0435 \u043E\u0442\u0434\u0430\u0451\u0442 \u0444\u0430\u0439\u043B: \u043A\u043B\u044E\u0447 \u043F\u0440\u0438\u0437\u043D\u0430\u043D, \u043D\u043E \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438 \u043D\u0430 \u043C\u043E\u043D\u0442\u0430\u0436 \u043D\u0435\u0442. \u0421\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u0435 \u043D\u043E\u0432\u043E\u0433\u043E \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E, \u043F\u043E\u043A\u0430 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u0430\u043A\u0442\u0438\u0432\u043D\u0430; \u0432\u0441\u0451, \u0447\u0442\u043E \u0443\u0436\u0435 \u0441\u0442\u043E\u0438\u0442 \u043D\u0430 \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435, \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043E\u0442\u0430\u0442\u044C. \u041F\u0440\u043E\u0434\u043B\u0438\u0442\u0435 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0443 \u0432 \u0431\u043E\u0442\u0435 \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435.`
|
|
14730
|
-
);
|
|
14731
|
-
}
|
|
14732
|
-
throw new DeliveryError(
|
|
14733
|
-
!hasKey ? `${url2} \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043A\u043B\u044E\u0447 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430, \u0430 \u043E\u043D \u043D\u0435 \u0437\u0430\u0434\u0430\u043D. \u0412\u043F\u0438\u0448\u0438\u0442\u0435 \u043A\u043B\u044E\u0447 \u0432 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044E MCP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430 (\u0441\u0435\u043A\u0446\u0438\u044F env) \u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u0435 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0443 \u2014 \u041A\u043B\u043E\u0434\u0430 \u0438\u043B\u0438 Codex.` : `${url2} \u043D\u0435 \u043F\u0440\u0438\u043D\u044F\u043B \u043A\u043B\u044E\u0447 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430 (${response.status}). \u0421\u043A\u043E\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043E, \u043A\u043B\u044E\u0447 \u0437\u0430\u043C\u0435\u043D\u0451\u043D \u0431\u043E\u043B\u0435\u0435 \u043D\u043E\u0432\u044B\u043C: \u043D\u043E\u0432\u044B\u0439 \u0444\u0430\u0439\u043B \u0438\u0437 \u0431\u043E\u0442\u0430 \u0443\u0436\u0435 \u043F\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D \u0437\u0434\u0435\u0441\u044C \u0438\u043B\u0438 \u043D\u0430 \u0434\u0440\u0443\u0433\u043E\u043C \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435. \u0412\u043E\u0437\u044C\u043C\u0438\u0442\u0435 \u043F\u043E\u0441\u043B\u0435\u0434\u043D\u0438\u0439 \u0444\u0430\u0439\u043B \u0443 \u0431\u043E\u0442\u0430 ${KEY_SOURCE_BOT} \u0438 \u043F\u043E\u0441\u0442\u0430\u0432\u044C\u0442\u0435 \u0435\u0433\u043E.`
|
|
14734
|
-
);
|
|
14735
|
-
}
|
|
14736
|
-
throw new DeliveryError(`${url2} \u043E\u0442\u0432\u0435\u0442\u0438\u043B ${response.status} ${response.statusText}`);
|
|
14737
|
-
}
|
|
14738
|
-
const body = await response.arrayBuffer();
|
|
14739
|
-
const buffer = Buffer.from(body);
|
|
14740
|
-
const sum = createHash("sha256").update(buffer).digest("hex");
|
|
14741
|
-
if (bytes !== void 0 && buffer.length !== bytes) {
|
|
14742
|
-
throw new DeliveryError(
|
|
14743
|
-
looksLikeHtml(buffer) ? `\u043F\u043E \u0430\u0434\u0440\u0435\u0441\u0443 ${url2} \u043B\u0435\u0436\u0438\u0442 \u043D\u0435 \u0430\u0440\u0445\u0438\u0432, \u0430 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u2014 \u0444\u0430\u0439\u043B \u0435\u0449\u0451 \u043D\u0435 \u0432\u044B\u043B\u043E\u0436\u0435\u043D.` : `\u0441\u043A\u0430\u0447\u0430\u043B\u043E\u0441\u044C ${buffer.length} \u0431\u0430\u0439\u0442 \u0432\u043C\u0435\u0441\u0442\u043E ${bytes} \u2014 \u0441\u0432\u044F\u0437\u044C \u043E\u0431\u043E\u0440\u0432\u0430\u043B\u0430\u0441\u044C, \u043F\u043E\u0432\u0442\u043E\u0440\u0438.`
|
|
14744
|
-
);
|
|
14745
|
-
}
|
|
14746
|
-
if (sum !== sha256) {
|
|
14747
|
-
throw new DeliveryError(
|
|
14748
|
-
looksLikeHtml(buffer) ? `\u043F\u043E \u0430\u0434\u0440\u0435\u0441\u0443 ${url2} \u043B\u0435\u0436\u0438\u0442 \u043D\u0435 \u0430\u0440\u0445\u0438\u0432, \u0430 \u0432\u0435\u0431-\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u2014 \u0444\u0430\u0439\u043B \u0435\u0449\u0451 \u043D\u0435 \u0432\u044B\u043B\u043E\u0436\u0435\u043D.` : `\u0441\u043A\u0430\u0447\u0430\u043D\u043D\u043E\u0435 \u043D\u0435 \u0441\u043E\u0432\u043F\u0430\u043B\u043E \u0441 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u043E\u0439 \u0441\u0443\u043C\u043C\u043E\u0439.
|
|
14749
|
-
\u0436\u0434\u0430\u043B\u0438 ${sha256}
|
|
14750
|
-
\u0432\u044B\u0448\u043B\u043E ${sum}
|
|
14751
|
-
\u041F\u043E\u0432\u0442\u043E\u0440\u0438; \u0435\u0441\u043B\u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u044F\u0435\u0442\u0441\u044F \u2014 \u0444\u0430\u0439\u043B \u043F\u043E\u0434\u043C\u0435\u043D\u0451\u043D \u0438\u043B\u0438 \u0431\u0438\u0442\u044B\u0439, \u0441\u0442\u0430\u0432\u0438\u0442\u044C \u0435\u0433\u043E \u043D\u0435\u043B\u044C\u0437\u044F.`
|
|
14752
|
-
);
|
|
14753
|
-
}
|
|
14754
|
-
writeFileSync(temp, buffer);
|
|
14755
|
-
if (existsSync(dest)) {
|
|
14756
|
-
throw new DeliveryError(
|
|
14757
|
-
`\u0444\u0430\u0439\u043B ${dest} \u0443\u0436\u0435 \u0437\u0430\u043D\u044F\u043B \u0434\u0440\u0443\u0433\u043E\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u2014 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0443\u0434\u0430\u043B\u044F\u043B. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 \u043E\u043F\u0435\u0440\u0430\u0446\u0438\u044E \u0441 \u043D\u043E\u0432\u044B\u043C staging.`
|
|
14758
|
-
);
|
|
14759
|
-
}
|
|
14760
|
-
renameSync(temp, dest);
|
|
14761
|
-
report?.(`\u0441\u043A\u0430\u0447\u0430\u043D\u043E ${Math.round(buffer.length / 1024 / 1024)} \u041C\u0411`);
|
|
14762
|
-
return { file: dest, bytes: buffer.length, sha256: sum };
|
|
14763
|
-
} catch (trouble) {
|
|
14764
|
-
rmSync(temp, { force: true });
|
|
14765
|
-
if (trouble instanceof DeliveryError) throw trouble;
|
|
14766
|
-
if (guard.signal.aborted) {
|
|
14767
|
-
throw new DeliveryError(`${url2} \u043D\u0435 \u043E\u0442\u0434\u0430\u043B \u0444\u0430\u0439\u043B \u0437\u0430 ${Math.round(timeoutMs / 6e4)} \u043C\u0438\u043D.`);
|
|
14768
|
-
}
|
|
14769
|
-
throw new DeliveryError(`\u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0441\u043A\u0430\u0447\u0430\u0442\u044C ${url2}: ${describeFailure(trouble)}`);
|
|
14770
|
-
} finally {
|
|
14771
|
-
clearTimeout(timer);
|
|
14772
|
-
}
|
|
14773
|
-
}
|
|
14774
|
-
function looksLikeHtml(buffer) {
|
|
14775
|
-
const start = buffer.subarray(0, 200).toString("latin1").trimStart().toLowerCase();
|
|
14776
|
-
return start.startsWith("<!doctype html") || start.startsWith("<html");
|
|
14777
|
-
}
|
|
14778
|
-
var BLOCK = 512;
|
|
14779
|
-
function tarEntries(data) {
|
|
14780
|
-
const entries = [];
|
|
14781
|
-
let offset = 0;
|
|
14782
|
-
let longName = null;
|
|
14783
|
-
let longTarget = null;
|
|
14784
|
-
while (offset + BLOCK <= data.length) {
|
|
14785
|
-
const header = data.subarray(offset, offset + BLOCK);
|
|
14786
|
-
if (header.every((b) => b === 0)) break;
|
|
14787
|
-
const name = fieldLine(header, 0, 100);
|
|
14788
|
-
const mode = octal(header, 100, 8);
|
|
14789
|
-
const size = fieldSize(header, 124, 12);
|
|
14790
|
-
const type = String.fromCharCode(header[156]);
|
|
14791
|
-
const target = fieldLine(header, 157, 100);
|
|
14792
|
-
const prefix = fieldLine(header, 345, 155);
|
|
14793
|
-
offset += BLOCK;
|
|
14794
|
-
const body = data.subarray(offset, offset + size);
|
|
14795
|
-
offset += Math.ceil(size / BLOCK) * BLOCK;
|
|
14796
|
-
if (type === "L") {
|
|
14797
|
-
longName = body.toString("utf8").replace(/\0+$/, "");
|
|
14798
|
-
continue;
|
|
14799
|
-
}
|
|
14800
|
-
if (type === "K") {
|
|
14801
|
-
longTarget = body.toString("utf8").replace(/\0+$/, "");
|
|
14802
|
-
continue;
|
|
14803
|
-
}
|
|
14804
|
-
if (type === "x") {
|
|
14805
|
-
const fields = parsePax(body);
|
|
14806
|
-
if (fields["path"] !== void 0) longName = fields["path"];
|
|
14807
|
-
if (fields["linkpath"] !== void 0) longTarget = fields["linkpath"];
|
|
14808
|
-
continue;
|
|
14809
|
-
}
|
|
14810
|
-
if (type === "g") continue;
|
|
14811
|
-
const full = longName ?? (prefix !== "" ? `${prefix}/${name}` : name);
|
|
14812
|
-
const linkTarget = longTarget ?? target;
|
|
14813
|
-
longName = null;
|
|
14814
|
-
longTarget = null;
|
|
14815
|
-
const kind = type === "5" ? "dir" : type === "2" ? "symlink" : type === "1" ? "hardlink" : "file";
|
|
14816
|
-
if (type !== "" && type !== "0" && type !== "\0" && kind === "file" && type !== "7") continue;
|
|
14817
|
-
entries.push({ name: full, kind, mode, body, target: linkTarget });
|
|
14818
|
-
}
|
|
14819
|
-
return entries;
|
|
14820
|
-
}
|
|
14821
|
-
function parsePax(body) {
|
|
14822
|
-
const fields = {};
|
|
14823
|
-
let offset = 0;
|
|
14824
|
-
while (offset < body.length) {
|
|
14825
|
-
const space = body.indexOf(32, offset);
|
|
14826
|
-
if (space === -1) break;
|
|
14827
|
-
const length = Number.parseInt(body.subarray(offset, space).toString("ascii"), 10);
|
|
14828
|
-
if (!Number.isFinite(length) || length <= 0 || offset + length > body.length) break;
|
|
14829
|
-
const entry = body.subarray(space + 1, offset + length).toString("utf8").replace(/\n$/, "");
|
|
14830
|
-
const equal = entry.indexOf("=");
|
|
14831
|
-
if (equal > 0) fields[entry.slice(0, equal)] = entry.slice(equal + 1);
|
|
14832
|
-
offset += length;
|
|
14833
|
-
}
|
|
14834
|
-
return fields;
|
|
14835
|
-
}
|
|
14836
|
-
function fieldLine(header, start, length) {
|
|
14837
|
-
const chunk = header.subarray(start, start + length);
|
|
14838
|
-
const end = chunk.indexOf(0);
|
|
14839
|
-
return chunk.subarray(0, end === -1 ? chunk.length : end).toString("utf8");
|
|
14840
|
-
}
|
|
14841
|
-
function octal(header, start, length) {
|
|
14842
|
-
const text2 = fieldLine(header, start, length).trim();
|
|
14843
|
-
const ch = Number.parseInt(text2, 8);
|
|
14844
|
-
return Number.isFinite(ch) ? ch : 0;
|
|
14845
|
-
}
|
|
14846
|
-
function fieldSize(header, start, length) {
|
|
14847
|
-
if ((header[start] & 128) !== 0) {
|
|
14848
|
-
let ch = 0;
|
|
14849
|
-
for (let i = start + 1; i < start + length; i += 1) ch = ch * 256 + header[i];
|
|
14850
|
-
return ch;
|
|
14851
|
-
}
|
|
14852
|
-
return octal(header, start, length);
|
|
14853
|
-
}
|
|
14854
|
-
function inside(root, path2) {
|
|
14855
|
-
if (path2 === "" || path2.startsWith("/") || path2.startsWith("\\")) return false;
|
|
14856
|
-
if (/^[A-Za-z]:/.test(path2)) return false;
|
|
14857
|
-
const target = resolve(root, path2);
|
|
14858
|
-
const bottom = resolve(root);
|
|
14859
|
-
return target === bottom || target.startsWith(bottom + sep);
|
|
14860
|
-
}
|
|
14861
|
-
function unpackArchive(archive, dest) {
|
|
14862
|
-
const entries = tarEntries(gunzipSync(readFileSync(archive)));
|
|
14863
|
-
if (entries.length === 0) throw new DeliveryError(`\u0430\u0440\u0445\u0438\u0432 ${archive} \u043F\u0443\u0441\u0442 \u2014 \u0440\u0430\u0441\u043F\u0430\u043A\u043E\u0432\u044B\u0432\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E`);
|
|
14864
|
-
for (const entry of entries) {
|
|
14865
|
-
if (!inside(dest, entry.name)) throw escapesRoot(archive, entry.name);
|
|
14866
|
-
if (entry.kind === "symlink" || entry.kind === "hardlink") {
|
|
14867
|
-
if (entry.target.startsWith("/") || entry.target.startsWith("\\") || /^[A-Za-z]:/.test(entry.target)) {
|
|
14868
|
-
throw escapesRoot(archive, `${entry.name} \u2192 ${entry.target}`);
|
|
14869
|
-
}
|
|
14870
|
-
const from = entry.kind === "hardlink" ? entry.target : join(dirname(entry.name), entry.target);
|
|
14871
|
-
if (!inside(dest, from)) throw escapesRoot(archive, `${entry.name} \u2192 ${entry.target}`);
|
|
14872
|
-
}
|
|
14873
|
-
}
|
|
14874
|
-
for (const entry of entries) {
|
|
14875
|
-
const path2 = join(dest, entry.name);
|
|
14876
|
-
if (entry.kind === "dir") {
|
|
14877
|
-
mkdirSync(path2, { recursive: true });
|
|
14878
|
-
continue;
|
|
14879
|
-
}
|
|
14880
|
-
mkdirSync(dirname(path2), { recursive: true });
|
|
14881
|
-
if (entry.kind === "symlink") {
|
|
14882
|
-
rmSync(path2, { force: true });
|
|
14883
|
-
symlinkSync(entry.target, path2);
|
|
14884
|
-
continue;
|
|
14885
|
-
}
|
|
14886
|
-
if (entry.kind === "hardlink") {
|
|
14887
|
-
writeFileSync(path2, readFileSync(join(dest, entry.target)));
|
|
14888
|
-
continue;
|
|
14889
|
-
}
|
|
14890
|
-
writeFileSync(path2, entry.body);
|
|
14891
|
-
if ((entry.mode & 73) !== 0) chmodSync(path2, entry.mode & 511);
|
|
14892
|
-
}
|
|
14893
|
-
}
|
|
14894
|
-
function escapesRoot(archive, name) {
|
|
14895
|
-
return new DeliveryError(
|
|
14896
|
-
`\u0430\u0440\u0445\u0438\u0432 ${archive} \u043F\u044B\u0442\u0430\u0435\u0442\u0441\u044F \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C \u0444\u0430\u0439\u043B \u0437\u0430 \u043F\u0440\u0435\u0434\u0435\u043B\u044B \u043F\u0430\u043F\u043A\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438: \xAB${name}\xBB.
|
|
14897
|
-
\u041D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0440\u0430\u0441\u043F\u0430\u043A\u043E\u0432\u0430\u043D\u043E. \u0421\u043A\u0430\u0447\u0430\u0439 \u0437\u0430\u043D\u043E\u0432\u043E \u2014 \u0432\u0435\u0440\u043E\u044F\u0442\u043D\u0435\u0435 \u0432\u0441\u0435\u0433\u043E, \u0444\u0430\u0439\u043B \u043F\u043E\u0432\u0440\u0435\u0436\u0434\u0451\u043D \u0438\u043B\u0438 \u043F\u043E\u0434\u043C\u0435\u043D\u0451\u043D.`
|
|
14898
|
-
);
|
|
14899
|
-
}
|
|
14900
|
-
function dirExists(path2) {
|
|
14901
|
-
try {
|
|
14902
|
-
return statSync(path2).isDirectory();
|
|
14903
|
-
} catch {
|
|
14904
|
-
return false;
|
|
14905
|
-
}
|
|
14906
|
-
}
|
|
14907
14796
|
var BODY_ENTRY = "cli.js";
|
|
14908
14797
|
var BODY_MANIFEST = "shell.json";
|
|
14909
14798
|
function shellDir(home) {
|
|
@@ -15418,7 +15307,6 @@ function rollbackShell(home) {
|
|
|
15418
15307
|
};
|
|
15419
15308
|
}
|
|
15420
15309
|
}
|
|
15421
|
-
var SOURCES_FILE = "python-sources.json";
|
|
15422
15310
|
var PUBLICATION_FILE2 = ".publication.json";
|
|
15423
15311
|
var CANDIDATE_FILE = ".candidate.json";
|
|
15424
15312
|
function recoverInterruptedPublication(dir) {
|
|
@@ -15482,26 +15370,6 @@ function recoverInterruptedPublication(dir) {
|
|
|
15482
15370
|
\u041E\u043D\u0430 \u0435\u0449\u0451 \u043D\u0435 \u0440\u0430\u0431\u043E\u0447\u0430\u044F: setup \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442 \u044D\u0442\u043E\u0442 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442 \u0438 \u0441\u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u043E\u0431\u0435\u0440\u0451\u0442 \u0435\u0433\u043E \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435.`
|
|
15483
15371
|
};
|
|
15484
15372
|
}
|
|
15485
|
-
function platformKey(os = process.platform, arch2 = process.arch) {
|
|
15486
|
-
if (os === "darwin") return arch2 === "arm64" ? "Darwin-arm64" : arch2 === "x64" ? "Darwin-x86_64" : null;
|
|
15487
|
-
if (os === "win32") return arch2 === "x64" ? "Windows-AMD64" : null;
|
|
15488
|
-
if (os === "linux") return arch2 === "x64" ? "Linux-x86_64" : arch2 === "arm64" ? "Linux-aarch64" : null;
|
|
15489
|
-
return null;
|
|
15490
|
-
}
|
|
15491
|
-
function pythonSource(engineDir, key = platformKey()) {
|
|
15492
|
-
if (key === null) return null;
|
|
15493
|
-
const file2 = join(engineDir, SOURCES_FILE);
|
|
15494
|
-
if (!existsSync(file2)) return null;
|
|
15495
|
-
const table = JSON.parse(readFileSync(file2, "utf8"));
|
|
15496
|
-
const row = table["platforms"][key];
|
|
15497
|
-
if (row === void 0) return null;
|
|
15498
|
-
return { url: table["base"] + row["tail"], sha256: row.sha256, mb: row["mb"] };
|
|
15499
|
-
}
|
|
15500
|
-
function pythonVersion(engineDir) {
|
|
15501
|
-
const file2 = join(engineDir, SOURCES_FILE);
|
|
15502
|
-
if (!existsSync(file2)) return "";
|
|
15503
|
-
return JSON.parse(readFileSync(file2, "utf8"))["version"];
|
|
15504
|
-
}
|
|
15505
15373
|
async function installPayload(engine, opts, hooks = {}) {
|
|
15506
15374
|
if (engine.pathSetByHand()) {
|
|
15507
15375
|
return {
|
|
@@ -15600,7 +15468,7 @@ ${VOICE_CLEANER_NOTE}
|
|
|
15600
15468
|
return {
|
|
15601
15469
|
ok: true,
|
|
15602
15470
|
text: `\u041D\u0430\u0447\u0438\u043D\u043A\u0430 ${manifest.version} \u043F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043B\u0435\u043D\u0430: ${dest}
|
|
15603
|
-
\u041E\u043D\u0430 \u0435\u0449\u0451 \u043D\u0435 \u0441\u0442\u0430\u043B\u0430 \u0440\u0430\u0431\u043E\u0447\u0435\u0439. \u0414\u0430\u043B\u044C\u0448\u0435 setup \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442 \u044D\u0442\u043E\u0442 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442: \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442
|
|
15471
|
+
\u041E\u043D\u0430 \u0435\u0449\u0451 \u043D\u0435 \u0441\u0442\u0430\u043B\u0430 \u0440\u0430\u0431\u043E\u0447\u0435\u0439. \u0414\u0430\u043B\u044C\u0448\u0435 setup \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442 \u044D\u0442\u043E\u0442 \u043A\u0430\u043D\u0434\u0438\u0434\u0430\u0442: \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u043F\u043E \u0435\u0433\u043E \u0437\u0430\u043C\u043A\u0443 \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E\u0441\u043B\u0435 \u043F\u0440\u043E\u0432\u0435\u0440\u043E\u043A \u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0438\u0442 current.
|
|
15604
15472
|
\u0420\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u043D\u0438\u0435 \u0440\u0435\u0447\u0438, \u0432\u044B\u0440\u0435\u0437 \u0433\u0435\u0440\u043E\u044F \u0438 \u0447\u0438\u0441\u0442\u043A\u0430 \u0433\u043E\u043B\u043E\u0441\u0430 \u0432 \u043D\u0435\u0433\u043E \u043D\u0435 \u0432\u0445\u043E\u0434\u044F\u0442: \u043E\u043D\u0438 \u0441\u0442\u0430\u0432\u044F\u0442\u0441\u044F \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u044B\u043C\u0438 \u0448\u0430\u0433\u0430\u043C\u0438 \u0438 \u0442\u043E\u043B\u044C\u043A\u043E \u043F\u043E \u043F\u0440\u043E\u0441\u044C\u0431\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430.`
|
|
15605
15473
|
};
|
|
15606
15474
|
});
|
|
@@ -15640,113 +15508,6 @@ async function deliver(manifest, dest, intakeNear, key, baseCurrent, hooks) {
|
|
|
15640
15508
|
discardVersionStage(stage);
|
|
15641
15509
|
}
|
|
15642
15510
|
}
|
|
15643
|
-
async function installPython(engine, opts) {
|
|
15644
|
-
try {
|
|
15645
|
-
return await withVersionLock(
|
|
15646
|
-
engine.versionsDir(),
|
|
15647
|
-
async () => installPythonUnderLock(engine, opts)
|
|
15648
|
-
);
|
|
15649
|
-
} catch (trouble) {
|
|
15650
|
-
if (trouble instanceof VersionLockError) return { ok: false, text: trouble.message };
|
|
15651
|
-
return { ok: false, text: troubleText("Python \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C", trouble) };
|
|
15652
|
-
}
|
|
15653
|
-
}
|
|
15654
|
-
async function installPythonUnderLock(engine, opts) {
|
|
15655
|
-
const place = opts.version === void 0 ? engine.place() : engine.placeForVersion(opts.version);
|
|
15656
|
-
if (place === null) {
|
|
15657
|
-
return { ok: false, text: engine.whyNoEngine() };
|
|
15658
|
-
}
|
|
15659
|
-
const key = platformKey();
|
|
15660
|
-
const source = pythonSource(place.engine, key);
|
|
15661
|
-
if (source === null || source.sha256 === "") {
|
|
15662
|
-
return {
|
|
15663
|
-
ok: false,
|
|
15664
|
-
text: `\u0413\u043E\u0442\u043E\u0432\u043E\u0439 \u043F\u043E\u0440\u0442\u0430\u0442\u0438\u0432\u043D\u043E\u0439 \u0441\u0431\u043E\u0440\u043A\u0438 Python \u043F\u043E\u0434 \u044D\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 (${key ?? `${process.platform}-${process.arch}`}) \u0443 \u043C\u0435\u043D\u044F \u043D\u0435\u0442.
|
|
15665
|
-
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u0441\u043A\u0430\u0436\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C Python 3.10 \u0438\u043B\u0438 \u043D\u043E\u0432\u0435\u0435 \u0441 python.org/downloads \u0438 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0443.`
|
|
15666
|
-
};
|
|
15667
|
-
}
|
|
15668
|
-
const dest = join(engine.home(), "bin");
|
|
15669
|
-
const version2 = pythonVersion(place.engine);
|
|
15670
|
-
if (!opts.consent) {
|
|
15671
|
-
return {
|
|
15672
|
-
ok: false,
|
|
15673
|
-
text: `\u041D\u0430 \u044D\u0442\u043E\u0439 \u043C\u0430\u0448\u0438\u043D\u0435 \u043D\u0435\u0442 Python, \u0430 \u0431\u0435\u0437 \u043D\u0435\u0433\u043E \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u043D\u0435\u0447\u0435\u043C.
|
|
15674
|
-
\u041C\u043E\u0433\u0443 \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u043F\u043E\u0440\u0442\u0430\u0442\u0438\u0432\u043D\u044B\u0439 Python ${version2} (${source.mb} \u041C\u0411) \u0432 ${dest}: \u043E\u043D \u043B\u0435\u0436\u0438\u0442 \u043E\u0434\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u043E\u0439 \u0438 \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043E\u0442\u0442\u0443\u0434\u0430 \u2014 \u0432 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0441\u0442\u0430\u0432\u0438\u0442\u0441\u044F, PATH \u043D\u0435 \u043C\u0435\u043D\u044F\u0435\u0442\u0441\u044F, \u043F\u0440\u0430\u0432\u0430 \u0430\u0434\u043C\u0438\u043D\u0438\u0441\u0442\u0440\u0430\u0442\u043E\u0440\u0430 \u043D\u0435 \u043D\u0443\u0436\u043D\u044B, \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u0437\u043D\u0430\u0447\u0438\u0442 \u0443\u0434\u0430\u043B\u0438\u0442\u044C \u043F\u0430\u043F\u043A\u0443. \u041F\u043E\u0434\u043F\u0438\u0441\u044C \u0444\u0430\u0439\u043B\u0430 \u0443 \u043C\u0435\u043D\u044F \u0435\u0441\u0442\u044C, \u0441\u0432\u0435\u0440\u044E.
|
|
15675
|
-
\u0421\u043F\u0440\u043E\u0441\u0438 \u0443 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0430 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u0438\u0435 \u0438 \u043F\u043E\u0437\u043E\u0432\u0438 setup \u0441 what=all \u0438 consent=true.`
|
|
15676
|
-
};
|
|
15677
|
-
}
|
|
15678
|
-
const pythonDir = join(dest, "python");
|
|
15679
|
-
try {
|
|
15680
|
-
safePythonParent(engine.home(), dest);
|
|
15681
|
-
if (existsSync(pythonDir)) {
|
|
15682
|
-
safePythonDirectory(engine.home(), pythonDir);
|
|
15683
|
-
engine.forgetPython();
|
|
15684
|
-
if (await engine.pythonTrouble() === null) {
|
|
15685
|
-
return {
|
|
15686
|
-
ok: true,
|
|
15687
|
-
text: `Python ${version2} \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D: ${pythonDir}
|
|
15688
|
-
\u041F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043B.`
|
|
15689
|
-
};
|
|
15690
|
-
}
|
|
15691
|
-
throw new DeliveryError(
|
|
15692
|
-
`\u0412 ${pythonDir} \u0443\u0436\u0435 \u0447\u0442\u043E-\u0442\u043E \u043B\u0435\u0436\u0438\u0442, \u043D\u043E \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C \u044D\u0442\u043E \u043D\u0435 \u0432\u044B\u0448\u043B\u043E. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435, \u043D\u0435 \u0438\u0434\u0451\u0442 \u043B\u0438 \u0434\u0440\u0443\u0433\u0430\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0430, \u0437\u0430\u0442\u0435\u043C \u0443\u0434\u0430\u043B\u0438\u0442\u0435 \u043E\u0441\u0442\u0430\u0442\u043E\u043A \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435.`
|
|
15693
|
-
);
|
|
15694
|
-
}
|
|
15695
|
-
const stage = createVersionStage(engine.versionsDir(), opts.version ?? "0-python-bootstrap");
|
|
15696
|
-
try {
|
|
15697
|
-
const archive = join(stage.root, "python.tar.gz");
|
|
15698
|
-
await downloadFile({ url: source.url, dest: archive, sha256: source.sha256, key: null });
|
|
15699
|
-
unpackArchive(archive, stage.payload);
|
|
15700
|
-
const stagedPython = join(stage.payload, "python");
|
|
15701
|
-
if (!dirExists(stagedPython)) throw new DeliveryError("\u0432 \u0430\u0440\u0445\u0438\u0432\u0435 Python \u043D\u0435\u0442 \u043F\u0430\u043F\u043A\u0438 python");
|
|
15702
|
-
if (dirExists(pythonDir)) {
|
|
15703
|
-
throw new DeliveryError(`\u043F\u0430\u043F\u043A\u0430 ${pythonDir} \u0437\u0430\u043D\u044F\u0442\u0430 \u0434\u0440\u0443\u0433\u0438\u043C \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u043C. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438\u0442\u0435 setup \u043F\u043E\u0437\u0436\u0435`);
|
|
15704
|
-
}
|
|
15705
|
-
renameSync(stagedPython, pythonDir);
|
|
15706
|
-
} finally {
|
|
15707
|
-
discardVersionStage(stage);
|
|
15708
|
-
}
|
|
15709
|
-
} catch (trouble2) {
|
|
15710
|
-
return { ok: false, text: troubleText("Python \u0441\u043A\u0430\u0447\u0430\u0442\u044C \u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C", trouble2) };
|
|
15711
|
-
}
|
|
15712
|
-
engine.forgetPython();
|
|
15713
|
-
const trouble = await engine.pythonTrouble();
|
|
15714
|
-
if (trouble !== null) {
|
|
15715
|
-
return {
|
|
15716
|
-
ok: false,
|
|
15717
|
-
text: `Python \u0441\u043A\u0430\u0447\u0430\u043B\u0441\u044F \u0438 \u0440\u0430\u0441\u043F\u0430\u043A\u043E\u0432\u0430\u043B\u0441\u044F \u0432 ${pythonDir}, \u043D\u043E \u043D\u0435 \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u043B\u0441\u044F.
|
|
15718
|
-
${trouble}`
|
|
15719
|
-
};
|
|
15720
|
-
}
|
|
15721
|
-
return {
|
|
15722
|
-
ok: true,
|
|
15723
|
-
text: `Python ${version2} \u043F\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D: ${pythonDir}
|
|
15724
|
-
\u0412 \u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0441\u0442\u0430\u0432\u0438\u043B\u043E\u0441\u044C. \u0414\u0430\u043B\u044C\u0448\u0435 \u2014 setup \u0441 what=all.`
|
|
15725
|
-
};
|
|
15726
|
-
}
|
|
15727
|
-
function safePythonParent(home, parent) {
|
|
15728
|
-
mkdirSync(parent, { recursive: true });
|
|
15729
|
-
const stat = lstatSync(parent);
|
|
15730
|
-
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
15731
|
-
throw new DeliveryError(`${parent} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u0431\u044B\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u043E\u0439 \u0432\u043D\u0443\u0442\u0440\u0438 \u0434\u043E\u043C\u0430 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430`);
|
|
15732
|
-
}
|
|
15733
|
-
const homeReal = realpathSync(home);
|
|
15734
|
-
const parentReal = realpathSync(parent);
|
|
15735
|
-
if (!parentReal.startsWith(homeReal + sep)) {
|
|
15736
|
-
throw new DeliveryError(`${parent} \u0432\u044B\u0448\u0435\u043B \u0437\u0430 \u043F\u0440\u0435\u0434\u0435\u043B\u044B \u0434\u043E\u043C\u0430 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430`);
|
|
15737
|
-
}
|
|
15738
|
-
}
|
|
15739
|
-
function safePythonDirectory(home, pythonDir) {
|
|
15740
|
-
const stat = lstatSync(pythonDir);
|
|
15741
|
-
if (stat.isSymbolicLink() || !stat.isDirectory()) {
|
|
15742
|
-
throw new DeliveryError(`${pythonDir} \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u043E\u0431\u044B\u0447\u043D\u043E\u0439 \u043F\u0430\u043F\u043A\u043E\u0439`);
|
|
15743
|
-
}
|
|
15744
|
-
const homeReal = realpathSync(home);
|
|
15745
|
-
const pythonReal = realpathSync(pythonDir);
|
|
15746
|
-
if (!pythonReal.startsWith(homeReal + sep)) {
|
|
15747
|
-
throw new DeliveryError(`${pythonDir} \u0432\u044B\u0448\u0435\u043B \u0437\u0430 \u043F\u0440\u0435\u0434\u0435\u043B\u044B \u0434\u043E\u043C\u0430 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430`);
|
|
15748
|
-
}
|
|
15749
|
-
}
|
|
15750
15511
|
function troubleText(what, trouble) {
|
|
15751
15512
|
const tail2 = trouble instanceof DeliveryError ? trouble.message : trouble instanceof Error ? trouble.message : String(trouble);
|
|
15752
15513
|
return `${what}, \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u043C\u0435\u043D\u044F\u043B.
|
|
@@ -16924,6 +16685,10 @@ function cardRows(readiness) {
|
|
|
16924
16685
|
}));
|
|
16925
16686
|
return rows.map((row) => ({ ...row, mb: row.state === "ok" ? 0 : row.mb, say: rowWords(row.state, row.mb) }));
|
|
16926
16687
|
}
|
|
16688
|
+
var FOR_MODEL = /\bsetup\b|\bwait\b|what=|consent|\bjob\b|Скажи человеку|Спроси человека|скажи ему|перескажи/i;
|
|
16689
|
+
function forHuman(line) {
|
|
16690
|
+
return FOR_MODEL.test(line) ? "" : line;
|
|
16691
|
+
}
|
|
16927
16692
|
function setupCard(o) {
|
|
16928
16693
|
const rows = cardRows(o.readiness);
|
|
16929
16694
|
const missingMb = rows.filter((row) => row.state === "missing").reduce((all, row) => all + row.mb, 0);
|
|
@@ -16935,7 +16700,7 @@ function setupCard(o) {
|
|
|
16935
16700
|
next = `\u041D\u0430\u043F\u0438\u0448\u0438 \xAB\u0441\u043A\u0430\u0447\u0430\u0439\xBB \u2014 \u0441\u043A\u0430\u0447\u0430\u044E ${o.noEngine ? "\u043C\u043E\u043D\u0442\u0430\u0436" : "Python"}.`;
|
|
16936
16701
|
} else if (o.readiness === null) {
|
|
16937
16702
|
title = o.title ?? TITLE_UNKNOWN;
|
|
16938
|
-
next = o.note ?? "";
|
|
16703
|
+
next = forHuman(o.note ?? "");
|
|
16939
16704
|
} else if (!ready) {
|
|
16940
16705
|
title = missingMb ? `\u041D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E \u0441\u043A\u0430\u0447\u0430\u0442\u044C ${weight(missingMb)} \u0434\u043B\u044F \u043F\u043E\u043B\u043D\u043E\u0446\u0435\u043D\u043D\u043E\u0439 \u0440\u0430\u0431\u043E\u0442\u044B` : "\u041D\u0435 \u0432\u0441\u0451 \u0433\u043E\u0442\u043E\u0432\u043E \u0434\u043B\u044F \u043F\u043E\u043B\u043D\u043E\u0446\u0435\u043D\u043D\u043E\u0439 \u0440\u0430\u0431\u043E\u0442\u044B";
|
|
16941
16706
|
next = missingMb ? `\u041D\u0430\u043F\u0438\u0448\u0438 \xAB\u0441\u043A\u0430\u0447\u0430\u0439\xBB \u2014 \u0441\u043A\u0430\u0447\u0430\u044E ${weight(missingMb)}.` : "\u041D\u0430\u043F\u0438\u0448\u0438 \xAB\u0441\u043A\u0430\u0447\u0430\u0439\xBB \u2014 \u043F\u043E\u0441\u0442\u0430\u0432\u043B\u044E, \u0447\u0435\u0433\u043E \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442.";
|
|
@@ -18091,8 +17856,6 @@ function nameOrRefusal(candidate) {
|
|
|
18091
17856
|
\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043D\u0430\u0437\u043E\u0432\u0438 \u0448\u0430\u0433 \u043E\u0434\u043D\u0438\u043C \u0441\u043B\u043E\u0432\u043E\u043C \u2014 \u0442\u0430\u043A, \u043A\u0430\u043A \u043D\u0430\u0437\u044B\u0432\u0430\u0435\u0442\u0441\u044F \u0435\u0433\u043E \u043F\u0430\u043F\u043A\u0430. \u0421\u0432\u043E\u0439 \u0448\u0430\u0433 \u043B\u0435\u0436\u0438\u0442 \u0432 \`mine/steps/<\u0438\u043C\u044F>\` \u0432 \u0434\u043E\u043C\u0435 \u041D\u0430\u043F\u0430\u0440\u043D\u0438\u043A\u0430, \u043D\u0430\u0448\u0438 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u044F\u0435\u0442 setup, \u0438\u043C\u044F \u0443 \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u0441\u0442\u043E\u0438\u0442 \u0432 \u0441\u043A\u043E\u0431\u043A\u0430\u0445.`
|
|
18092
17857
|
};
|
|
18093
17858
|
}
|
|
18094
|
-
|
|
18095
|
-
// src/setup-job.ts
|
|
18096
17859
|
var SETUP_JOB_MARK = "setup-";
|
|
18097
17860
|
function isSetupJob(id) {
|
|
18098
17861
|
return id.startsWith(SETUP_JOB_MARK);
|
|
@@ -18107,13 +17870,108 @@ var CHECK = "\u041F\u0440\u043E\u0432\u0435\u0440\u044F\u044E, \u0447\u0442\u043
|
|
|
18107
17870
|
var INSTALL_NEW = "\u0421\u0442\u0430\u0432\u043B\u044E \u043D\u043E\u0432\u0443\u044E \u0432\u0435\u0440\u0441\u0438\u044E";
|
|
18108
17871
|
var MISSING = "\u0421\u0442\u0430\u0432\u043B\u044E \u043D\u0435\u0434\u043E\u0441\u0442\u0430\u044E\u0449\u0435\u0435";
|
|
18109
17872
|
var works = /* @__PURE__ */ new Map();
|
|
18110
|
-
|
|
18111
|
-
|
|
17873
|
+
var JOBS_DIR = "jobs";
|
|
17874
|
+
var JOBS_KEPT2 = 10;
|
|
17875
|
+
var BEAT_MS = 1e4;
|
|
17876
|
+
var STALE_MS = 6e4;
|
|
17877
|
+
var JOB_ID = /^setup-[\w-]{1,80}$/;
|
|
17878
|
+
function running(home, clock) {
|
|
17879
|
+
for (const work of works.values()) if (work.ended === null) return work.id;
|
|
17880
|
+
if (home === null) return null;
|
|
17881
|
+
for (const record2 of records(home)) {
|
|
17882
|
+
if (record2.ended === null && alive(record2, clock)) return record2.id;
|
|
17883
|
+
}
|
|
18112
17884
|
return null;
|
|
18113
17885
|
}
|
|
18114
|
-
function
|
|
18115
|
-
|
|
18116
|
-
|
|
17886
|
+
function records(home) {
|
|
17887
|
+
let names;
|
|
17888
|
+
try {
|
|
17889
|
+
names = readdirSync(join(home, JOBS_DIR)).filter((name) => name.endsWith(".json"));
|
|
17890
|
+
} catch {
|
|
17891
|
+
return [];
|
|
17892
|
+
}
|
|
17893
|
+
return names.sort().reverse().map((name) => load(home, name.slice(0, -".json".length))).filter((record2) => record2 !== null);
|
|
17894
|
+
}
|
|
17895
|
+
function load(home, id) {
|
|
17896
|
+
if (!JOB_ID.test(id)) return null;
|
|
17897
|
+
try {
|
|
17898
|
+
const value = JSON.parse(readFileSync(join(home, JOBS_DIR, `${id}.json`), "utf8"));
|
|
17899
|
+
if (value.id !== id || typeof value.what !== "string" || typeof value.started !== "number" || !Array.isArray(value.stages) || typeof value.at !== "number" || typeof value.pid !== "number" || typeof value.beat !== "number") return null;
|
|
17900
|
+
return {
|
|
17901
|
+
id,
|
|
17902
|
+
what: value.what,
|
|
17903
|
+
started: value.started,
|
|
17904
|
+
stages: value.stages.map(String),
|
|
17905
|
+
at: value.at,
|
|
17906
|
+
message: typeof value.message === "string" ? value.message : "",
|
|
17907
|
+
ended: value.ended ?? null,
|
|
17908
|
+
pid: value.pid,
|
|
17909
|
+
beat: value.beat
|
|
17910
|
+
};
|
|
17911
|
+
} catch {
|
|
17912
|
+
return null;
|
|
17913
|
+
}
|
|
17914
|
+
}
|
|
17915
|
+
function alive(record2, clock) {
|
|
17916
|
+
if (clock() - record2.beat > STALE_MS) return false;
|
|
17917
|
+
try {
|
|
17918
|
+
process.kill(record2.pid, 0);
|
|
17919
|
+
return true;
|
|
17920
|
+
} catch (trouble) {
|
|
17921
|
+
return trouble.code === "EPERM";
|
|
17922
|
+
}
|
|
17923
|
+
}
|
|
17924
|
+
function save(work, clock) {
|
|
17925
|
+
if (work.home === null) return;
|
|
17926
|
+
try {
|
|
17927
|
+
const dir = join(work.home, JOBS_DIR);
|
|
17928
|
+
mkdirSync(dir, { recursive: true });
|
|
17929
|
+
const file2 = join(dir, `${work.id}.json`);
|
|
17930
|
+
const temp = `${file2}.${process.pid}.tmp`;
|
|
17931
|
+
const record2 = {
|
|
17932
|
+
id: work.id,
|
|
17933
|
+
what: work.what,
|
|
17934
|
+
started: work.started,
|
|
17935
|
+
stages: work.stages,
|
|
17936
|
+
at: work.at,
|
|
17937
|
+
message: work.message,
|
|
17938
|
+
ended: work.ended,
|
|
17939
|
+
pid: process.pid,
|
|
17940
|
+
beat: clock()
|
|
17941
|
+
};
|
|
17942
|
+
writeFileSync(temp, JSON.stringify(record2), "utf8");
|
|
17943
|
+
renameSync(temp, file2);
|
|
17944
|
+
} catch {
|
|
17945
|
+
}
|
|
17946
|
+
}
|
|
17947
|
+
function prune2(home) {
|
|
17948
|
+
try {
|
|
17949
|
+
const dir = join(home, JOBS_DIR);
|
|
17950
|
+
const names = readdirSync(dir).filter((name) => JOB_ID.test(name.replace(/\.json$/, ""))).sort();
|
|
17951
|
+
for (const name of names.slice(0, Math.max(0, names.length - JOBS_KEPT2))) rmSync(join(dir, name), { force: true });
|
|
17952
|
+
} catch {
|
|
17953
|
+
}
|
|
17954
|
+
}
|
|
17955
|
+
function fromDisk(home, id, clock) {
|
|
17956
|
+
const record2 = load(home, id);
|
|
17957
|
+
if (record2 === null) return null;
|
|
17958
|
+
if (record2.ended !== null || alive(record2, clock)) return record2;
|
|
17959
|
+
return {
|
|
17960
|
+
...record2,
|
|
17961
|
+
ended: {
|
|
17962
|
+
at: record2.beat,
|
|
17963
|
+
ending: {
|
|
17964
|
+
ok: false,
|
|
17965
|
+
trouble: "\u041E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u043E\u0431\u043E\u0440\u0432\u0430\u043B\u043E\u0441\u044C: \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0430, \u043A\u043E\u0442\u043E\u0440\u0430\u044F \u0435\u0433\u043E \u0432\u0435\u043B\u0430, \u0437\u0430\u043A\u0440\u044B\u043B\u0430\u0441\u044C \u043F\u043E\u0441\u0440\u0435\u0434\u0438 \u0440\u0430\u0431\u043E\u0442\u044B. \u041F\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.",
|
|
17966
|
+
advice: "\u041D\u0430\u043F\u0438\u0448\u0438 \xAB\u043E\u0431\u043D\u043E\u0432\u0438\xBB \u0435\u0449\u0451 \u0440\u0430\u0437 \u2014 \u043D\u0430\u0447\u043D\u0443 \u0437\u0430\u043D\u043E\u0432\u043E.",
|
|
17967
|
+
report: `\u041F\u0440\u043E\u0446\u0435\u0441\u0441 \u043E\u0431\u043E\u043B\u043E\u0447\u043A\u0438 ${record2.pid}, \u043A\u043E\u0442\u043E\u0440\u044B\u0439 \u0432\u0451\u043B \u0437\u0430\u0434\u0430\u0447\u0443, \u043F\u0440\u043E\u043F\u0430\u043B \u043D\u0430 \u044D\u0442\u0430\u043F\u0435 \xAB${record2.stages[record2.at - 1] ?? CHECK}\xBB.`
|
|
17968
|
+
}
|
|
17969
|
+
}
|
|
17970
|
+
};
|
|
17971
|
+
}
|
|
17972
|
+
function startSetupJob(what, run, clock = Date.now, home = null) {
|
|
17973
|
+
const already = running(home, clock);
|
|
17974
|
+
if (already !== null) return already;
|
|
18117
17975
|
const started = clock();
|
|
18118
17976
|
const id = `${SETUP_JOB_MARK}${new Date(started).toISOString().replace(/[:.]/g, "-")}`;
|
|
18119
17977
|
const work = {
|
|
@@ -18124,23 +17982,31 @@ function startSetupJob(what, run, clock = Date.now) {
|
|
|
18124
17982
|
at: 1,
|
|
18125
17983
|
message: "",
|
|
18126
17984
|
ended: null,
|
|
18127
|
-
done: Promise.resolve()
|
|
17985
|
+
done: Promise.resolve(),
|
|
17986
|
+
home
|
|
18128
17987
|
};
|
|
18129
17988
|
const control = {
|
|
18130
17989
|
plan(stages) {
|
|
18131
17990
|
work.stages = stages;
|
|
18132
17991
|
work.at = Math.min(work.at, stages.length);
|
|
17992
|
+
save(work, clock);
|
|
18133
17993
|
},
|
|
18134
17994
|
go(stage) {
|
|
18135
17995
|
const index = work.stages.indexOf(stage);
|
|
18136
17996
|
if (index >= 0) work.at = index + 1;
|
|
18137
17997
|
work.message = "";
|
|
17998
|
+
save(work, clock);
|
|
18138
17999
|
},
|
|
18139
18000
|
line(text2) {
|
|
18140
18001
|
work.message = text2;
|
|
18002
|
+
save(work, clock);
|
|
18141
18003
|
}
|
|
18142
18004
|
};
|
|
18143
18005
|
works.set(id, work);
|
|
18006
|
+
if (home !== null) prune2(home);
|
|
18007
|
+
save(work, clock);
|
|
18008
|
+
const beat = home === null ? null : setInterval(() => save(work, clock), BEAT_MS);
|
|
18009
|
+
beat?.unref();
|
|
18144
18010
|
work.done = collectJobInstallFaults(id, () => run(control).catch((trouble) => {
|
|
18145
18011
|
noteInstallFault("update-job", trouble);
|
|
18146
18012
|
return {
|
|
@@ -18151,15 +18017,17 @@ function startSetupJob(what, run, clock = Date.now) {
|
|
|
18151
18017
|
};
|
|
18152
18018
|
})).then((ending) => {
|
|
18153
18019
|
work.ended = { at: clock(), ending };
|
|
18020
|
+
if (beat !== null) clearInterval(beat);
|
|
18021
|
+
save(work, clock);
|
|
18154
18022
|
});
|
|
18155
18023
|
return id;
|
|
18156
18024
|
}
|
|
18157
18025
|
function quiet(line) {
|
|
18158
18026
|
return line.replace(/^⚠\s*/, "").replace(/^Что делать:/, "\u0421\u043E\u0432\u0435\u0442:");
|
|
18159
18027
|
}
|
|
18160
|
-
function setupJobText(id, clock = Date.now) {
|
|
18161
|
-
const work = works.get(id);
|
|
18162
|
-
if (work ===
|
|
18028
|
+
function setupJobText(id, clock = Date.now, home = null) {
|
|
18029
|
+
const work = works.get(id) ?? (home === null ? null : fromDisk(home, id, clock));
|
|
18030
|
+
if (work === null) return null;
|
|
18163
18031
|
const head2 = `\u0417\u0430\u0434\u0430\u043D\u0438\u0435 ${work.id}: ${work.what}`;
|
|
18164
18032
|
if (work.ended === null) {
|
|
18165
18033
|
const sec2 = Math.max(0, Math.round((clock() - work.started) / 1e3));
|
|
@@ -18183,8 +18051,8 @@ function setupJobText(id, clock = Date.now) {
|
|
|
18183
18051
|
`\u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: ${ending.advice}`
|
|
18184
18052
|
].join("\n");
|
|
18185
18053
|
}
|
|
18186
|
-
function setupJobReport(id) {
|
|
18187
|
-
const text2 = setupJobText(id);
|
|
18054
|
+
function setupJobReport(id, home = null) {
|
|
18055
|
+
const text2 = setupJobText(id, Date.now, home);
|
|
18188
18056
|
return text2 === null ? null : readJob(text2);
|
|
18189
18057
|
}
|
|
18190
18058
|
function weightExact(bytes) {
|
|
@@ -18265,9 +18133,10 @@ async function runUpdate(job, deps) {
|
|
|
18265
18133
|
updated = true;
|
|
18266
18134
|
steps.push({ report: outcome.text });
|
|
18267
18135
|
} else {
|
|
18136
|
+
const cause = causeOf(outcome.text);
|
|
18268
18137
|
steps.push({
|
|
18269
18138
|
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
|
|
18139
|
+
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${cause === "" ? "" : `: ${cause}`}. \u0420\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
18140
|
});
|
|
18272
18141
|
}
|
|
18273
18142
|
}
|
|
@@ -18283,6 +18152,11 @@ async function runUpdate(job, deps) {
|
|
|
18283
18152
|
if (updated) return { ok: true, say: SAY_RESTART, report };
|
|
18284
18153
|
return { ok: true, say: installed ? SAY_INSTALLED : SAY_NOTHING, report };
|
|
18285
18154
|
}
|
|
18155
|
+
function causeOf(text2) {
|
|
18156
|
+
const line = text2.split("\n").map((one) => one.trim()).find((one) => one !== "" && !/^(Новая версия|Версия) \S+ не встала/.test(one) && !/^Что делать:/.test(one)) ?? "";
|
|
18157
|
+
const phrase = (line.split(/\.\s|\s—\s|;\s/)[0] ?? "").replace(/\s*\([^)]*\)/g, "").replace(/\.$/, "").trim();
|
|
18158
|
+
return phrase === "" ? "" : phrase[0].toLowerCase() + phrase.slice(1);
|
|
18159
|
+
}
|
|
18286
18160
|
async function deliverMissing(job, deps) {
|
|
18287
18161
|
const answer = await deps.installMissing();
|
|
18288
18162
|
if (answer.type === "error") {
|
|
@@ -18382,25 +18256,15 @@ async function installStep(engine, asked, key, baseUrl, tell) {
|
|
|
18382
18256
|
`\u041A\u0430\u043D\u0434\u0438\u0434\u0430\u0442 ${candidate.version} \u0443\u0436\u0435 \u043F\u043E\u0434\u0433\u043E\u0442\u043E\u0432\u043B\u0435\u043D, \u043D\u043E \u0435\u0449\u0451 \u043D\u0435 \u0440\u0430\u0431\u043E\u0447\u0438\u0439. \u0421\u043F\u0440\u043E\u0441\u0438 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u0438\u0435 \u0441\u043E\u0431\u0440\u0430\u0442\u044C \u0435\u0433\u043E \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u0435 \u0438 \u043F\u043E\u0437\u043E\u0432\u0438 setup \u0441 consent=true.`
|
|
18383
18257
|
);
|
|
18384
18258
|
}
|
|
18385
|
-
let bootstrapText = "";
|
|
18386
18259
|
const extras = step === "all" ? "later" : "now";
|
|
18387
|
-
const activated = await continuePreparedCandidate(engine, candidate,
|
|
18388
|
-
if (await engine.pythonTrouble() === null) {
|
|
18389
|
-
return { ok: true, text: "Python \u0443\u0436\u0435 \u0434\u043E\u0441\u0442\u0443\u043F\u0435\u043D; \u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E \u043D\u0438\u0447\u0435\u0433\u043E \u043D\u0435 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043B." };
|
|
18390
|
-
}
|
|
18391
|
-
const python2 = await installPythonUnderLock(engine, { consent, version: locked.version });
|
|
18392
|
-
bootstrapText = python2.text;
|
|
18393
|
-
return python2;
|
|
18394
|
-
}, void 0, extras);
|
|
18260
|
+
const activated = await continuePreparedCandidate(engine, candidate, void 0, extras);
|
|
18395
18261
|
if (!activated.ok) return toolError(activated.text);
|
|
18396
18262
|
engine.forgetPlace();
|
|
18397
|
-
|
|
18398
|
-
|
|
18399
|
-
${activated.text}`.trim());
|
|
18400
|
-
}
|
|
18263
|
+
engine.forgetPython();
|
|
18264
|
+
if (step === "python") return toolSuccess(activated.text);
|
|
18401
18265
|
if (step === "all") {
|
|
18402
18266
|
const ready = `${activated.text}
|
|
18403
|
-
\u041A\u0430\u043D\u0434\u0438\u0434\u0430\u0442 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u043B
|
|
18267
|
+
\u041A\u0430\u043D\u0434\u0438\u0434\u0430\u0442 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u043B \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438 \u043F\u043E \u0441\u0432\u043E\u0435\u043C\u0443 \u0437\u0430\u043C\u043A\u0443 \u0438 \u043F\u0440\u043E\u0448\u0451\u043B env-check. \u0412\u0441\u0451 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0435 \u0433\u043E\u0442\u043E\u0432\u043E.`;
|
|
18404
18268
|
const later = await installStep(engine, asked, key, baseUrl, tell);
|
|
18405
18269
|
if (later.type === "error") {
|
|
18406
18270
|
return toolSuccess(
|
|
@@ -18414,16 +18278,15 @@ ${activated.text}`.trim());
|
|
|
18414
18278
|
${EXTRAS_LATER}`), later]);
|
|
18415
18279
|
}
|
|
18416
18280
|
}
|
|
18417
|
-
if (step === "python" || step === "all") {
|
|
18418
|
-
if (await engine.pythonTrouble() !== null) {
|
|
18419
|
-
const result = await installPython(engine, { consent });
|
|
18420
|
-
if (!result.ok) return toolError(result.text);
|
|
18421
|
-
if (step === "python") return toolSuccess(result.text);
|
|
18422
|
-
return toolSuccess(result.text + "\n\u041F\u043E\u0437\u043E\u0432\u0438 setup \u0441 what=all \u0435\u0449\u0451 \u0440\u0430\u0437.");
|
|
18423
|
-
}
|
|
18424
|
-
}
|
|
18425
18281
|
const place = engine.place();
|
|
18426
18282
|
if (place === null) return toolError(engine.whyNoEngine());
|
|
18283
|
+
if (consent && await engine.pythonTrouble() !== null) {
|
|
18284
|
+
try {
|
|
18285
|
+
await engine.bringPython(place);
|
|
18286
|
+
} catch (trouble) {
|
|
18287
|
+
return toolError(`\u041F\u0438\u0442\u043E\u043D \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043F\u043E\u0441\u0442\u0430\u0432\u0438\u0442\u044C \u043D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C: ${describeFailure(trouble)}. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u043E\u0432\u0442\u043E\u0440\u0438 setup.`);
|
|
18288
|
+
}
|
|
18289
|
+
}
|
|
18427
18290
|
const common = [
|
|
18428
18291
|
"--pack",
|
|
18429
18292
|
place.pack,
|
|
@@ -18659,7 +18522,7 @@ async function lookAround(engine, model, key, baseUrl) {
|
|
|
18659
18522
|
shell: shellNews,
|
|
18660
18523
|
...o.noEngine === true ? { noEngine: true } : {},
|
|
18661
18524
|
...o.noPython === true ? { noPython: true } : {},
|
|
18662
|
-
note: firstLine(said),
|
|
18525
|
+
note: o.note ?? firstLine(said),
|
|
18663
18526
|
shellVersion: VERSION
|
|
18664
18527
|
}));
|
|
18665
18528
|
const shell = updateShell(engine, false, key, baseUrl, NEWS_POINTER_MS, toShell);
|
|
@@ -18671,10 +18534,10 @@ async function lookAround(engine, model, key, baseUrl) {
|
|
|
18671
18534
|
});
|
|
18672
18535
|
return card(together([toolSuccess(payload.text), await shell]), { noEngine: true });
|
|
18673
18536
|
}
|
|
18674
|
-
|
|
18675
|
-
|
|
18537
|
+
const noPython = await engine.pythonTrouble();
|
|
18538
|
+
if (noPython !== null) {
|
|
18676
18539
|
return card(together([
|
|
18677
|
-
toolSuccess(
|
|
18540
|
+
toolSuccess(noPython),
|
|
18678
18541
|
await updateEngine(engine, false, key, baseUrl, NEWS_POINTER_MS, toEngine),
|
|
18679
18542
|
await shell
|
|
18680
18543
|
]), { noPython: true });
|
|
@@ -18686,7 +18549,7 @@ async function lookAround(engine, model, key, baseUrl) {
|
|
|
18686
18549
|
]);
|
|
18687
18550
|
return card(
|
|
18688
18551
|
together([newsForModel(shellNews, engineNews), machine.result, news, own]),
|
|
18689
|
-
{ readiness: machine.readiness }
|
|
18552
|
+
{ readiness: machine.readiness, note: firstLine(together([machine.result, news, own])) }
|
|
18690
18553
|
);
|
|
18691
18554
|
}
|
|
18692
18555
|
function newsForModel(shell, engine) {
|
|
@@ -18716,8 +18579,8 @@ function startUpdate(engine, what, key, baseUrl) {
|
|
|
18716
18579
|
what,
|
|
18717
18580
|
pointerMs: ASKED_POINTER_MS,
|
|
18718
18581
|
installMissing: () => installMissing(engine, key, baseUrl, void 0)
|
|
18719
|
-
}));
|
|
18720
|
-
const report = setupJobReport(id);
|
|
18582
|
+
}), Date.now, engine.home());
|
|
18583
|
+
const report = setupJobReport(id, engine.home());
|
|
18721
18584
|
return toolSuccess(
|
|
18722
18585
|
`\u0417\u0430\u0434\u0430\u0447\u0430 ${id}: ${report?.what ?? title}.
|
|
18723
18586
|
\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.',
|
|
@@ -18749,10 +18612,8 @@ async function askBeforeHeavy(engine, step, model, key, baseUrl) {
|
|
|
18749
18612
|
});
|
|
18750
18613
|
return toolSuccess(payload.text);
|
|
18751
18614
|
}
|
|
18752
|
-
|
|
18753
|
-
|
|
18754
|
-
return toolSuccess(python.text);
|
|
18755
|
-
}
|
|
18615
|
+
const noPython = await engine.pythonTrouble();
|
|
18616
|
+
if (noPython !== null) return toolSuccess(noPython);
|
|
18756
18617
|
return asToolResult(await engine.command([
|
|
18757
18618
|
"env-install",
|
|
18758
18619
|
"--pack",
|
|
@@ -18857,7 +18718,7 @@ var TRIALS_STEP = "\u041F\u043E\u0442\u043E\u043C \u0441\u043E\u0431\u0435\u0440
|
|
|
18857
18718
|
async function followWork(engine, asked, pace = realPace, tell) {
|
|
18858
18719
|
const ask2 = async () => {
|
|
18859
18720
|
if (!isSetupJob(asked.job)) return engine.command(["job", asked.job]);
|
|
18860
|
-
const text2 = setupJobText(asked.job);
|
|
18721
|
+
const text2 = setupJobText(asked.job, Date.now, engine.home());
|
|
18861
18722
|
return text2 !== null ? { ok: true, text: text2 } : {
|
|
18862
18723
|
ok: false,
|
|
18863
18724
|
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.`
|
|
@@ -23165,4 +23026,4 @@ ${inTable}`, file2);
|
|
|
23165
23026
|
};
|
|
23166
23027
|
}
|
|
23167
23028
|
|
|
23168
|
-
export { CrashReporter, DEFAULT_HOME, DeliveryError, Engine, ForeignBlockError,
|
|
23029
|
+
export { CrashReporter, DEFAULT_HOME, DeliveryError, Engine, ForeignBlockError, INSTALL_STEPS, KEEP_COPIES, KEEP_VERSIONS, LOCK_FILE, LONG_STEPS, MANIFEST_TIMEOUT_MS, MANIFEST_URL, MARKER, MIN_ENGINE, McpServer, NaparnikApiClient, NaparnikAuthError, NaparnikClientError, NaparnikConfigError, NaparnikError, NaparnikInsufficientBalanceError, NaparnikScopeError, NaparnikServerError, NaparnikTimeoutError, PAUSE_HOURS, SERVER_NAME, START_SEC, StdioServerTransport, TOOL_SEC, USER_AGENT, VERSION, WHERE_TO_GET_KEY, Wakefulness, bringPython, buildAll, buildBlock, buildResources, bundleUrlFor, chooseBody, compare, configPath, currentMachineFingerprint, decide, decideShell, defineTool, depFolderName, deploy, downloadFile, fetchManifest, fetchShellManifest, fileOrRefusal, findBlock, fromHost, fromNpxCache, handOverToBody, inside, install, installPayload, installStep, installedShell, jsonSchemaOf, keyFromBlock, keyInTable, lastLine, loadConfig, lockedPython, manifestUrlFor, markChecked, markChecked2, markCurrent2 as markCurrent, parseEngineManifest, parseFailure, path, platformKey, previousVersion2 as previousVersion, probe, readConfig, realPace, refusalFor, remove, reportInstallFaults, rollback, rollbackShell, shellDir, systemBlocker, tarEntries, tidyOld2 as tidyOld, timeToCheck, timeToCheck2, unpackArchive, updateEngine, watchProcessCrashes, withArgs };
|