@naparnik/mcp 0.10.38 → 0.10.40
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 +10 -0
- package/dist/{chunk-MCZJVJFA.js → chunk-QD2NNOLZ.js} +473 -37
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Изменения @naparnik/mcp
|
|
2
2
|
|
|
3
|
+
## 0.10.40 — 2026-09-24. Видно, что стоит и что качается
|
|
4
|
+
|
|
5
|
+
Под ответом проверки больше нет пустой серой рамки. Там карточка: что
|
|
6
|
+
уже стоит, чего не хватает и сколько это весит, вышло ли новое и что
|
|
7
|
+
сказать дальше.
|
|
8
|
+
|
|
9
|
+
Пока идёт установка, видна полоса: сколько скачано из скольких, процент
|
|
10
|
+
и сколько ещё ждать. Модель распознавания речи теперь тоже показывает
|
|
11
|
+
ход, а не молчит десять минут.
|
|
12
|
+
|
|
3
13
|
## 0.10.38 — 2026-09-24. Порядок внутри
|
|
4
14
|
|
|
5
15
|
**Для вас ничего не меняется.** Убрали старый способ монтажа, которым
|
|
@@ -727,7 +727,7 @@ function parsePositiveInt(raw, fallback) {
|
|
|
727
727
|
}
|
|
728
728
|
|
|
729
729
|
// src/version.ts
|
|
730
|
-
var VERSION = "0.10.
|
|
730
|
+
var VERSION = "0.10.40";
|
|
731
731
|
var USER_AGENT = `naparnik-mcp/${VERSION}`;
|
|
732
732
|
var MIN_ENGINE = "2026.09.24-446";
|
|
733
733
|
var LAUNCHER_PROTOCOL = 1;
|
|
@@ -13778,7 +13778,7 @@ async function askPointer(opts) {
|
|
|
13778
13778
|
...key !== void 0 ? { headers: { authorization: `Bearer ${key}` } } : {}
|
|
13779
13779
|
});
|
|
13780
13780
|
if (!response.ok) {
|
|
13781
|
-
return { ok: false, why: `\u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u043E\u0442\u0432\u0435\u0442\u0438\u043B\u0430 ${response.status} \u2014 ${what} \u043D\u0435 \u043E\u0442\u0434\u0430\u043D
|
|
13781
|
+
return { ok: false, why: `\u0440\u0430\u0437\u0434\u0430\u0447\u0430 \u043E\u0442\u0432\u0435\u0442\u0438\u043B\u0430 ${response.status} \u2014 ${what} \u043D\u0435 \u043E\u0442\u0434\u0430\u043D`, status: response.status };
|
|
13782
13782
|
}
|
|
13783
13783
|
const type = (response.headers.get("content-type") ?? "").toLowerCase();
|
|
13784
13784
|
if (!type.includes("json")) {
|
|
@@ -15823,6 +15823,10 @@ function empty() {
|
|
|
15823
15823
|
behind: "",
|
|
15824
15824
|
ahead: "",
|
|
15825
15825
|
message: "",
|
|
15826
|
+
got: 0,
|
|
15827
|
+
of: 0,
|
|
15828
|
+
percent: 0,
|
|
15829
|
+
eta: "",
|
|
15826
15830
|
file: "",
|
|
15827
15831
|
outcome: "",
|
|
15828
15832
|
trouble: "",
|
|
@@ -15849,6 +15853,7 @@ var RUNNING = /^Ещё считает, (\d+(?:[.,]\d+)?) с\.$/;
|
|
|
15849
15853
|
var COMPLAINT = /^⚠ (.+)$/;
|
|
15850
15854
|
var PLAN_HEAD = /^План:$/;
|
|
15851
15855
|
var PLAN_ROW = /^· (.+)$/;
|
|
15856
|
+
var DOWNLOAD = /^Скачано (\d+) МБ(?: из (\d+) \((\d+)%\)(?:, (.+))?)?$/;
|
|
15852
15857
|
var STYLE = /^Стиль: /;
|
|
15853
15858
|
var LEFT_TAIL = /\.\s+(Осталось .+)$/;
|
|
15854
15859
|
function readJob(text2) {
|
|
@@ -15955,6 +15960,13 @@ function readJob(text2) {
|
|
|
15955
15960
|
}
|
|
15956
15961
|
if (job.status === "running" || job.status === "waiting") job.message = line;
|
|
15957
15962
|
}
|
|
15963
|
+
const download = job.status === "running" ? DOWNLOAD.exec(job.message) : null;
|
|
15964
|
+
if (download !== null) {
|
|
15965
|
+
job.got = Number(download[1]);
|
|
15966
|
+
job.of = Number(download[2] ?? 0);
|
|
15967
|
+
job.percent = Math.min(100, Number(download[3] ?? 0));
|
|
15968
|
+
job.eta = download[4] ?? "";
|
|
15969
|
+
}
|
|
15958
15970
|
return job;
|
|
15959
15971
|
}
|
|
15960
15972
|
function seconds(text2) {
|
|
@@ -16332,7 +16344,7 @@ function pythonCrash(text2) {
|
|
|
16332
16344
|
if (/(?:^|\.)(?:KeyboardInterrupt|SystemExit|Explained|Refusal)$/.test(errorType)) return null;
|
|
16333
16345
|
const message = [m[2] ?? "", ...lines.slice(at + 1)].join("\n").trim();
|
|
16334
16346
|
const innermost = frames[frames.length - 1];
|
|
16335
|
-
const
|
|
16347
|
+
const firstLine2 = message.split("\n")[0] ?? "";
|
|
16336
16348
|
return {
|
|
16337
16349
|
errorType,
|
|
16338
16350
|
message,
|
|
@@ -16340,7 +16352,7 @@ function pythonCrash(text2) {
|
|
|
16340
16352
|
keep: "tail",
|
|
16341
16353
|
frames: frames.slice(-3).map((f) => `${basename(f.file.replace(/\\/g, "/"))}:${f.func}`),
|
|
16342
16354
|
python: pythonVersionIn(frames.map((f) => f.file)),
|
|
16343
|
-
essence: `${errorType}${
|
|
16355
|
+
essence: `${errorType}${firstLine2 === "" ? "" : `: ${firstLine2}`}` + (innermost ? ` \u2014 ${basename(innermost.file.replace(/\\/g, "/"))}:${innermost.line}` : "")
|
|
16344
16356
|
};
|
|
16345
16357
|
}
|
|
16346
16358
|
function pythonVersionIn(files) {
|
|
@@ -16440,6 +16452,91 @@ function tail(text2, max) {
|
|
|
16440
16452
|
function orNull(value, max) {
|
|
16441
16453
|
return value === null || value === "" ? null : head(value, max);
|
|
16442
16454
|
}
|
|
16455
|
+
var SETUP_CONTRACT = "naparnik-setup/1";
|
|
16456
|
+
var READINESS_CONTRACT = "naparnik-readiness/1";
|
|
16457
|
+
var JSON_CHECK = "--json";
|
|
16458
|
+
function knowsJsonCheck(engineDir) {
|
|
16459
|
+
try {
|
|
16460
|
+
const contract = JSON.parse(readFileSync(join(engineDir, "shell-contract.json"), "utf8"));
|
|
16461
|
+
const flags = contract.env_check_flags;
|
|
16462
|
+
return Array.isArray(flags) && flags.includes(JSON_CHECK);
|
|
16463
|
+
} catch {
|
|
16464
|
+
return false;
|
|
16465
|
+
}
|
|
16466
|
+
}
|
|
16467
|
+
function readReadiness(stdout) {
|
|
16468
|
+
const lines = stdout.trim().split("\n");
|
|
16469
|
+
let raw;
|
|
16470
|
+
try {
|
|
16471
|
+
raw = JSON.parse(lines[lines.length - 1] ?? "");
|
|
16472
|
+
} catch {
|
|
16473
|
+
return null;
|
|
16474
|
+
}
|
|
16475
|
+
const data = raw;
|
|
16476
|
+
if (data === null || typeof data !== "object" || data["contract"] !== READINESS_CONTRACT) return null;
|
|
16477
|
+
if (typeof data["words"] !== "string" || !Array.isArray(data["parts"])) return null;
|
|
16478
|
+
const parts = [];
|
|
16479
|
+
for (const item of data["parts"]) {
|
|
16480
|
+
const part = item;
|
|
16481
|
+
if (part === null || typeof part !== "object" || typeof part["name"] !== "string") continue;
|
|
16482
|
+
parts.push({
|
|
16483
|
+
name: part["name"],
|
|
16484
|
+
title: typeof part["title"] === "string" && part["title"] !== "" ? part["title"] : part["name"],
|
|
16485
|
+
ok: part["ok"] === true,
|
|
16486
|
+
mb: typeof part["mb"] === "number" && part["mb"] > 0 ? Math.round(part["mb"]) : 0,
|
|
16487
|
+
on_demand: part["on_demand"] === true,
|
|
16488
|
+
step: typeof part["step"] === "string" ? part["step"] : ""
|
|
16489
|
+
});
|
|
16490
|
+
}
|
|
16491
|
+
return { words: data["words"], ready: data["ready"] === true, parts };
|
|
16492
|
+
}
|
|
16493
|
+
var NOT_A_ROW = /* @__PURE__ */ new Set(["system"]);
|
|
16494
|
+
function weight(mb) {
|
|
16495
|
+
if (mb >= 1e3) return `${(mb / 1024).toFixed(1).replace(".", ",")} \u0413\u0411`;
|
|
16496
|
+
return `${mb} \u041C\u0411`;
|
|
16497
|
+
}
|
|
16498
|
+
function refusalWords(status) {
|
|
16499
|
+
if (status === 401) {
|
|
16500
|
+
return `\u041A\u043B\u044E\u0447 \u043F\u043E\u0434\u043F\u0438\u0441\u043A\u0438 \u043D\u0435 \u043F\u0440\u0438\u043D\u044F\u0442 \u2014 \u043D\u043E\u0432\u044B\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043D\u0435 \u043F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043D\u0430\u043F\u0438\u0448\u0438\u0442\u0435 \u0431\u043E\u0442\u0443 ${KEY_SOURCE_BOT} \xAB\u041F\u043E\u043B\u0443\u0447\u0438\u0442\u044C \u043A\u043B\u044E\u0447\xBB.`;
|
|
16501
|
+
}
|
|
16502
|
+
if (status === 403) {
|
|
16503
|
+
return `\u041F\u043E\u0434\u043F\u0438\u0441\u043A\u0430 \u043A\u043E\u043D\u0447\u0438\u043B\u0430\u0441\u044C \u2014 \u043D\u043E\u0432\u044B\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043D\u0435 \u043F\u0440\u0438\u0445\u043E\u0434\u044F\u0442. \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C: \u043F\u0440\u043E\u0434\u043B\u0438\u0442\u0435 \u0435\u0451 \u0443 \u0431\u043E\u0442\u0430 ${KEY_SOURCE_BOT}.`;
|
|
16504
|
+
}
|
|
16505
|
+
return "";
|
|
16506
|
+
}
|
|
16507
|
+
function setupCard(o) {
|
|
16508
|
+
const rows = (o.readiness?.parts ?? []).filter((part) => !NOT_A_ROW.has(part.name)).map((part) => ({
|
|
16509
|
+
title: part.title,
|
|
16510
|
+
state: part.ok ? "ok" : part.on_demand ? "later" : "missing",
|
|
16511
|
+
mb: part.ok ? 0 : part.mb
|
|
16512
|
+
}));
|
|
16513
|
+
const missingMb = rows.filter((row) => row.state === "missing").reduce((all, row) => all + row.mb, 0);
|
|
16514
|
+
const ready = o.readiness?.ready === true;
|
|
16515
|
+
const fresh = [];
|
|
16516
|
+
if (o.shell?.fresh) fresh.push(`\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 ${o.shell.fresh}${o.shell.mb ? ` (${weight(o.shell.mb)})` : ""}`);
|
|
16517
|
+
if (o.engine?.fresh) fresh.push(`\u0434\u0432\u0438\u0436\u043E\u043A ${o.engine.fresh}${o.engine.mb ? ` (${weight(o.engine.mb)})` : ""}`);
|
|
16518
|
+
const update = fresh.length ? `\u0412\u044B\u0448\u043B\u043E \u043D\u043E\u0432\u043E\u0435: ${fresh.join(", ")}.` : "";
|
|
16519
|
+
const trouble = refusalWords(o.shell?.status ?? 0) || refusalWords(o.engine?.status ?? 0);
|
|
16520
|
+
let next;
|
|
16521
|
+
if (o.noEngine) next = "\u0414\u0432\u0438\u0436\u043A\u0430 \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u0435\u0449\u0451 \u043D\u0435\u0442. \u0421\u043A\u0430\u0436\u0438\u0442\u0435 \xAB\u043F\u043E\u0441\u0442\u0430\u0432\u044C\xBB \u2014 \u043E\u043D \u0441\u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u043F\u043E\u0441\u043B\u0435 \u0432\u0430\u0448\u0435\u0433\u043E \xAB\u0434\u0430\xBB.";
|
|
16522
|
+
else if (o.noPython) next = "\u041D\u0443\u0436\u0435\u043D Python. \u0421\u043A\u0430\u0436\u0438\u0442\u0435 \xAB\u043F\u043E\u0441\u0442\u0430\u0432\u044C\xBB \u2014 \u043E\u043D \u0441\u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u043F\u043E\u0441\u043B\u0435 \u0432\u0430\u0448\u0435\u0433\u043E \xAB\u0434\u0430\xBB.";
|
|
16523
|
+
else if (o.readiness === null) next = o.note ?? "";
|
|
16524
|
+
else if (!ready) {
|
|
16525
|
+
next = `\u0414\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442${missingMb ? ` ${weight(missingMb)}` : " \u0447\u0430\u0441\u0442\u0438"}. \u0421\u043A\u0430\u0436\u0438\u0442\u0435 \xAB\u043F\u043E\u0441\u0442\u0430\u0432\u044C\xBB \u2014 \u0434\u043E\u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u043F\u043E\u0441\u043B\u0435 \u0432\u0430\u0448\u0435\u0433\u043E \xAB\u0434\u0430\xBB.`;
|
|
16526
|
+
} else if (update !== "") next = "\u041C\u043E\u0436\u043D\u043E \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C. \u0421\u043A\u0430\u0436\u0438\u0442\u0435 \xAB\u043E\u0431\u043D\u043E\u0432\u0438\xBB \u2014 \u043D\u043E\u0432\u043E\u0435 \u0437\u0430\u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u043F\u043E\u0441\u043B\u0435 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A\u0430.";
|
|
16527
|
+
else next = "\u0412\u0441\u0451 \u043D\u0430 \u043C\u0435\u0441\u0442\u0435 \u2014 \u043C\u043E\u0436\u043D\u043E \u043C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C.";
|
|
16528
|
+
return {
|
|
16529
|
+
contract: SETUP_CONTRACT,
|
|
16530
|
+
engine: o.engine?.installed ?? "",
|
|
16531
|
+
shell: o.shellVersion,
|
|
16532
|
+
ready,
|
|
16533
|
+
rows,
|
|
16534
|
+
missingMb,
|
|
16535
|
+
update,
|
|
16536
|
+
trouble,
|
|
16537
|
+
next
|
|
16538
|
+
};
|
|
16539
|
+
}
|
|
16443
16540
|
var WIDGET_MIME = "text/html;profile=mcp-app";
|
|
16444
16541
|
function widgetStamp(html) {
|
|
16445
16542
|
return createHash("sha256").update(html).digest("hex").slice(0, 8);
|
|
@@ -16650,6 +16747,108 @@ function runbarWidgetHtml() {
|
|
|
16650
16747
|
.side[hidden] { display: none; }
|
|
16651
16748
|
.side b { font-weight: 650; color: var(--ink); }
|
|
16652
16749
|
|
|
16750
|
+
/* \u2500\u2500\u2500 \u0428\u043A\u0430\u043B\u0430: \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u043A\u0430\u0447\u0430\u043D\u043E, \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0433\u043E\u0442\u043E\u0432\u043E \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
16751
|
+
|
|
16752
|
+
/* \u26A0 \u0428\u041A\u0410\u041B\u0410 \u2014 \u041E\u0414\u041D\u0410 \u041D\u0410 \u0421\u041A\u0410\u0427\u0418\u0412\u0410\u041D\u0418\u0415 \u0418 \u041D\u0410 \u041A\u0410\u0420\u0422\u041E\u0427\u041A\u0423. \u0412\u043B\u0430\u0434\u0435\u043B\u0435\u0446 2026-09-24: \xAB\u0447\u0442\u043E
|
|
16753
|
+
\u0441\u0442\u0430\u0432\u043B\u044E, \u0447\u0442\u043E \u043E\u0441\u0442\u0430\u043B\u043E\u0441\u044C, \u043F\u0440\u043E\u0433\u0440\u0435\u0441\u0441-\u0431\u0430\u0440\xBB. \u0416\u0451\u043B\u0442\u0430\u044F \u0437\u0430\u043B\u0438\u0432\u043A\u0430 \u2014 \u044D\u0442\u043E \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0442\u0430 \u0436\u0435
|
|
16754
|
+
\u0440\u043E\u043B\u044C, \u0447\u0442\u043E \u0443 \u0438\u0434\u0443\u0449\u0435\u0433\u043E \u044D\u0442\u0430\u043F\u0430; \u0448\u0438\u0440\u0438\u043D\u0443 \u0441\u0442\u0430\u0432\u0438\u0442 \u0441\u043A\u0440\u0438\u043F\u0442, \u0430 \u043F\u0435\u0440\u0435\u0445\u043E\u0434 \u043F\u043E \u0448\u0438\u0440\u0438\u043D\u0435
|
|
16755
|
+
\u043F\u043B\u0430\u0432\u043D\u044B\u0439, \u0447\u0442\u043E\u0431\u044B \u043E\u043F\u0440\u043E\u0441 \u0440\u0430\u0437 \u0432 2,5 \u0441 \u043D\u0435 \u0434\u0451\u0440\u0433\u0430\u043B \u0435\u0451 \u0441\u043A\u0430\u0447\u043A\u0430\u043C\u0438. */
|
|
16756
|
+
.meter {
|
|
16757
|
+
position: relative;
|
|
16758
|
+
height: 8px;
|
|
16759
|
+
margin-top: 12px;
|
|
16760
|
+
border-radius: 4px;
|
|
16761
|
+
background: var(--off);
|
|
16762
|
+
overflow: hidden;
|
|
16763
|
+
}
|
|
16764
|
+
.meter__fill {
|
|
16765
|
+
display: block;
|
|
16766
|
+
width: 0;
|
|
16767
|
+
height: 100%;
|
|
16768
|
+
border-radius: 4px;
|
|
16769
|
+
background: var(--yellow);
|
|
16770
|
+
transition: width .6s var(--ease);
|
|
16771
|
+
}
|
|
16772
|
+
.meter__cap {
|
|
16773
|
+
margin: 7px 0 0;
|
|
16774
|
+
color: var(--ink-soft);
|
|
16775
|
+
font-size: 13px;
|
|
16776
|
+
line-height: 1.4;
|
|
16777
|
+
font-variant-numeric: tabular-nums;
|
|
16778
|
+
}
|
|
16779
|
+
.meter__cap b { color: var(--ink); font-weight: 650; }
|
|
16780
|
+
.dl[hidden], .meter[hidden], .meter__cap[hidden] { display: none; }
|
|
16781
|
+
|
|
16782
|
+
/* \u2500\u2500\u2500 \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F: \u043E\u0442\u0432\u0435\u0442 setup \u0431\u0435\u0437 \u0437\u0430\u0434\u0430\u0447\u0438 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
16783
|
+
|
|
16784
|
+
/* \u26A0 \u041A\u0410\u0420\u0422\u041E\u0427\u041A\u0410 \u0412\u041C\u0415\u0421\u0422\u041E \u0421\u0412\u0401\u0420\u0422\u041A\u0418, \u0418 \u042D\u0422\u041E \u0416\u0418\u0412\u0410\u042F \u041F\u041E\u041B\u041E\u041C\u041A\u0410 2026-09-24. \u0420\u0430\u043C\u043A\u0443 \u0432\u0438\u0434\u0436\u0435\u0442\u0430
|
|
16785
|
+
\u0445\u043E\u0441\u0442 \u0440\u0438\u0441\u0443\u0435\u0442 \u043D\u0430 \u043A\u0430\u0436\u0434\u043E\u043C \u0432\u044B\u0437\u043E\u0432\u0435 setup; \u0441\u0432\u0451\u0440\u043D\u0443\u0442\u0430\u044F \u043F\u043E\u043B\u043E\u0441\u0430 \u0432 Claude Desktop
|
|
16786
|
+
\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u043B\u0430 \u043F\u043E\u0434 \u043E\u0442\u0432\u0435\u0442\u043E\u043C \u043F\u0443\u0441\u0442\u0443\u044E \u0441\u0435\u0440\u0443\u044E \u043F\u043B\u0430\u0448\u043A\u0443. */
|
|
16787
|
+
.card[hidden] { display: none; }
|
|
16788
|
+
.card__meta { margin: 4px 0 0; color: var(--ink-soft); font-size: 12.5px; font-variant-numeric: tabular-nums; }
|
|
16789
|
+
.card__meta[hidden] { display: none; }
|
|
16790
|
+
.parts { display: grid; gap: 2px 18px; margin: 14px 0 0; padding: 0; list-style: none; }
|
|
16791
|
+
.parts[hidden] { display: none; }
|
|
16792
|
+
.part {
|
|
16793
|
+
display: flex;
|
|
16794
|
+
align-items: center;
|
|
16795
|
+
gap: 10px;
|
|
16796
|
+
min-width: 0;
|
|
16797
|
+
padding: 6px 0;
|
|
16798
|
+
border-bottom: 1px solid var(--edge);
|
|
16799
|
+
font-size: 14px;
|
|
16800
|
+
line-height: 1.3;
|
|
16801
|
+
}
|
|
16802
|
+
/* \u0417\u043D\u0430\u043A \u0447\u0430\u0441\u0442\u0438 \u2014 \u0444\u043E\u0440\u043C\u0430, \u0430 \u043D\u0435 \u0442\u043E\u043B\u044C\u043A\u043E \u0446\u0432\u0435\u0442: \u0441\u0442\u043E\u0438\u0442 \u2014 \u0437\u0430\u043B\u0438\u0442\u044B\u0439 \u043A\u0440\u0443\u0436\u043E\u043A \u0441 \u0433\u0430\u043B\u043E\u0447\u043A\u043E\u0439,
|
|
16803
|
+
\u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u2014 \u0436\u0451\u043B\u0442\u043E\u0435 \u043A\u043E\u043B\u044C\u0446\u043E, \u043F\u043E \u043F\u0440\u043E\u0441\u044C\u0431\u0435 \u2014 \u0433\u043E\u043B\u0443\u0431\u043E\u0435 \u043F\u0443\u043D\u043A\u0442\u0438\u0440\u043D\u043E\u0435. */
|
|
16804
|
+
.part__m {
|
|
16805
|
+
position: relative;
|
|
16806
|
+
flex: none;
|
|
16807
|
+
width: 16px;
|
|
16808
|
+
height: 16px;
|
|
16809
|
+
border-radius: 50%;
|
|
16810
|
+
box-sizing: border-box;
|
|
16811
|
+
}
|
|
16812
|
+
.part.ok .part__m { background: var(--good); }
|
|
16813
|
+
.part.ok .part__m::before {
|
|
16814
|
+
content: "";
|
|
16815
|
+
position: absolute;
|
|
16816
|
+
top: 4px;
|
|
16817
|
+
left: 4px;
|
|
16818
|
+
width: 7px;
|
|
16819
|
+
height: 3.5px;
|
|
16820
|
+
border-left: 1.8px solid var(--good-ink);
|
|
16821
|
+
border-bottom: 1.8px solid var(--good-ink);
|
|
16822
|
+
transform: rotate(-45deg);
|
|
16823
|
+
}
|
|
16824
|
+
.part.missing .part__m { border: 2.5px solid var(--yellow); }
|
|
16825
|
+
.part.later .part__m { border: 2px dashed var(--note-dot); }
|
|
16826
|
+
.part__t { display: block; flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
|
|
16827
|
+
.part.ok .part__t { color: var(--ink-soft); }
|
|
16828
|
+
.part__w { flex: none; color: var(--ink-soft); font-size: 12.5px; font-variant-numeric: tabular-nums; }
|
|
16829
|
+
.part.missing .part__w { color: var(--ink); font-weight: 650; }
|
|
16830
|
+
/* \u0427\u0442\u043E \u0434\u0435\u043B\u0430\u0442\u044C \u0434\u0430\u043B\u044C\u0448\u0435 \u2014 \u043A\u0440\u0443\u043F\u043D\u0435\u0435 \u0441\u043F\u0438\u0441\u043A\u0430: \u044D\u0442\u043E \u043E\u0442\u0432\u0435\u0442 \u043D\u0430 \xAB\u0438 \u0447\u0442\u043E \u0442\u0435\u043F\u0435\u0440\u044C\xBB. */
|
|
16831
|
+
.next {
|
|
16832
|
+
display: flex;
|
|
16833
|
+
align-items: flex-start;
|
|
16834
|
+
gap: 9px;
|
|
16835
|
+
margin: 14px 0 0;
|
|
16836
|
+
font-size: 15px;
|
|
16837
|
+
font-weight: 650;
|
|
16838
|
+
line-height: 1.35;
|
|
16839
|
+
letter-spacing: -0.01em;
|
|
16840
|
+
}
|
|
16841
|
+
.next[hidden] { display: none; }
|
|
16842
|
+
.next::before {
|
|
16843
|
+
content: "";
|
|
16844
|
+
flex: none;
|
|
16845
|
+
width: 8px;
|
|
16846
|
+
height: 8px;
|
|
16847
|
+
margin-top: 6px;
|
|
16848
|
+
border-radius: 2px;
|
|
16849
|
+
background: var(--yellow);
|
|
16850
|
+
}
|
|
16851
|
+
|
|
16653
16852
|
/* \u2500\u2500\u2500 \u041A\u043E\u043D\u0435\u0446 \u0440\u0430\u0431\u043E\u0442\u044B \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
16654
16853
|
|
|
16655
16854
|
/* \u26A0 \u041E\u0422\u0412\u0415\u0422 \u041A\u0420\u0423\u041F\u041D\u0415\u0415 \u0425\u041E\u0414\u0410. \u041E\u0442\u0431\u0440\u0430\u043A\u043E\u0432\u043A\u0430 \u0432\u043B\u0430\u0434\u0435\u043B\u044C\u0446\u0430 \u043D\u0430 \u0444\u043E\u0440\u043C\u0435 \u0432\u044B\u0431\u043E\u0440\u0430 2026-09-10:
|
|
@@ -16762,6 +16961,7 @@ function runbarWidgetHtml() {
|
|
|
16762
16961
|
body { padding: 22px 20px 24px; }
|
|
16763
16962
|
h2 { font-size: 21px; }
|
|
16764
16963
|
.rail { gap: 5px; }
|
|
16964
|
+
.parts { grid-template-columns: 1fr 1fr; }
|
|
16765
16965
|
}
|
|
16766
16966
|
@media (min-width: 760px) {
|
|
16767
16967
|
body { padding: 26px 24px 28px; }
|
|
@@ -16781,7 +16981,20 @@ function runbarWidgetHtml() {
|
|
|
16781
16981
|
<span class="now__c" id="nowLeft" hidden></span>
|
|
16782
16982
|
</span>
|
|
16783
16983
|
</div>
|
|
16984
|
+
<div class="dl" id="dl" hidden>
|
|
16985
|
+
<div class="meter" id="dlMeter"><span class="meter__fill" id="dlFill"></span></div>
|
|
16986
|
+
<p class="meter__cap" id="dlCap"></p>
|
|
16987
|
+
</div>
|
|
16784
16988
|
<div class="msg" id="msg" hidden></div>
|
|
16989
|
+
<section class="card" id="card" hidden>
|
|
16990
|
+
<p class="card__meta" id="cardMeta" hidden></p>
|
|
16991
|
+
<div class="meter" id="cardMeter" hidden><span class="meter__fill" id="cardFill"></span></div>
|
|
16992
|
+
<p class="meter__cap" id="cardCap" hidden></p>
|
|
16993
|
+
<ul class="parts" id="cardRows" hidden></ul>
|
|
16994
|
+
<div class="msg" id="cardUpdate" hidden></div>
|
|
16995
|
+
<div class="note" id="cardTrouble" hidden></div>
|
|
16996
|
+
<p class="next" id="cardNext" hidden></p>
|
|
16997
|
+
</section>
|
|
16785
16998
|
<p class="side" id="behind" hidden></p>
|
|
16786
16999
|
<p class="side" id="ahead" hidden></p>
|
|
16787
17000
|
<div class="end" id="end" hidden>
|
|
@@ -16805,6 +17018,7 @@ function runbarWidgetHtml() {
|
|
|
16805
17018
|
// \u043F\u0440\u0438\u0447\u0438\u043D\u0435 (\u0430\u043D\u0442\u0438\u0432\u0438\u0440\u0443\u0441, \u043D\u0435\u0445\u0432\u0430\u0442\u043A\u0430 \u043F\u0430\u043C\u044F\u0442\u0438, \u0433\u043E\u043D\u043A\u0430 \u0437\u0430 \u0444\u0430\u0439\u043B\u043E\u043C \u0437\u0430\u0434\u0430\u043D\u0438\u044F).
|
|
16806
17019
|
var GIVE_UP_AFTER = 5;
|
|
16807
17020
|
var CONTRACT = '${JOB_CONTRACT}';
|
|
17021
|
+
var SETUP = '${SETUP_CONTRACT}';
|
|
16808
17022
|
|
|
16809
17023
|
var nextId = 1;
|
|
16810
17024
|
// Object.create(null), \u0430 \u043D\u0435 {}: \u0438\u043D\u0430\u0447\u0435 id \u0432\u0438\u0434\u0430 \xABtoString\xBB \u0434\u043E\u0441\u0442\u0430\u0451\u0442 \u0444\u0443\u043D\u043A\u0446\u0438\u044E \u0441
|
|
@@ -16936,6 +17150,7 @@ function runbarWidgetHtml() {
|
|
|
16936
17150
|
job = data;
|
|
16937
17151
|
// \u0414\u0430\u043D\u043D\u044B\u0435 \u043F\u0440\u0438\u0448\u043B\u0438 \u043F\u043E\u0441\u043B\u0435 \u0441\u0432\u0451\u0440\u0442\u043A\u0438 \u2014 \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043C\u0441\u044F \u0432 \u043B\u0435\u043D\u0442\u0443.
|
|
16938
17152
|
document.body.classList.remove('gone');
|
|
17153
|
+
byId('card').hidden = true;
|
|
16939
17154
|
var ended = !working(data.status);
|
|
16940
17155
|
|
|
16941
17156
|
show('what', data.what || '\u0420\u0430\u0431\u043E\u0442\u0430\u044E');
|
|
@@ -16955,9 +17170,13 @@ function runbarWidgetHtml() {
|
|
|
16955
17170
|
if (data.at && data.total) title = title + ' \xB7 \u044D\u0442\u0430\u043F ' + data.at + ' \u0438\u0437 ' + data.total;
|
|
16956
17171
|
show('nowTitle', title);
|
|
16957
17172
|
show('nowLeft', data.left || '');
|
|
16958
|
-
|
|
17173
|
+
var loading = download(data);
|
|
17174
|
+
// \u0421\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u0435 \u0443\u0436\u0435 \u0441\u043A\u0430\u0437\u0430\u043D\u043E \u0448\u043A\u0430\u043B\u043E\u0439 \u0438 \u043F\u043E\u0434\u043F\u0438\u0441\u044C\u044E \u043F\u043E\u0434 \u043D\u0435\u0439 \u2014 \u0442\u0430 \u0436\u0435 \u0441\u0442\u0440\u043E\u043A\u0430
|
|
17175
|
+
// \u0433\u043E\u043B\u0443\u0431\u043E\u0439 \u043F\u043B\u0430\u0448\u043A\u043E\u0439 \u0440\u044F\u0434\u043E\u043C \u0431\u044B\u043B\u0430 \u0431\u044B \u0432\u0442\u043E\u0440\u044B\u043C \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440\u043E\u043C \u043E\u0434\u043D\u0438\u0445 \u0438 \u0442\u0435\u0445 \u0436\u0435 \u0447\u0438\u0441\u0435\u043B.
|
|
17176
|
+
show('msg', data.status === 'waiting' || loading ? '' : (data.message || ''));
|
|
16959
17177
|
} else {
|
|
16960
17178
|
byId('msg').hidden = true;
|
|
17179
|
+
byId('dl').hidden = true;
|
|
16961
17180
|
}
|
|
16962
17181
|
|
|
16963
17182
|
// \xAB\u041F\u043E\u0437\u0430\u0434\u0438\xBB \u0438 \xAB\u0434\u0430\u043B\u044C\u0448\u0435\xBB \u043F\u0440\u0438\u0445\u043E\u0434\u044F\u0442 \u0441\u0442\u0440\u043E\u043A\u0430\u043C\u0438 \u0434\u0432\u0438\u0436\u043A\u0430 \u0446\u0435\u043B\u0438\u043A\u043E\u043C: \u0434\u0440\u043E\u0431\u0438\u0442\u044C \u0438\u0445 \u043F\u043E
|
|
@@ -16971,6 +17190,131 @@ function runbarWidgetHtml() {
|
|
|
16971
17190
|
reportSize();
|
|
16972
17191
|
}
|
|
16973
17192
|
|
|
17193
|
+
/**
|
|
17194
|
+
* \u0417\u0430\u0433\u043B\u0430\u0432\u043D\u0430\u044F \u0443 \u0440\u0443\u0441\u0441\u043A\u043E\u0433\u043E \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u044F \u0447\u0430\u0441\u0442\u0438, \u0430 \u0438\u043C\u044F \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u2014 \u043A\u0430\u043A \u0435\u0441\u0442\u044C.
|
|
17195
|
+
*
|
|
17196
|
+
* \u26A0 \u041D\u0415 CSS \xABfirst-letter\xBB. \u041D\u0430\u0437\u0432\u0430\u043D\u0438\u044F \u0447\u0430\u0441\u0442\u0435\u0439 \u043F\u0438\u0448\u0435\u0442 \u0434\u0432\u0438\u0436\u043E\u043A \u0441\u0442\u0440\u043E\u0447\u043D\u044B\u043C\u0438: \u043E\u043D\u0438 \u0436\u0435
|
|
17197
|
+
* \u0438\u0434\u0443\u0442 \u0432 \u0435\u0433\u043E \u043E\u0442\u0432\u0435\u0442 \u043C\u043E\u0434\u0435\u043B\u0438 \u0441\u0435\u0440\u0435\u0434\u0438\u043D\u043E\u0439 \u0444\u0440\u0430\u0437\u044B. \u041D\u043E \xABffmpeg\xBB \u2014 \u0438\u043C\u044F \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B, \u0438
|
|
17198
|
+
* \u043F\u0440\u0430\u0432\u0438\u043B\u043E \u0434\u043B\u044F \u0432\u0441\u0435\u0445 \u043F\u0435\u0440\u0432\u044B\u0445 \u0431\u0443\u043A\u0432 \u0434\u0435\u043B\u0430\u043B\u043E \u0438\u0437 \u043D\u0435\u0433\u043E \xABFfmpeg\xBB (\u0441\u043D\u0438\u043C\u043E\u043A 2026-09-24).
|
|
17199
|
+
*/
|
|
17200
|
+
function capital(text) {
|
|
17201
|
+
var s = String(text || '');
|
|
17202
|
+
return /^[\u0430-\u044F\u0451]/.test(s) ? s.charAt(0).toUpperCase() + s.slice(1) : s;
|
|
17203
|
+
}
|
|
17204
|
+
|
|
17205
|
+
/** \xAB245 \u041C\u0411\xBB, \xAB1,6 \u0413\u0411\xBB \u2014 \u043A\u0430\u043A \u0432 \u0441\u043B\u043E\u0432\u0430\u0445 setup, \u0430 \u043D\u0435 \u0433\u043E\u043B\u044B\u043C \u0447\u0438\u0441\u043B\u043E\u043C \u043C\u0435\u0433\u0430\u0431\u0430\u0439\u0442. */
|
|
17206
|
+
function weight(mb) {
|
|
17207
|
+
var n = Math.max(0, Math.round(Number(mb) || 0));
|
|
17208
|
+
if (n >= 1000) return (n / 1024).toFixed(1).replace('.', ',') + ' \u0413\u0411';
|
|
17209
|
+
return n + ' \u041C\u0411';
|
|
17210
|
+
}
|
|
17211
|
+
|
|
17212
|
+
function fill(id, percent) {
|
|
17213
|
+
var el = byId(id);
|
|
17214
|
+
if (el) el.style.width = Math.max(0, Math.min(100, Number(percent) || 0)) + '%';
|
|
17215
|
+
}
|
|
17216
|
+
|
|
17217
|
+
/**
|
|
17218
|
+
* \u0428\u043A\u0430\u043B\u0430 \u0441\u043A\u0430\u0447\u0438\u0432\u0430\u043D\u0438\u044F \u043F\u043E \u0447\u0438\u0441\u043B\u0430\u043C \u0437\u0430\u0434\u0430\u0447\u0438. \u0412\u0435\u0440\u043D\u0451\u0442, \u043D\u0430\u0440\u0438\u0441\u043E\u0432\u0430\u043D\u0430 \u043B\u0438 \u043E\u043D\u0430.
|
|
17219
|
+
*
|
|
17220
|
+
* \u26A0 \u0411\u0415\u0417 \xAB\u0418\u0417 \u0421\u041A\u041E\u041B\u042C\u041A\u0418\u0425\xBB \u0417\u0410\u041B\u0418\u0412\u041A\u0418 \u041D\u0415\u0422, \u0410 \u041F\u041E\u0414\u041F\u0418\u0421\u042C \u0415\u0421\u0422\u042C. \u0412\u0441\u0435\u0433\u043E \u0434\u0432\u0438\u0436\u043E\u043A \u0437\u043D\u0430\u0435\u0442 \u043D\u0435
|
|
17221
|
+
* \u0432\u0441\u0435\u0433\u0434\u0430; \u0437\u0430\u043B\u0438\u0442\u044C \u043D\u0430\u0443\u0433\u0430\u0434 \u2014 \u0441\u043E\u0432\u0440\u0430\u0442\u044C \u043E \u0434\u043E\u043B\u0435, \u0430 \u043C\u0435\u0433\u0430\u0431\u0430\u0439\u0442\u044B \u043F\u0440\u0430\u0432\u0434\u0438\u0432\u044B.
|
|
17222
|
+
*/
|
|
17223
|
+
function download(data) {
|
|
17224
|
+
var box = byId('dl');
|
|
17225
|
+
if (!box) return false;
|
|
17226
|
+
var got = Number(data.got) || 0;
|
|
17227
|
+
if (!got) { box.hidden = true; return false; }
|
|
17228
|
+
var of = Number(data.of) || 0;
|
|
17229
|
+
byId('dlMeter').hidden = !of;
|
|
17230
|
+
fill('dlFill', of ? data.percent : 0);
|
|
17231
|
+
var cap = byId('dlCap');
|
|
17232
|
+
cap.innerHTML = '';
|
|
17233
|
+
var b = document.createElement('b');
|
|
17234
|
+
b.textContent = of ? (got + ' \u0438\u0437 ' + weight(of)) : ('\u0441\u043A\u0430\u0447\u0430\u043D\u043E ' + weight(got));
|
|
17235
|
+
cap.appendChild(b);
|
|
17236
|
+
var tail = of ? ' \xB7 ' + (Number(data.percent) || 0) + '%' : '';
|
|
17237
|
+
if (data.eta) tail += ' \xB7 ' + data.eta;
|
|
17238
|
+
cap.appendChild(document.createTextNode(tail));
|
|
17239
|
+
cap.hidden = false;
|
|
17240
|
+
box.hidden = false;
|
|
17241
|
+
return true;
|
|
17242
|
+
}
|
|
17243
|
+
|
|
17244
|
+
// \u2500\u2500\u2500 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
17245
|
+
|
|
17246
|
+
/**
|
|
17247
|
+
* \u041E\u0442\u0432\u0435\u0442 setup \u0431\u0435\u0437 \u0437\u0430\u0434\u0430\u0447\u0438: \u0447\u0442\u043E \u0441\u0442\u043E\u0438\u0442, \u0447\u0435\u0433\u043E \u043D\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442, \u0447\u0442\u043E \u0432\u044B\u0448\u043B\u043E, \u0447\u0442\u043E \u0434\u0430\u043B\u044C\u0448\u0435.
|
|
17248
|
+
*
|
|
17249
|
+
* \u26A0 \u041E\u041F\u0420\u041E\u0421 \u041D\u0415 \u0417\u0410\u0412\u041E\u0414\u0418\u0422\u0421\u042F: \u0440\u0430\u0431\u043E\u0442\u044B \u043D\u0435\u0442, \u0441\u043F\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044C \u043D\u0435 \u043E \u0447\u0435\u043C. \u041A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u2014 \u0441\u043D\u0438\u043C\u043E\u043A
|
|
17250
|
+
* \u043D\u0430 \u043C\u043E\u043C\u0435\u043D\u0442 \u043E\u0442\u0432\u0435\u0442\u0430; \u043D\u043E\u0432\u044B\u0439 \u0432\u044B\u0437\u043E\u0432 setup \u043F\u0440\u0438\u043D\u0435\u0441\u0451\u0442 \u043D\u043E\u0432\u0443\u044E.
|
|
17251
|
+
*/
|
|
17252
|
+
function renderCard(data) {
|
|
17253
|
+
if (closed) return;
|
|
17254
|
+
job = null;
|
|
17255
|
+
document.body.classList.remove('gone');
|
|
17256
|
+
document.body.classList.remove('bad');
|
|
17257
|
+
var hide = ['now', 'rail', 'msg', 'dl', 'behind', 'ahead', 'clock', 'end', 'note'];
|
|
17258
|
+
for (var i = 0; i < hide.length; i++) { var el = byId(hide[i]); if (el) el.hidden = true; }
|
|
17259
|
+
|
|
17260
|
+
var rows = data.rows || [];
|
|
17261
|
+
var ok = 0, need = 0;
|
|
17262
|
+
for (var j = 0; j < rows.length; j++) {
|
|
17263
|
+
if (rows[j].state === 'ok') { ok++; need++; }
|
|
17264
|
+
else if (rows[j].state === 'missing') need++;
|
|
17265
|
+
}
|
|
17266
|
+
show('what', data.ready ? '\u0412\u0441\u0451 \u0433\u043E\u0442\u043E\u0432\u043E \u043A \u043C\u043E\u043D\u0442\u0430\u0436\u0443' : (need > ok ? '\u0414\u043B\u044F \u043C\u043E\u043D\u0442\u0430\u0436\u0430 \u043D\u0435 \u0432\u0441\u0451 \u043D\u0430 \u043C\u0435\u0441\u0442\u0435' : '\u041C\u043E\u043D\u0442\u0430\u0436 \u043D\u0430 \u044D\u0442\u043E\u043C \u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0435'));
|
|
17267
|
+
|
|
17268
|
+
var meta = [];
|
|
17269
|
+
if (data.engine) meta.push('\u0434\u0432\u0438\u0436\u043E\u043A ' + data.engine);
|
|
17270
|
+
if (data.shell) meta.push('\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435 ' + data.shell);
|
|
17271
|
+
show('cardMeta', meta.join(' \xB7 '));
|
|
17272
|
+
|
|
17273
|
+
// \u0428\u043A\u0430\u043B\u0430 \u0433\u043E\u0442\u043E\u0432\u043D\u043E\u0441\u0442\u0438 \u2014 \u043F\u043E \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u043C\u0443: \u0442\u043E, \u0447\u0442\u043E \u0432\u0441\u0442\u0430\u043D\u0435\u0442 \u043F\u043E \u043F\u0440\u043E\u0441\u044C\u0431\u0435, \u0434\u043E\u043B\u0435\u0439
|
|
17274
|
+
// \xAB\u043D\u0435 \u0433\u043E\u0442\u043E\u0432\u043E\xBB \u043D\u0435 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044F, \u0438\u043D\u0430\u0447\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A \u0431\u0435\u0437 \u0441\u0443\u0431\u0442\u0438\u0442\u0440\u043E\u0432 \u043D\u0430\u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u0438\u0434\u0435\u043B \u0431\u044B
|
|
17275
|
+
// \u043D\u0435\u0434\u043E\u043B\u0438\u0442\u0443\u044E \u043F\u043E\u043B\u043E\u0441\u0443 \u043D\u0430 \u0438\u0441\u043F\u0440\u0430\u0432\u043D\u043E\u0439 \u043C\u0430\u0448\u0438\u043D\u0435.
|
|
17276
|
+
byId('cardMeter').hidden = !need;
|
|
17277
|
+
fill('cardFill', need ? ok * 100 / need : 0);
|
|
17278
|
+
var cap = byId('cardCap');
|
|
17279
|
+
cap.innerHTML = '';
|
|
17280
|
+
if (need) {
|
|
17281
|
+
var b = document.createElement('b');
|
|
17282
|
+
b.textContent = '\u0413\u043E\u0442\u043E\u0432\u043E ' + ok + ' \u0438\u0437 ' + need;
|
|
17283
|
+
cap.appendChild(b);
|
|
17284
|
+
if (data.missingMb) cap.appendChild(document.createTextNode(' \xB7 \u0434\u043E\u043A\u0430\u0447\u0430\u0442\u044C ' + weight(data.missingMb)));
|
|
17285
|
+
}
|
|
17286
|
+
cap.hidden = !need;
|
|
17287
|
+
|
|
17288
|
+
var list = byId('cardRows');
|
|
17289
|
+
list.innerHTML = '';
|
|
17290
|
+
for (var k = 0; k < rows.length; k++) {
|
|
17291
|
+
var row = rows[k];
|
|
17292
|
+
var li = document.createElement('li');
|
|
17293
|
+
li.className = 'part ' + row.state;
|
|
17294
|
+
var mark = document.createElement('span');
|
|
17295
|
+
mark.className = 'part__m';
|
|
17296
|
+
li.appendChild(mark);
|
|
17297
|
+
var title = document.createElement('span');
|
|
17298
|
+
title.className = 'part__t';
|
|
17299
|
+
title.textContent = capital(row.title);
|
|
17300
|
+
li.appendChild(title);
|
|
17301
|
+
var w = document.createElement('span');
|
|
17302
|
+
w.className = 'part__w';
|
|
17303
|
+
w.textContent = row.state === 'ok' ? '\u0441\u0442\u043E\u0438\u0442'
|
|
17304
|
+
: row.state === 'later' ? ('\u043F\u043E \u043F\u0440\u043E\u0441\u044C\u0431\u0435' + (row.mb ? ' \xB7 ' + weight(row.mb) : ''))
|
|
17305
|
+
: (row.mb ? weight(row.mb) : '\u043D\u0435\u0442');
|
|
17306
|
+
li.appendChild(w);
|
|
17307
|
+
list.appendChild(li);
|
|
17308
|
+
}
|
|
17309
|
+
list.hidden = !rows.length;
|
|
17310
|
+
|
|
17311
|
+
show('cardUpdate', data.update || '');
|
|
17312
|
+
show('cardTrouble', data.trouble || '');
|
|
17313
|
+
show('cardNext', data.next || '');
|
|
17314
|
+
byId('card').hidden = false;
|
|
17315
|
+
reportSize();
|
|
17316
|
+
}
|
|
17317
|
+
|
|
16974
17318
|
function side(id, label, text) {
|
|
16975
17319
|
var el = byId(id);
|
|
16976
17320
|
if (!el) return;
|
|
@@ -17015,6 +17359,9 @@ function runbarWidgetHtml() {
|
|
|
17015
17359
|
/** \u041E\u0442\u043A\u0430\u0437 \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0430: \u0441\u043B\u043E\u0432\u0430 \u0432\u043C\u0435\u0441\u0442\u043E \u043F\u043E\u043B\u043E\u0441\u044B. \u041F\u0443\u0441\u0442\u0430\u044F \u0440\u0430\u043C\u043A\u0430 \u0442\u0443\u0442 \u0441\u0442\u0440\u0430\u0448\u043D\u0435\u0435 \u0431\u0435\u0434\u044B. */
|
|
17016
17360
|
function finishWithWords(text) {
|
|
17017
17361
|
job = null;
|
|
17362
|
+
document.body.classList.remove('gone');
|
|
17363
|
+
byId('card').hidden = true;
|
|
17364
|
+
byId('dl').hidden = true;
|
|
17018
17365
|
byId('now').hidden = true;
|
|
17019
17366
|
byId('rail').hidden = true;
|
|
17020
17367
|
byId('msg').hidden = true;
|
|
@@ -17044,7 +17391,7 @@ function runbarWidgetHtml() {
|
|
|
17044
17391
|
// \xAB\u0437\u0430\u043A\u0440\u044B\u0442\u043E\xBB, \u043F\u0440\u0438\u0448\u0435\u0434\u0448\u0430\u044F \u0441\u043B\u0435\u0434\u043E\u043C \u043D\u0430\u0441\u0442\u043E\u044F\u0449\u0430\u044F \u0437\u0430\u0434\u0430\u0447\u0430 (\u0445\u043E\u0441\u0442 \u0432\u043F\u0440\u0430\u0432\u0435 \u043F\u0440\u0438\u0441\u043B\u0430\u0442\u044C \u0434\u0432\u0430
|
|
17045
17392
|
// \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F \u043F\u043E\u0434\u0440\u044F\u0434) \u043E\u0441\u0442\u0430\u043B\u0430\u0441\u044C \u0431\u044B \u0431\u0435\u0437 \u043E\u043F\u0440\u043E\u0441\u0430 \u2014 \u043F\u043E\u043B\u043E\u0441\u0430 \u043F\u043E\u043A\u0430\u0437\u0430\u043B\u0430 \u0431\u044B \u043F\u0435\u0440\u0432\u044B\u0439
|
|
17046
17393
|
// \u043A\u0430\u0434\u0440 \u0438 \u0437\u0430\u043C\u0435\u0440\u043B\u0430.
|
|
17047
|
-
var all = ['now', 'rail', 'msg', 'behind', 'ahead', 'clock', 'end', 'note', 'what'];
|
|
17394
|
+
var all = ['now', 'rail', 'msg', 'dl', 'card', 'behind', 'ahead', 'clock', 'end', 'note', 'what'];
|
|
17048
17395
|
for (var i = 0; i < all.length; i++) { var el = byId(all[i]); if (el) el.hidden = true; }
|
|
17049
17396
|
document.body.classList.add('gone');
|
|
17050
17397
|
reportSize();
|
|
@@ -17085,8 +17432,16 @@ function runbarWidgetHtml() {
|
|
|
17085
17432
|
}
|
|
17086
17433
|
if (m.method === 'ui/notifications/tool-result') {
|
|
17087
17434
|
if (m.params && m.params.isError) { finishWithWords(words(m.params)); return; }
|
|
17435
|
+
// \u041E\u0442\u0432\u0435\u0442 setup \u0431\u0435\u0437 \u0437\u0430\u0434\u0430\u0447\u0438 \u2014 \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F, \u0430 \u043D\u0435 \u0441\u0432\u0451\u0440\u0442\u043A\u0430: \u0440\u0430\u043C\u043A\u0443 \u0445\u043E\u0441\u0442
|
|
17436
|
+
// \u0440\u0438\u0441\u0443\u0435\u0442 \u0432\u0441\u0451 \u0440\u0430\u0432\u043D\u043E, \u0438 \u0441\u0432\u0451\u0440\u043D\u0443\u0442\u0430\u044F \u043F\u043E\u043B\u043E\u0441\u0430 \u043E\u0441\u0442\u0430\u0432\u043B\u044F\u043B\u0430 \u0431\u044B \u043F\u0443\u0441\u0442\u0443\u044E \u043F\u043B\u0430\u0448\u043A\u0443.
|
|
17437
|
+
var card = m.params && m.params.structuredContent;
|
|
17438
|
+
if (card && card.contract === SETUP) { renderCard(card); return; }
|
|
17088
17439
|
var data = parse(m.params);
|
|
17089
|
-
// \u26A0 \u041E\u0422\u0412\u0415\u0422 \u0411\u0415\u0417 \u0417\u0410\u0414\u0410\u0427\u0418 \u2014 \u0421\u0412\u041E\u0420\u0410\u0427\u0418\u0412\u0410\u0415\u041C\u0421\u042F, \u0410 \u041D\u0415 \u0412\u0418\u0421\u0418\u041C \u041D\u0410
|
|
17440
|
+
// \u26A0 \u041E\u0422\u0412\u0415\u0422 \u0411\u0415\u0417 \u0417\u0410\u0414\u0410\u0427\u0418 \u0418 \u0411\u0415\u0417 \u041A\u0410\u0420\u0422\u041E\u0427\u041A\u0418 \u2014 \u0421\u0412\u041E\u0420\u0410\u0427\u0418\u0412\u0410\u0415\u041C\u0421\u042F, \u0410 \u041D\u0415 \u0412\u0418\u0421\u0418\u041C \u041D\u0410
|
|
17441
|
+
// \u0417\u0410\u0413\u041B\u0423\u0428\u041A\u0415. \u0423 setup \u043A\u0430\u0440\u0442\u043E\u0447\u043A\u0430 \u0435\u0441\u0442\u044C \u0432\u0441\u0435\u0433\u0434\u0430 (\u0432\u044B\u0448\u0435, 2026-09-24): \u0441\u0432\u0451\u0440\u0442\u043A\u0443
|
|
17442
|
+
// Claude Desktop \u043D\u0435 \u0443\u0431\u0438\u0440\u0430\u0435\u0442, \u0438 \u0442\u0430\u043C \u043E\u0441\u0442\u0430\u0432\u0430\u043B\u0430\u0441\u044C \u043F\u0443\u0441\u0442\u0430\u044F \u0440\u0430\u043C\u043A\u0430. \u0417\u0434\u0435\u0441\u044C
|
|
17443
|
+
// \u043E\u0441\u0442\u0430\u043B\u0438\u0441\u044C \u0447\u0443\u0436\u0438\u0435 \u043E\u0442\u0432\u0435\u0442\u044B \u0431\u0435\u0437 \u0440\u0430\u0431\u043E\u0442\u044B \u2014 plan \u0431\u0435\u0437 \u0432\u0438\u0434\u0435\u043E (docs/plan/README.md,
|
|
17444
|
+
// \u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0439 \u0431\u0440\u0430\u043A). \u041F\u043E\u043B\u043E\u0441\u0430
|
|
17090
17445
|
// \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D\u0430 \u0443 \u0412\u0421\u0415\u0413\u041E \u0438\u043D\u0441\u0442\u0440\u0443\u043C\u0435\u043D\u0442\u0430, \u0430 \u043D\u0435 \u0443 \u043E\u0442\u0434\u0435\u043B\u044C\u043D\u043E\u0433\u043E \u043E\u0442\u0432\u0435\u0442\u0430, \u0438 \u0445\u043E\u0441\u0442 \u0440\u0438\u0441\u0443\u0435\u0442
|
|
17091
17446
|
// \u0435\u0451 \u043D\u0430 \u043A\u0430\u0436\u0434\u043E\u043C \u0432\u044B\u0437\u043E\u0432\u0435 \u2014 \u0432 \u0442\u043E\u043C \u0447\u0438\u0441\u043B\u0435 \u043D\u0430 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0435 setup \u0431\u0435\u0437 \u0430\u0440\u0433\u0443\u043C\u0435\u043D\u0442\u043E\u0432,
|
|
17092
17447
|
// \u0433\u0434\u0435 \u043D\u0438\u043A\u0430\u043A\u043E\u0439 \u0440\u0430\u0431\u043E\u0442\u044B \u043D\u0435\u0442 \u0438 \u043D\u043E\u043C\u0435\u0440\u0430 \u0437\u0430\u0434\u0430\u0447\u0438 \u0432 \u043E\u0442\u0432\u0435\u0442\u0435 \u0442\u043E\u0436\u0435. \u0420\u0430\u043D\u044C\u0448\u0435 \u0437\u0434\u0435\u0441\u044C
|
|
@@ -17337,23 +17692,47 @@ function nameOrRefusal(candidate) {
|
|
|
17337
17692
|
var ASKED_POINTER_MS = 15e3;
|
|
17338
17693
|
var NEWS_POINTER_MS = 5e3;
|
|
17339
17694
|
var EXTRAS_LATER = "\u041C\u043E\u043D\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C \u0443\u0436\u0435 \u043C\u043E\u0436\u043D\u043E. \u0424\u043E\u043D\u043E\u043C \u0434\u043E\u043A\u0430\u0447\u0438\u0432\u0430\u044E \u0442\u043E, \u0431\u0435\u0437 \u0447\u0435\u0433\u043E \u043C\u043E\u043D\u0442\u0430\u0436 \u0438 \u0442\u0430\u043A \u0438\u0434\u0451\u0442: \u0448\u0443\u043C\u043E\u0434\u0430\u0432 \u0433\u043E\u043B\u043E\u0441\u0430 \u2014 \u043E\u043A\u043E\u043B\u043E 30 \u041C\u0411, \u043A\u0430\u0440\u0442\u0443 \u0433\u0435\u0440\u043E\u044F \u0438 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u0434\u043B\u044F \u0433\u0440\u0430\u0444\u0438\u043A\u0438 \u2014 \u0434\u043E 150 \u041C\u0411. \u0411\u0440\u0430\u0443\u0437\u0435\u0440 \u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F, \u0442\u043E\u043B\u044C\u043A\u043E \u0435\u0441\u043B\u0438 \u0435\u0433\u043E \u0441\u0431\u043E\u0440\u043A\u0430 \u0434\u043B\u044F \u044D\u0442\u043E\u0439 \u043C\u0430\u0448\u0438\u043D\u044B \u0443\u0436\u0435 \u0432\u044B\u043B\u043E\u0436\u0435\u043D\u0430: \u0433\u0440\u0430\u0444\u0438\u043A\u0430 \u0432 \u043C\u043E\u043D\u0442\u0430\u0436 \u0435\u0449\u0451 \u043D\u0435 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0430. \u041D\u0435 \u0434\u043E\u043A\u0430\u0447\u0430\u0435\u0442\u0441\u044F \u2014 \u043C\u043E\u043D\u0442\u0430\u0436 \u043D\u0435 \u0443\u043F\u0430\u0434\u0451\u0442, \u0430 setup \u0441\u043A\u0430\u0436\u0435\u0442 \u0441\u043B\u043E\u0432\u0430\u043C\u0438, \u0447\u0435\u0433\u043E \u043D\u0435\u0442.";
|
|
17340
|
-
async function
|
|
17695
|
+
async function inspectMachine(engine, asked) {
|
|
17341
17696
|
const video = asked.video;
|
|
17342
17697
|
const model = asked.model;
|
|
17343
17698
|
const place = engine.place();
|
|
17344
|
-
if (place === null) return toolError(engine.whyNoEngine());
|
|
17345
|
-
const
|
|
17699
|
+
if (place === null) return { result: toolError(engine.whyNoEngine()), readiness: null };
|
|
17700
|
+
const args = [
|
|
17346
17701
|
"env-check",
|
|
17347
17702
|
"--pack",
|
|
17348
17703
|
place.pack,
|
|
17349
17704
|
...video !== void 0 ? ["--video", path(video)] : [],
|
|
17350
17705
|
...model !== void 0 ? ["--model", model] : []
|
|
17351
|
-
]
|
|
17352
|
-
|
|
17706
|
+
];
|
|
17707
|
+
let readiness = null;
|
|
17708
|
+
let words;
|
|
17709
|
+
if (knowsJsonCheck(place.engine)) {
|
|
17710
|
+
const answer = await askReadiness(engine, place, args);
|
|
17711
|
+
if ("ok" in answer && !answer.ok) return { result: toolError(answer.text), readiness: null };
|
|
17712
|
+
if ("parts" in answer) readiness = answer;
|
|
17713
|
+
words = "parts" in answer ? answer.words : answer.text;
|
|
17714
|
+
} else {
|
|
17715
|
+
const outcome = await engine.command(args);
|
|
17716
|
+
if (!outcome.ok) return { result: toolError(outcome.text), readiness: null };
|
|
17717
|
+
words = outcome.text;
|
|
17718
|
+
}
|
|
17353
17719
|
const catalog = await askCatalog(engine, place.pack, video);
|
|
17354
|
-
return toolSuccess(`${
|
|
17720
|
+
return { result: toolSuccess(`${words}
|
|
17355
17721
|
|
|
17356
|
-
${catalog}`);
|
|
17722
|
+
${catalog}`), readiness };
|
|
17723
|
+
}
|
|
17724
|
+
async function askReadiness(engine, place, args) {
|
|
17725
|
+
const python = await engine.pythonTrouble();
|
|
17726
|
+
if (python !== null) return { ok: false, text: python };
|
|
17727
|
+
let stdout;
|
|
17728
|
+
try {
|
|
17729
|
+
stdout = (await engine.run(place, [...args, JSON_CHECK])).stdout;
|
|
17730
|
+
} catch (err) {
|
|
17731
|
+
const e = err;
|
|
17732
|
+
if (e.code !== 2 || typeof e.stdout !== "string") return parseFailure(err, "\u041F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043C\u0430\u0448\u0438\u043D\u044B \u043D\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u043B\u0430\u0441\u044C");
|
|
17733
|
+
stdout = e.stdout;
|
|
17734
|
+
}
|
|
17735
|
+
return readReadiness(stdout) ?? { ok: true, text: stdout.trim() };
|
|
17357
17736
|
}
|
|
17358
17737
|
async function installStep(engine, asked, key, baseUrl, tell) {
|
|
17359
17738
|
const step = asked.step;
|
|
@@ -17462,7 +17841,8 @@ ${EXTRAS_LATER}`), later]);
|
|
|
17462
17841
|
})
|
|
17463
17842
|
);
|
|
17464
17843
|
}
|
|
17465
|
-
async function updateEngine(engine, consent, key, baseUrl, timeoutMs = ASKED_POINTER_MS) {
|
|
17844
|
+
async function updateEngine(engine, consent, key, baseUrl, timeoutMs = ASKED_POINTER_MS, seen = () => {
|
|
17845
|
+
}) {
|
|
17466
17846
|
if (engine.pathSetByHand()) {
|
|
17467
17847
|
return toolSuccess(
|
|
17468
17848
|
"\u041F\u0430\u043F\u043A\u0430 \u0434\u0432\u0438\u0436\u043A\u0430 \u0437\u0430\u0434\u0430\u043D\u0430 \u0432\u0440\u0443\u0447\u043D\u0443\u044E \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u0439 NAPARNIK_ENGINE \u2014 \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u043D\u0435\u0447\u0435\u0433\u043E: \u0441\u0430\u043C\u043E\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435 \u0440\u0430\u0431\u043E\u0442\u0430\u0435\u0442 \u0441 \u0432\u0435\u0440\u0441\u0438\u043E\u043D\u043D\u043E\u0439 \u0440\u0430\u0441\u043A\u043B\u0430\u0434\u043A\u043E\u0439 \u0432 ~/.naparnik/engine, \u0430 \u044D\u0442\u0430 \u043F\u0430\u043F\u043A\u0430 \u043C\u0438\u043C\u043E \u043D\u0435\u0451. \u0421\u043A\u0430\u0436\u0438 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u0443, \u0447\u0442\u043E \u0434\u0432\u0438\u0436\u043E\u043A \u0437\u0434\u0435\u0441\u044C \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0435\u0442\u0441\u044F \u0442\u0435\u043C \u0436\u0435 \u0441\u043F\u043E\u0441\u043E\u0431\u043E\u043C, \u043A\u0430\u043A\u0438\u043C \u0431\u044B\u043B \u043F\u043E\u043B\u043E\u0436\u0435\u043D."
|
|
@@ -17475,6 +17855,12 @@ async function updateEngine(engine, consent, key, baseUrl, timeoutMs = ASKED_POI
|
|
|
17475
17855
|
}
|
|
17476
17856
|
const outcome = await fetchManifest(manifestUrl(engine, baseUrl), timeoutMs, key);
|
|
17477
17857
|
const decision = decide(engine.freshVersion(), outcome.ok ? outcome.manifest : null);
|
|
17858
|
+
seen({
|
|
17859
|
+
installed: engine.freshVersion(),
|
|
17860
|
+
fresh: decision.what === "nothing" ? null : decision.manifest.version,
|
|
17861
|
+
mb: decision.what === "nothing" ? 0 : Math.round(decision.manifest.bytes / 1024 / 1024),
|
|
17862
|
+
status: outcome.ok ? 0 : outcome.status ?? 0
|
|
17863
|
+
});
|
|
17478
17864
|
if (decision.what === "nothing") {
|
|
17479
17865
|
const ownDir2 = engine.freshVersion();
|
|
17480
17866
|
return toolSuccess(
|
|
@@ -17496,12 +17882,19 @@ ${VOICE_CLEANER_NOTE}
|
|
|
17496
17882
|
}
|
|
17497
17883
|
return asToolResult(await deploy(engine, decision.manifest, void 0, key));
|
|
17498
17884
|
}
|
|
17499
|
-
async function updateShell(engine, consent, key, baseUrl, timeoutMs = ASKED_POINTER_MS) {
|
|
17885
|
+
async function updateShell(engine, consent, key, baseUrl, timeoutMs = ASKED_POINTER_MS, seen = () => {
|
|
17886
|
+
}) {
|
|
17500
17887
|
const home = engine.home();
|
|
17501
17888
|
const url2 = engine.variable("NAPARNIK_BUNDLE_MANIFEST") ?? bundleUrlFor(baseUrl);
|
|
17502
17889
|
const outcome = await fetchShellManifest(url2, timeoutMs, key);
|
|
17503
17890
|
const installed = installedShell(home);
|
|
17504
17891
|
const decision = decideShell(installed, outcome.ok ? outcome.manifest : null);
|
|
17892
|
+
seen({
|
|
17893
|
+
installed,
|
|
17894
|
+
fresh: decision.what === "nothing" ? null : decision.manifest.version,
|
|
17895
|
+
mb: decision.what === "nothing" ? 0 : Math.round((decision.manifest.body?.bytes ?? 0) / 1024 / 1024),
|
|
17896
|
+
status: outcome.ok ? 0 : outcome.status ?? 0
|
|
17897
|
+
});
|
|
17505
17898
|
if (decision.what === "nothing") {
|
|
17506
17899
|
if (!outcome.ok) {
|
|
17507
17900
|
return toolSuccess(
|
|
@@ -17586,46 +17979,89 @@ function setupTool(engine, passport, key, baseUrl) {
|
|
|
17586
17979
|
}
|
|
17587
17980
|
}),
|
|
17588
17981
|
async execute(args, ctx) {
|
|
17589
|
-
|
|
17590
|
-
|
|
17591
|
-
|
|
17592
|
-
|
|
17593
|
-
|
|
17594
|
-
|
|
17595
|
-
|
|
17596
|
-
|
|
17597
|
-
|
|
17598
|
-
return consent ? installEverything(engine, key, baseUrl, tell) : lookAround(engine, args.model, key, baseUrl);
|
|
17599
|
-
}
|
|
17600
|
-
const step = HEAVY_STEPS[what];
|
|
17601
|
-
return consent ? installStep(engine, { step, model: args.model, consent: true }, key, baseUrl, tell) : askBeforeHeavy(engine, step, args.model, key, baseUrl);
|
|
17982
|
+
const news = { engine: null, shell: null };
|
|
17983
|
+
const said = await answer(args, ctx?.emitProgress, news);
|
|
17984
|
+
return withCard(said, () => setupCard({
|
|
17985
|
+
readiness: null,
|
|
17986
|
+
engine: news.engine ?? { installed: engine.freshVersion(), fresh: null, mb: 0, status: 0 },
|
|
17987
|
+
shell: news.shell,
|
|
17988
|
+
note: firstLine(said),
|
|
17989
|
+
shellVersion: VERSION
|
|
17990
|
+
}));
|
|
17602
17991
|
}
|
|
17603
17992
|
});
|
|
17993
|
+
async function answer(args, tell, news) {
|
|
17994
|
+
if (args.rollback === "engine") return asToolResult(rollback(engine));
|
|
17995
|
+
if (args.rollback === "shell") return asToolResult(rollbackShell(engine.home()));
|
|
17996
|
+
const consent = args.consent === true;
|
|
17997
|
+
const what = args.what;
|
|
17998
|
+
if (what === void 0) return lookAround(engine, args.model, key, baseUrl);
|
|
17999
|
+
if (what === "engine") {
|
|
18000
|
+
return updateEngine(engine, consent, key, baseUrl, ASKED_POINTER_MS, (seen) => {
|
|
18001
|
+
if (!consent) news.engine = seen;
|
|
18002
|
+
});
|
|
18003
|
+
}
|
|
18004
|
+
if (what === "shell") {
|
|
18005
|
+
return updateShell(engine, consent, key, baseUrl, ASKED_POINTER_MS, (seen) => {
|
|
18006
|
+
if (!consent) news.shell = seen;
|
|
18007
|
+
});
|
|
18008
|
+
}
|
|
18009
|
+
if (what === "all") {
|
|
18010
|
+
return consent ? installEverything(engine, key, baseUrl, tell) : lookAround(engine, args.model, key, baseUrl);
|
|
18011
|
+
}
|
|
18012
|
+
const step = HEAVY_STEPS[what];
|
|
18013
|
+
return consent ? installStep(engine, { step, model: args.model, consent: true }, key, baseUrl, tell) : askBeforeHeavy(engine, step, args.model, key, baseUrl);
|
|
18014
|
+
}
|
|
17604
18015
|
}
|
|
17605
18016
|
async function lookAround(engine, model, key, baseUrl) {
|
|
17606
|
-
|
|
18017
|
+
let engineNews = null;
|
|
18018
|
+
let shellNews = null;
|
|
18019
|
+
const toEngine = (news2) => {
|
|
18020
|
+
engineNews = news2;
|
|
18021
|
+
};
|
|
18022
|
+
const toShell = (news2) => {
|
|
18023
|
+
shellNews = news2;
|
|
18024
|
+
};
|
|
18025
|
+
const card = (said, o) => withCard(said, () => setupCard({
|
|
18026
|
+
readiness: o.readiness ?? null,
|
|
18027
|
+
engine: engineNews ?? { installed: engine.freshVersion(), fresh: null, mb: 0, status: 0 },
|
|
18028
|
+
shell: shellNews,
|
|
18029
|
+
...o.noEngine === true ? { noEngine: true } : {},
|
|
18030
|
+
...o.noPython === true ? { noPython: true } : {},
|
|
18031
|
+
note: firstLine(said),
|
|
18032
|
+
shellVersion: VERSION
|
|
18033
|
+
}));
|
|
18034
|
+
const shell = updateShell(engine, false, key, baseUrl, NEWS_POINTER_MS, toShell);
|
|
17607
18035
|
if (engine.place() === null) {
|
|
17608
18036
|
const payload = await installPayload(engine, {
|
|
17609
18037
|
consent: false,
|
|
17610
18038
|
manifestUrl: manifestUrl(engine, baseUrl),
|
|
17611
18039
|
...key !== void 0 ? { key } : {}
|
|
17612
18040
|
});
|
|
17613
|
-
return together([toolSuccess(payload.text), await shell]);
|
|
18041
|
+
return card(together([toolSuccess(payload.text), await shell]), { noEngine: true });
|
|
17614
18042
|
}
|
|
17615
18043
|
if (await engine.pythonTrouble() !== null) {
|
|
17616
18044
|
const python = await installPython(engine, { consent: false });
|
|
17617
|
-
return together([
|
|
18045
|
+
return card(together([
|
|
17618
18046
|
toolSuccess(python.text),
|
|
17619
|
-
await updateEngine(engine, false, key, baseUrl, NEWS_POINTER_MS),
|
|
18047
|
+
await updateEngine(engine, false, key, baseUrl, NEWS_POINTER_MS, toEngine),
|
|
17620
18048
|
await shell
|
|
17621
|
-
]);
|
|
18049
|
+
]), { noPython: true });
|
|
17622
18050
|
}
|
|
17623
18051
|
const [machine, news, own] = await Promise.all([
|
|
17624
|
-
|
|
17625
|
-
updateEngine(engine, false, key, baseUrl, NEWS_POINTER_MS),
|
|
18052
|
+
inspectMachine(engine, { model }),
|
|
18053
|
+
updateEngine(engine, false, key, baseUrl, NEWS_POINTER_MS, toEngine),
|
|
17626
18054
|
shell
|
|
17627
18055
|
]);
|
|
17628
|
-
return together([machine, news, own]);
|
|
18056
|
+
return card(together([machine.result, news, own]), { readiness: machine.readiness });
|
|
18057
|
+
}
|
|
18058
|
+
function withCard(result, card) {
|
|
18059
|
+
if (result.type !== "success" || result.structured !== void 0) return result;
|
|
18060
|
+
return toolSuccess(wordsOf(result.content), card());
|
|
18061
|
+
}
|
|
18062
|
+
function firstLine(result) {
|
|
18063
|
+
const text2 = result.type === "success" ? wordsOf(result.content) : result.error;
|
|
18064
|
+
return text2.split("\n").map((line) => line.trim()).find((line) => line !== "") ?? "";
|
|
17629
18065
|
}
|
|
17630
18066
|
async function installEverything(engine, key, baseUrl, tell) {
|
|
17631
18067
|
const said = [await updateShell(engine, true, key, baseUrl)];
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Engine, chooseBody, handOverToBody, VERSION, rollback, rollbackShell, remove, fromNpxCache, install, keyFromBlock, readConfig, ForeignBlockError, currentMachineFingerprint, CrashReporter, watchProcessCrashes, McpServer, buildAll, realPace, buildResources, StdioServerTransport, fromHost, WHERE_TO_GET_KEY, Wakefulness, systemBlocker, updateEngine, installStep, NaparnikApiClient, timeToCheck2, manifestUrlFor, fetchManifest, markChecked2, decide, shellDir, timeToCheck, bundleUrlFor, fetchShellManifest, markChecked, decideShell, installedShell, NaparnikConfigError } from './chunk-
|
|
2
|
+
import { Engine, chooseBody, handOverToBody, VERSION, rollback, rollbackShell, remove, fromNpxCache, install, keyFromBlock, readConfig, ForeignBlockError, currentMachineFingerprint, CrashReporter, watchProcessCrashes, McpServer, buildAll, realPace, buildResources, StdioServerTransport, fromHost, WHERE_TO_GET_KEY, Wakefulness, systemBlocker, updateEngine, installStep, NaparnikApiClient, timeToCheck2, manifestUrlFor, fetchManifest, markChecked2, decide, shellDir, timeToCheck, bundleUrlFor, fetchShellManifest, markChecked, decideShell, installedShell, NaparnikConfigError } from './chunk-QD2NNOLZ.js';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { realpathSync, readFileSync } from 'fs';
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1534,9 +1534,9 @@ declare class NaparnikConfigError extends NaparnikError {
|
|
|
1534
1534
|
* годится ли она для новой начинки: разойдись она с пакетом, и в логах будет
|
|
1535
1535
|
* стоять чужое число, а обновление начнёт считать оболочку не той.
|
|
1536
1536
|
*/
|
|
1537
|
-
declare const VERSION = "0.10.
|
|
1537
|
+
declare const VERSION = "0.10.40";
|
|
1538
1538
|
/** Как мы представляемся серверу Напарника. По нему в логах видно оболочку. */
|
|
1539
|
-
declare const USER_AGENT = "naparnik-mcp/0.10.
|
|
1539
|
+
declare const USER_AGENT = "naparnik-mcp/0.10.40";
|
|
1540
1540
|
/**
|
|
1541
1541
|
* Самая старая начинка (движок монтажа), с которой эта оболочка работает.
|
|
1542
1542
|
* Обновление начинки ниже этой версии не ставится, а выше — требует оболочки
|
|
@@ -1622,12 +1622,18 @@ declare function parseEngineManifest(raw: unknown, from: string): ManifestOutcom
|
|
|
1622
1622
|
* Что вышло из разбора: наш объект — или причина, по которой его нет.
|
|
1623
1623
|
* Одна форма на оба указателя.
|
|
1624
1624
|
*/
|
|
1625
|
+
/**
|
|
1626
|
+
* `status` — код раздачи, когда она ответила отказом. Нужен карточке `setup`:
|
|
1627
|
+
* 401 (ключа нет или чужой) и 403 (ключ наш, подписка кончилась) человеку
|
|
1628
|
+
* говорятся разными словами, а в `why` они слиты в одну фразу для модели.
|
|
1629
|
+
*/
|
|
1625
1630
|
type Parsed<T> = {
|
|
1626
1631
|
ok: true;
|
|
1627
1632
|
manifest: T;
|
|
1628
1633
|
} | {
|
|
1629
1634
|
ok: false;
|
|
1630
1635
|
why: string;
|
|
1636
|
+
status?: number;
|
|
1631
1637
|
};
|
|
1632
1638
|
|
|
1633
1639
|
/** Умолчание: раздача прода. Одна правда с адресом API — `config.ts`. */
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { DEFAULT_HOME, DeliveryError, Engine, ForeignBlockError, INSIDE_PYTHON, INSTALL_STEPS, KEEP_COPIES, KEEP_VERSIONS, LONG_STEPS, MANIFEST_TIMEOUT_MS, MANIFEST_URL, MARKER, MIN_ENGINE, NaparnikApiClient, NaparnikAuthError, NaparnikClientError, NaparnikConfigError, NaparnikError, NaparnikInsufficientBalanceError, NaparnikScopeError, NaparnikServerError, NaparnikTimeoutError, PAUSE_HOURS, SERVER_NAME, SOURCES_FILE, START_SEC, TOOL_SEC, USER_AGENT, VERSION, buildAll, buildBlock, buildResources, compare, configPath, decide, defineTool, deploy, downloadFile, fetchManifest, fileOrRefusal, findBlock, fromNpxCache, inside, install, installPayload, installPython, jsonSchemaOf, keyInTable, lastLine, loadConfig, markChecked2 as markChecked, markCurrent, parseEngineManifest, parseFailure, path, platformKey, previousVersion, probe, pythonSource, refusalFor, remove, rollback, tarEntries, tidyOld, timeToCheck2 as timeToCheck, unpackArchive, withArgs } from './chunk-
|
|
1
|
+
export { DEFAULT_HOME, DeliveryError, Engine, ForeignBlockError, INSIDE_PYTHON, INSTALL_STEPS, KEEP_COPIES, KEEP_VERSIONS, LONG_STEPS, MANIFEST_TIMEOUT_MS, MANIFEST_URL, MARKER, MIN_ENGINE, NaparnikApiClient, NaparnikAuthError, NaparnikClientError, NaparnikConfigError, NaparnikError, NaparnikInsufficientBalanceError, NaparnikScopeError, NaparnikServerError, NaparnikTimeoutError, PAUSE_HOURS, SERVER_NAME, SOURCES_FILE, START_SEC, TOOL_SEC, USER_AGENT, VERSION, buildAll, buildBlock, buildResources, compare, configPath, decide, defineTool, deploy, downloadFile, fetchManifest, fileOrRefusal, findBlock, fromNpxCache, inside, install, installPayload, installPython, jsonSchemaOf, keyInTable, lastLine, loadConfig, markChecked2 as markChecked, markCurrent, parseEngineManifest, parseFailure, path, platformKey, previousVersion, probe, pythonSource, refusalFor, remove, rollback, tarEntries, tidyOld, timeToCheck2 as timeToCheck, unpackArchive, withArgs } from './chunk-QD2NNOLZ.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naparnik/mcp",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.40",
|
|
4
4
|
"description": "MCP-сервер Напарника: монтаж вертикального видео на машине пользователя — паузы, субтитры, герой на новом фоне, звук. Видео никуда не уезжает.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"private": false,
|