@taskless-app/swarm 0.6.0 → 0.6.1
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/README.md +21 -0
- package/dist/cli.js +126 -7
- package/dist/overmind.js +403 -154
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -152,6 +152,27 @@ swarm remove --yes # отключить машину от роя цел
|
|
|
152
152
|
машин (её незавершённые прогоны освобождаются и уедут на другие машины) и стирает
|
|
153
153
|
токены. Вернуть — `swarm login && swarm start`.
|
|
154
154
|
|
|
155
|
+
## Перелогин — одна команда
|
|
156
|
+
|
|
157
|
+
Токен машины отзывается сам собой: вошли на второй машине, нажали «сбросить токен
|
|
158
|
+
роя», выключили рой тумблером. Демон при этом жив и тикает, но работу не берёт, а в
|
|
159
|
+
логе повторяет одну строку — «токен роя отозван … Почини одной командой: swarm login».
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
swarm login # и всё: без stop, без start, без чтения логов
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Команда сама разруливает демона: увидела поднятого — **гасит его аккуратно** (как
|
|
166
|
+
`swarm stop --wait`: живые дроны доигрывают, новую работу рой в это время не берёт),
|
|
167
|
+
поднимает страницу входа и **поднимает демона обратно** — уже с новым токеном.
|
|
168
|
+
Перезапуск обязателен: токен читается один раз при старте процесса, иначе демон
|
|
169
|
+
продолжил бы стучаться старым.
|
|
170
|
+
|
|
171
|
+
Ждать нечего — `swarm stop --force` в другом терминале оборвёт дронов и вход пойдёт
|
|
172
|
+
сразу. Демон был погашен до команды — обратно она его не поднимает: было выключено,
|
|
173
|
+
выключенным и останется. Вход не удался или вкладку закрыли — демон возвращается в то
|
|
174
|
+
состояние, в котором был.
|
|
175
|
+
|
|
155
176
|
## Кем исполнять дрона
|
|
156
177
|
|
|
157
178
|
Рою всё равно, какой агент внутри: всё, что знает про конкретный харнесс (как
|
package/dist/cli.js
CHANGED
|
@@ -613,15 +613,19 @@ var init_hostPool = __esm({
|
|
|
613
613
|
});
|
|
614
614
|
|
|
615
615
|
// ../swarm-core/src/hostCommands.ts
|
|
616
|
-
var HOST_COMMAND_STATUSES, TERMINAL, HOST_COMMAND_OPEN_STATUSES, HOST_COMMAND_TTL_MS, HOST_COMMAND_KEEPALIVE_MS, RUN_SCOPED_COMMAND_KINDS, RUN_SCOPED;
|
|
616
|
+
var SWARM_PACKAGE_NAME, MANUAL_UPDATE_COMMAND, HOST_COMMAND_STATUSES, TERMINAL, HOST_COMMAND_OPEN_STATUSES, HOST_COMMAND_TTL_MS, HOST_COMMAND_KEEPALIVE_MS, HOST_COMMAND_ACK_GRACE_MS, HOST_COMMAND_MUTE_REASON, RUN_SCOPED_COMMAND_KINDS, RUN_SCOPED;
|
|
617
617
|
var init_hostCommands = __esm({
|
|
618
618
|
"../swarm-core/src/hostCommands.ts"() {
|
|
619
619
|
"use strict";
|
|
620
|
+
SWARM_PACKAGE_NAME = "@taskless-app/swarm";
|
|
621
|
+
MANUAL_UPDATE_COMMAND = `npm i -g ${SWARM_PACKAGE_NAME}@latest`;
|
|
620
622
|
HOST_COMMAND_STATUSES = ["pending", "delivered", "running", "done", "failed", "rejected", "expired"];
|
|
621
623
|
TERMINAL = /* @__PURE__ */ new Set(["done", "failed", "rejected", "expired"]);
|
|
622
624
|
HOST_COMMAND_OPEN_STATUSES = HOST_COMMAND_STATUSES.filter((s) => !TERMINAL.has(s));
|
|
623
625
|
HOST_COMMAND_TTL_MS = 30 * 6e4;
|
|
624
626
|
HOST_COMMAND_KEEPALIVE_MS = 10 * 6e4;
|
|
627
|
+
HOST_COMMAND_ACK_GRACE_MS = 5 * 6e4;
|
|
628
|
+
HOST_COMMAND_MUTE_REASON = `\u043C\u0430\u0448\u0438\u043D\u0430 \u043D\u0435 \u043F\u043E\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u043B\u0430 \u0438\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435 \u2014 \u0432\u0435\u0440\u043E\u044F\u0442\u043D\u043E, \u0434\u0435\u043C\u043E\u043D \u0441\u0442\u0430\u0440\u0435\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u044B. \u041E\u0431\u043D\u043E\u0432\u0438 \u0432\u0440\u0443\u0447\u043D\u0443\u044E: ${MANUAL_UPDATE_COMMAND}`;
|
|
625
629
|
RUN_SCOPED_COMMAND_KINDS = ["stop_run", "wake_run"];
|
|
626
630
|
RUN_SCOPED = new Set(RUN_SCOPED_COMMAND_KINDS);
|
|
627
631
|
}
|
|
@@ -1833,7 +1837,7 @@ var init_package = __esm({
|
|
|
1833
1837
|
"package.json"() {
|
|
1834
1838
|
package_default = {
|
|
1835
1839
|
name: "@taskless-app/swarm",
|
|
1836
|
-
version: "0.6.
|
|
1840
|
+
version: "0.6.1",
|
|
1837
1841
|
type: "module",
|
|
1838
1842
|
description: "Local control plane for a fleet of AI coding agents (drones), coordinating through Taskless. The overmind runs the swarm.",
|
|
1839
1843
|
keywords: [
|
|
@@ -1882,7 +1886,8 @@ var init_package = __esm({
|
|
|
1882
1886
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
1883
1887
|
execa: "^10.0.0",
|
|
1884
1888
|
zod: "3.25.76"
|
|
1885
|
-
}
|
|
1889
|
+
},
|
|
1890
|
+
gitHead: "415ad928e18430894ae24ac2e4267073f5c6da14"
|
|
1886
1891
|
};
|
|
1887
1892
|
}
|
|
1888
1893
|
});
|
|
@@ -1993,6 +1998,14 @@ async function probeAgentToken(args, fetchFn = fetch) {
|
|
|
1993
1998
|
return "unreachable";
|
|
1994
1999
|
}
|
|
1995
2000
|
}
|
|
2001
|
+
function isRevokedTokenError(e) {
|
|
2002
|
+
if (e && typeof e === "object" && e.code === 401) return true;
|
|
2003
|
+
const text = e instanceof Error ? e.message : typeof e === "string" ? e : "";
|
|
2004
|
+
return /invalid_token|(?:http|status|code)[ =:]*401\b|\(401\)|401 unauthorized/i.test(text);
|
|
2005
|
+
}
|
|
2006
|
+
function revokedTokenLine() {
|
|
2007
|
+
return "[taskless] \u0442\u043E\u043A\u0435\u043D \u0440\u043E\u044F \u043E\u0442\u043E\u0437\u0432\u0430\u043D (401 invalid_token) \u2014 \u0440\u043E\u0439 \u043D\u0435 \u0431\u0435\u0440\u0451\u0442 \u0440\u0430\u0431\u043E\u0442\u0443. \u041F\u043E\u0447\u0438\u043D\u0438 \u043E\u0434\u043D\u043E\u0439 \u043A\u043E\u043C\u0430\u043D\u0434\u043E\u0439: swarm login";
|
|
2008
|
+
}
|
|
1996
2009
|
var STORE_PATH2, base2;
|
|
1997
2010
|
var init_agentToken = __esm({
|
|
1998
2011
|
"src/agentToken.ts"() {
|
|
@@ -3216,8 +3229,9 @@ var SWARM_PACKAGE, LATEST_TIMEOUT_MS;
|
|
|
3216
3229
|
var init_release = __esm({
|
|
3217
3230
|
"src/release.ts"() {
|
|
3218
3231
|
"use strict";
|
|
3232
|
+
init_src();
|
|
3219
3233
|
init_claudeBin();
|
|
3220
|
-
SWARM_PACKAGE =
|
|
3234
|
+
SWARM_PACKAGE = SWARM_PACKAGE_NAME;
|
|
3221
3235
|
LATEST_TIMEOUT_MS = 4e3;
|
|
3222
3236
|
}
|
|
3223
3237
|
});
|
|
@@ -8908,7 +8922,9 @@ async function connectSwarmMcp(cfg) {
|
|
|
8908
8922
|
try {
|
|
8909
8923
|
await client.connect(transport);
|
|
8910
8924
|
} catch (e) {
|
|
8911
|
-
console.warn(
|
|
8925
|
+
console.warn(
|
|
8926
|
+
isRevokedTokenError(e) ? `${revokedTokenLine()} (\u043F\u043E\u043A\u0430 \u0442\u043E\u043A\u0435\u043D\u0430 \u043D\u0435\u0442 \u2014 \u0441\u043E\u0431\u044B\u0442\u0438\u044F \u043A\u043E\u043F\u044F\u0442\u0441\u044F \u0432 outbox)` : `Swarm MCP: \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0441\u044F \u043D\u0435 \u0432\u044B\u0448\u043B\u043E (${e instanceof Error ? e.message : e}) \u2192 \u0431\u0443\u0444\u0435\u0440 \u0432 outbox.`
|
|
8927
|
+
);
|
|
8912
8928
|
return null;
|
|
8913
8929
|
}
|
|
8914
8930
|
return async (name, args) => await client.callTool({ name, arguments: swarmToolArgs(name, args, workspace) });
|
|
@@ -8984,6 +9000,7 @@ function resilientSwarmMcp(opts = {}) {
|
|
|
8984
9000
|
|
|
8985
9001
|
// src/login.ts
|
|
8986
9002
|
import { execa as execa2 } from "execa";
|
|
9003
|
+
import { createServer } from "net";
|
|
8987
9004
|
async function waitForLogin(d) {
|
|
8988
9005
|
const deadline = d.now() + d.timeoutMs;
|
|
8989
9006
|
for (; ; ) {
|
|
@@ -8993,6 +9010,53 @@ async function waitForLogin(d) {
|
|
|
8993
9010
|
await d.sleep(d.pollMs);
|
|
8994
9011
|
}
|
|
8995
9012
|
}
|
|
9013
|
+
async function withDaemonStopped(d, body) {
|
|
9014
|
+
const st = await d.status();
|
|
9015
|
+
if (!st) {
|
|
9016
|
+
if (!await d.portFree()) {
|
|
9017
|
+
d.err(
|
|
9018
|
+
`\u0432\u0445\u043E\u0434 \u041D\u0415 \u0441\u043E\u0441\u0442\u043E\u044F\u043B\u0441\u044F: \u043F\u043E\u0440\u0442 ${d.port} \u0437\u0430\u043D\u044F\u0442, \u043D\u043E \u044D\u0442\u043E \u043D\u0435 \u0434\u0435\u043C\u043E\u043D \u0440\u043E\u044F (\u0435\u0433\u043E \u043C\u043E\u0440\u0434\u0430 \u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442). \u0421\u0442\u0440\u0430\u043D\u0438\u0446\u0430 \u0432\u0445\u043E\u0434\u0430 \u043E\u0431\u044F\u0437\u0430\u043D\u0430 \u043F\u043E\u0434\u043D\u044F\u0442\u044C\u0441\u044F \u0438\u043C\u0435\u043D\u043D\u043E \u043D\u0430 \u043D\u0451\u043C \u2014 \u043E\u043D \u0437\u0430\u0448\u0438\u0442 \u0432 redirect_uri. \u041E\u0441\u0432\u043E\u0431\u043E\u0434\u0438 \u043F\u043E\u0440\u0442 \u0438 \u043F\u043E\u0432\u0442\u043E\u0440\u0438: swarm login`
|
|
9019
|
+
);
|
|
9020
|
+
return 1;
|
|
9021
|
+
}
|
|
9022
|
+
const code2 = await body();
|
|
9023
|
+
if (code2 === 0) d.out("\u0434\u0435\u043C\u043E\u043D \u043D\u0430 \u044D\u0442\u043E\u0439 \u043C\u0430\u0448\u0438\u043D\u0435 \u043D\u0435 \u043F\u043E\u0434\u043D\u044F\u0442 \u2014 \u0440\u043E\u0439 \u0436\u0434\u0451\u0442 \u0437\u0430\u043F\u0443\u0441\u043A\u0430: swarm start");
|
|
9024
|
+
return code2;
|
|
9025
|
+
}
|
|
9026
|
+
d.out(
|
|
9027
|
+
st.live.length ? `\u0434\u0435\u043C\u043E\u043D \u0440\u043E\u044F \u043F\u043E\u0434\u043D\u044F\u0442, \u0436\u0438\u0432\u044B\u0445 \u0441\u0435\u0441\u0441\u0438\u0439: ${st.live.length}. \u0413\u0430\u0448\u0443 \u0435\u0433\u043E \u0441\u0430\u043C \u2014 \u0432\u0445\u043E\u0434 \u043F\u043E\u0434\u043D\u0438\u043C\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u043D\u0430 \u0442\u043E\u043C \u0436\u0435 \u043F\u043E\u0440\u0442\u0443 ${d.port}.` : `\u0434\u0435\u043C\u043E\u043D \u0440\u043E\u044F \u043F\u043E\u0434\u043D\u044F\u0442 \u2014 \u0433\u0430\u0448\u0443 \u0435\u0433\u043E \u0441\u0430\u043C: \u0432\u0445\u043E\u0434 \u043F\u043E\u0434\u043D\u0438\u043C\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0443 \u043D\u0430 \u0442\u043E\u043C \u0436\u0435 \u043F\u043E\u0440\u0442\u0443 ${d.port}.`
|
|
9028
|
+
);
|
|
9029
|
+
if (await d.stop() !== "stopped") {
|
|
9030
|
+
d.err(`\u0432\u0445\u043E\u0434 \u041D\u0415 \u0441\u043E\u0441\u0442\u043E\u044F\u043B\u0441\u044F: \u0434\u0435\u043C\u043E\u043D \u043D\u0435 \u043F\u043E\u0433\u0430\u0448\u0435\u043D (\u0441\u043C. \u0432\u044B\u0448\u0435), \u043F\u043E\u0440\u0442 ${d.port} \u0437\u0430\u043D\u044F\u0442 \u0438\u043C. \u0420\u043E\u0439 \u043E\u0441\u0442\u0430\u043B\u0441\u044F \u043A\u0430\u043A \u0431\u044B\u043B.`);
|
|
9031
|
+
return 1;
|
|
9032
|
+
}
|
|
9033
|
+
if (!await d.portFree()) {
|
|
9034
|
+
d.err(`\u0432\u0445\u043E\u0434 \u041D\u0415 \u0441\u043E\u0441\u0442\u043E\u044F\u043B\u0441\u044F: \u0434\u0435\u043C\u043E\u043D \u043F\u043E\u0433\u0430\u0448\u0435\u043D, \u043D\u043E \u043F\u043E\u0440\u0442 ${d.port} \u0432\u0441\u0451 \u0440\u0430\u0432\u043D\u043E \u0437\u0430\u043D\u044F\u0442 \u043A\u0435\u043C-\u0442\u043E \u0435\u0449\u0451. \u041F\u043E\u0434\u043D\u0438\u043C\u0430\u044E \u0440\u043E\u0439 \u043E\u0431\u0440\u0430\u0442\u043D\u043E.`);
|
|
9035
|
+
await restoreDaemon(d, false);
|
|
9036
|
+
return 1;
|
|
9037
|
+
}
|
|
9038
|
+
let code = 1;
|
|
9039
|
+
try {
|
|
9040
|
+
code = await body();
|
|
9041
|
+
return code;
|
|
9042
|
+
} finally {
|
|
9043
|
+
await restoreDaemon(d, code === 0);
|
|
9044
|
+
}
|
|
9045
|
+
}
|
|
9046
|
+
async function restoreDaemon(d, loginOk) {
|
|
9047
|
+
d.out(
|
|
9048
|
+
loginOk ? "\u0432\u0445\u043E\u0434 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D \u2014 \u043F\u043E\u0434\u043D\u0438\u043C\u0430\u044E \u0434\u0435\u043C\u043E\u043D\u0430 \u043E\u0431\u0440\u0430\u0442\u043D\u043E, \u0443\u0436\u0435 \u0441 \u043D\u043E\u0432\u044B\u043C \u0442\u043E\u043A\u0435\u043D\u043E\u043C\u2026" : "\u0432\u0445\u043E\u0434 \u043D\u0435 \u0441\u043E\u0441\u0442\u043E\u044F\u043B\u0441\u044F \u2014 \u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u044E \u0434\u0435\u043C\u043E\u043D\u0430 \u0432 \u043F\u0440\u0435\u0436\u043D\u0435\u0435 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\u2026"
|
|
9049
|
+
);
|
|
9050
|
+
if (await d.start()) return;
|
|
9051
|
+
d.err("\u0434\u0435\u043C\u043E\u043D \u043E\u0431\u0440\u0430\u0442\u043D\u043E \u041D\u0415 \u043F\u043E\u0434\u043D\u044F\u043B\u0441\u044F (\u043F\u0440\u0438\u0447\u0438\u043D\u0430 \u0432\u044B\u0448\u0435) \u2014 \u0440\u043E\u0439 \u0441\u0442\u043E\u0438\u0442. \u041F\u043E\u0434\u043D\u0438\u043C\u0438 \u0432\u0440\u0443\u0447\u043D\u0443\u044E: swarm start");
|
|
9052
|
+
}
|
|
9053
|
+
function isPortFree(port, host = "127.0.0.1") {
|
|
9054
|
+
return new Promise((resolve4) => {
|
|
9055
|
+
const probe = createServer();
|
|
9056
|
+
probe.once("error", () => resolve4(false));
|
|
9057
|
+
probe.listen(port, host, () => probe.close(() => resolve4(true)));
|
|
9058
|
+
});
|
|
9059
|
+
}
|
|
8996
9060
|
async function chooseWorkspace(d) {
|
|
8997
9061
|
if (d.list.length === 0) {
|
|
8998
9062
|
d.out("\u043D\u0435\u0442 \u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445 \u0432\u043E\u0440\u043A\u0441\u043F\u0435\u0439\u0441\u043E\u0432 (list_workspaces \u043F\u0443\u0441\u0442)");
|
|
@@ -9264,6 +9328,59 @@ function takeWorkspace(argv) {
|
|
|
9264
9328
|
return { workspace, rest: [...argv.slice(0, i), ...argv.slice(i + 2)] };
|
|
9265
9329
|
}
|
|
9266
9330
|
async function runLogin(db2, opts) {
|
|
9331
|
+
return withDaemonStopped(
|
|
9332
|
+
{
|
|
9333
|
+
status: async () => {
|
|
9334
|
+
const st = await daemonStatus2();
|
|
9335
|
+
return st ? { live: st.live } : null;
|
|
9336
|
+
},
|
|
9337
|
+
stop: stopDaemonForLogin,
|
|
9338
|
+
portFree: () => isPortFree(WEB_PORT),
|
|
9339
|
+
// Аргументы не передаём намеренно: пути к репозиториям демон помнит с прошлого
|
|
9340
|
+
// запуска (TASWM-335), а `swarm login` их и не знает — он про вход, не про репо.
|
|
9341
|
+
// А вот ОКРУЖЕНИЕ поднятого обратно демона — наше: если `swarm login` зовут из
|
|
9342
|
+
// шелла без SWARM_BACKEND, рой вернётся в sqlite-режиме, то есть слепым к
|
|
9343
|
+
// воркспейсу. В опубликованном пакете дефолт уже client (SWARM_DIST_BUILD) —
|
|
9344
|
+
// предупреждение достаётся монорепе, где это реальная разница.
|
|
9345
|
+
start: async () => {
|
|
9346
|
+
if (SWARM_BACKEND !== "client") {
|
|
9347
|
+
console.warn("SWARM_BACKEND=client \u043D\u0435 \u0437\u0430\u0434\u0430\u043D \u2014 \u043F\u043E\u0434\u043D\u0438\u043C\u0430\u044E \u0434\u0435\u043C\u043E\u043D\u0430 \u043E\u0431\u0440\u0430\u0442\u043D\u043E \u0432 \u043B\u043E\u043A\u0430\u043B\u044C\u043D\u043E\u043C sqlite-\u0440\u0435\u0436\u0438\u043C\u0435, \u0411\u0415\u0417 \u0441\u0432\u044F\u0437\u0438 \u0441 \u0432\u043E\u0440\u043A\u0441\u043F\u0435\u0439\u0441\u043E\u043C Taskless.");
|
|
9348
|
+
}
|
|
9349
|
+
return await runStartDetached([]) === 0;
|
|
9350
|
+
},
|
|
9351
|
+
out: (s) => console.log(s),
|
|
9352
|
+
err: (s) => console.error(s),
|
|
9353
|
+
port: WEB_PORT
|
|
9354
|
+
},
|
|
9355
|
+
() => runLoginFlow(db2, opts)
|
|
9356
|
+
);
|
|
9357
|
+
}
|
|
9358
|
+
async function stopDaemonForLogin() {
|
|
9359
|
+
const res = await daemonStop({ force: false, wait: true });
|
|
9360
|
+
if (!res) {
|
|
9361
|
+
const beat = readHeartbeat(HEARTBEAT_PATH);
|
|
9362
|
+
if (beat != null && Date.now() - beat < 6e4) {
|
|
9363
|
+
console.error(
|
|
9364
|
+
`\u0434\u0435\u043C\u043E\u043D \u043F\u043E\u0434\u0430\u0451\u0442 \u043F\u0443\u043B\u044C\u0441 (${HEARTBEAT_PATH}), \u043D\u043E \u043C\u043E\u0440\u0434\u0430 127.0.0.1:${WEB_PORT} \u043D\u0435 \u043E\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u2014 \u0441\u0430\u043C \u0441\u0435\u0431\u044F \u043F\u043E\u0433\u0430\u0441\u0438\u0442\u044C \u043E\u043D \u043D\u0435 \u043C\u043E\u0436\u0435\u0442. \u041F\u043E\u0445\u043E\u0436\u0435, \u043F\u0440\u043E\u0446\u0435\u0441\u0441 \u0437\u0430\u0432\u0438\u0441: \u043D\u0430\u0439\u0434\u0438 \u0435\u0433\u043E (ps) \u0438 \u043F\u043E\u0433\u0430\u0441\u0438 \u0441\u0438\u0433\u043D\u0430\u043B\u043E\u043C \u0432\u0440\u0443\u0447\u043D\u0443\u044E, \u043F\u043E\u0442\u043E\u043C \u043F\u043E\u0432\u0442\u043E\u0440\u0438 swarm login.`
|
|
9365
|
+
);
|
|
9366
|
+
return "failed";
|
|
9367
|
+
}
|
|
9368
|
+
return "stopped";
|
|
9369
|
+
}
|
|
9370
|
+
if (res.waiting) {
|
|
9371
|
+
console.log(`\u0436\u0434\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F \u0436\u0438\u0432\u044B\u0445 \u0441\u0435\u0441\u0441\u0438\u0439 (${res.sessions.length}): ${await liveSessionNames(res.sessions)} \u2014 \u043D\u043E\u0432\u0443\u044E \u0440\u0430\u0431\u043E\u0442\u0443 \u0440\u043E\u0439 \u0443\u0436\u0435 \u043D\u0435 \u0431\u0435\u0440\u0451\u0442`);
|
|
9372
|
+
console.log("\u043E\u0431\u043E\u0440\u0432\u0430\u0442\u044C \u0438\u0445 \u0438 \u0432\u043E\u0439\u0442\u0438 \u043F\u0440\u044F\u043C\u043E \u0441\u0435\u0439\u0447\u0430\u0441: swarm stop --force \u0432 \u0434\u0440\u0443\u0433\u043E\u043C \u0442\u0435\u0440\u043C\u0438\u043D\u0430\u043B\u0435");
|
|
9373
|
+
} else {
|
|
9374
|
+
console.log("\u0436\u0438\u0432\u044B\u0445 \u0441\u0435\u0441\u0441\u0438\u0439 \u043D\u0435 \u0431\u044B\u043B\u043E \u2014 \u0434\u0435\u043C\u043E\u043D \u043F\u043E\u0433\u0430\u0448\u0435\u043D");
|
|
9375
|
+
}
|
|
9376
|
+
const down = res.waiting ? await waitDaemonDown({ timeoutMs: 6 * 60 * 6e4 }) : await waitDaemonDown({ timeoutMs: 3e4, pollMs: 500 });
|
|
9377
|
+
if (down) return "stopped";
|
|
9378
|
+
console.error(
|
|
9379
|
+
res.waiting ? "\u0436\u0434\u0443 \u0431\u043E\u043B\u044C\u0448\u0435 6 \u0447\u0430\u0441\u043E\u0432 \u2014 \u0434\u0435\u043C\u043E\u043D \u0432\u0441\u0451 \u0435\u0449\u0451 \u0433\u0430\u0441\u043D\u0435\u0442. \u0412\u0445\u043E\u0434 \u043D\u0435 \u043D\u0430\u0447\u0438\u043D\u0430\u044E: \u043F\u043E\u0440\u0442 \u0437\u0430\u043D\u044F\u0442 \u0438\u043C (swarm status \u043F\u043E\u043A\u0430\u0436\u0435\u0442, \u043A\u0442\u043E \u0435\u0449\u0451 \u0436\u0438\u0432)." : "\u0434\u0435\u043C\u043E\u043D \u043F\u0440\u0438\u043D\u044F\u043B \u043A\u043E\u043C\u0430\u043D\u0434\u0443, \u043D\u043E \u0437\u0430 30\u0441 \u043D\u0435 \u0432\u044B\u0448\u0435\u043B \u2014 \u0432\u0445\u043E\u0434 \u043D\u0435 \u043D\u0430\u0447\u0438\u043D\u0430\u044E (\u043F\u043E\u0440\u0442 \u0437\u0430\u043D\u044F\u0442 \u0438\u043C). \u041F\u0440\u043E\u0432\u0435\u0440\u044C: swarm status"
|
|
9380
|
+
);
|
|
9381
|
+
return "failed";
|
|
9382
|
+
}
|
|
9383
|
+
async function runLoginFlow(db2, opts) {
|
|
9267
9384
|
const web = startWeb({ db: db2 });
|
|
9268
9385
|
try {
|
|
9269
9386
|
let agent = loadAgentToken();
|
|
@@ -9351,7 +9468,7 @@ async function runLogin(db2, opts) {
|
|
|
9351
9468
|
console.log(
|
|
9352
9469
|
others.length ? `\u0440\u043E\u0439 \u0431\u0435\u0440\u0451\u0442 \u0440\u0430\u0431\u043E\u0442\u0443 \u0418\u0417 \u0412\u0421\u0415\u0425 \u0442\u0432\u043E\u0438\u0445 \u0432\u043E\u0440\u043A\u0441\u043F\u0435\u0439\u0441\u043E\u0432 (\u0435\u0449\u0451 ${others.length}: ${others.map((w) => w.slug).join(", ")}) \u2014 \u0432\u043E\u0440\u043A\u0441\u043F\u0435\u0439\u0441 \u043F\u0440\u0438\u0435\u0437\u0436\u0430\u0435\u0442 \u0441 \u043A\u0430\u0436\u0434\u044B\u043C \u043F\u0440\u043E\u0433\u043E\u043D\u043E\u043C. \u0412\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043D\u0443\u0436\u0435\u043D \u0442\u043E\u043B\u044C\u043A\u043E \u0434\u043B\u044F \u0432\u044B\u0437\u043E\u0432\u043E\u0432 \u043D\u0435 \u043F\u0440\u043E \u043F\u0440\u043E\u0433\u043E\u043D.` : "\u044D\u0442\u043E \u0435\u0434\u0438\u043D\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439 \u0432\u043E\u0440\u043A\u0441\u043F\u0435\u0439\u0441 \u0442\u043E\u043A\u0435\u043D\u0430."
|
|
9353
9470
|
);
|
|
9354
|
-
console.log("\u0433\u043E\u0442\u043E\u0432\u043E
|
|
9471
|
+
console.log("\u0433\u043E\u0442\u043E\u0432\u043E \u2014 \u0432\u0445\u043E\u0434 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D.");
|
|
9355
9472
|
return 0;
|
|
9356
9473
|
} finally {
|
|
9357
9474
|
web.server.close();
|
|
@@ -9627,7 +9744,9 @@ function usage() {
|
|
|
9627
9744
|
swarm update \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C \u0440\u043E\u0439 \u0434\u043E \u043E\u043F\u0443\u0431\u043B\u0438\u043A\u043E\u0432\u0430\u043D\u043D\u043E\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 (\u0442\u0435\u043C \u0436\u0435 \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440\u043E\u043C,
|
|
9628
9745
|
\u043A\u0430\u043A\u0438\u043C \u043E\u043D \u043F\u043E\u0441\u0442\u0430\u0432\u043B\u0435\u043D)
|
|
9629
9746
|
swarm login [--workspace <slug|id>] [--no-open]
|
|
9630
|
-
\u0432\u043E\u0439\u0442\u0438 \u0432 Taskless \u0438 \u0432\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u043E\u0440\u043A\u0441\u043F\u0435\u0439\u0441
|
|
9747
|
+
\u0432\u043E\u0439\u0442\u0438 \u0432 Taskless \u0438 \u0432\u044B\u0431\u0440\u0430\u0442\u044C \u0432\u043E\u0440\u043A\u0441\u043F\u0435\u0439\u0441. \u0414\u0435\u043C\u043E\u043D\u0430 \u0433\u0430\u0441\u0438\u0442 \u0438 \u043F\u043E\u0434\u043D\u0438\u043C\u0430\u0435\u0442
|
|
9748
|
+
\u0441\u0430\u043C\u0430 (\u0436\u0438\u0432\u044B\u0435 \u0441\u0435\u0441\u0441\u0438\u0438 \u0434\u043E\u0438\u0433\u0440\u044B\u0432\u0430\u044E\u0442) \u2014 \u043F\u0435\u0440\u0435\u043B\u043E\u0433\u0438\u043D \u044D\u0442\u043E \u043E\u0434\u043D\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u0430,
|
|
9749
|
+
\u0431\u0435\u0437 stop/start \u0440\u0443\u043A\u0430\u043C\u0438
|
|
9631
9750
|
swarm start [--repo <path>] [--foreground]
|
|
9632
9751
|
\u043F\u043E\u0434\u043D\u044F\u0442\u044C \u0440\u043E\u0439 \u043D\u0430 \u044D\u0442\u043E\u0439 \u043C\u0430\u0448\u0438\u043D\u0435: \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u043E\u0447\u0435\u0440\u0435\u0434\u044C, \u0441\u043F\u0430\u0432\u043D\u0438\u0442 \u0438 \u0431\u0443\u0434\u0438\u0442 \u0434\u0440\u043E\u043D\u043E\u0432.
|
|
9633
9752
|
\u0420\u0435\u043F\u043E\u0437\u0438\u0442\u043E\u0440\u0438\u0438 \u043D\u0430\u0445\u043E\u0434\u0438\u0442 \u0441\u0430\u043C \u2014 \u043A\u043B\u043E\u043D\u044B \u043F\u0440\u043E\u0435\u043A\u0442\u043E\u0432 Taskless \u043D\u0430 \u044D\u0442\u043E\u0439 \u043C\u0430\u0448\u0438\u043D\u0435;
|