@jungjaehoon/mama-os 0.78.0 → 0.79.0
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 +311 -0
- package/README.md +38 -24
- package/db/migrations/002-model-runs-parent-index.sql +11 -0
- package/db/migrations/003-upkeep-settled.sql +15 -0
- package/dist/api/google-read-actions.d.ts +30 -0
- package/dist/api/google-read-actions.d.ts.map +1 -0
- package/dist/api/google-read-actions.js +256 -0
- package/dist/api/google-read-actions.js.map +1 -0
- package/dist/api/record-actions.d.ts.map +1 -1
- package/dist/api/record-actions.js +23 -5
- package/dist/api/record-actions.js.map +1 -1
- package/dist/api/report-handler.d.ts +0 -6
- package/dist/api/report-handler.d.ts.map +1 -1
- package/dist/api/report-handler.js +0 -54
- package/dist/api/report-handler.js.map +1 -1
- package/dist/api/security-events.d.ts +1 -1
- package/dist/api/security-events.d.ts.map +1 -1
- package/dist/api/security-events.js.map +1 -1
- package/dist/api/source-actions.d.ts +9 -0
- package/dist/api/source-actions.d.ts.map +1 -1
- package/dist/api/source-actions.js +49 -0
- package/dist/api/source-actions.js.map +1 -1
- package/dist/api/viewer-request-security.d.ts +14 -1
- package/dist/api/viewer-request-security.d.ts.map +1 -1
- package/dist/api/viewer-request-security.js +26 -3
- package/dist/api/viewer-request-security.js.map +1 -1
- package/dist/api/viewer-server.d.ts +7 -0
- package/dist/api/viewer-server.d.ts.map +1 -1
- package/dist/api/viewer-server.js +32 -0
- package/dist/api/viewer-server.js.map +1 -1
- package/dist/api/work-actions.d.ts +19 -2
- package/dist/api/work-actions.d.ts.map +1 -1
- package/dist/api/work-actions.js +15 -0
- package/dist/api/work-actions.js.map +1 -1
- package/dist/cli/commands/backup.d.ts +7 -6
- package/dist/cli/commands/backup.d.ts.map +1 -1
- package/dist/cli/commands/backup.js +44 -7
- package/dist/cli/commands/backup.js.map +1 -1
- package/dist/cli/commands/control.d.ts +22 -4
- package/dist/cli/commands/control.d.ts.map +1 -1
- package/dist/cli/commands/control.js +172 -11
- package/dist/cli/commands/control.js.map +1 -1
- package/dist/cli/commands/daemon.d.ts +13 -2
- package/dist/cli/commands/daemon.d.ts.map +1 -1
- package/dist/cli/commands/daemon.js +211 -5
- package/dist/cli/commands/daemon.js.map +1 -1
- package/dist/cli/commands/init-questions.d.ts +98 -0
- package/dist/cli/commands/init-questions.d.ts.map +1 -0
- package/dist/cli/commands/init-questions.js +420 -0
- package/dist/cli/commands/init-questions.js.map +1 -0
- package/dist/cli/commands/init-section.d.ts +13 -0
- package/dist/cli/commands/init-section.d.ts.map +1 -0
- package/dist/cli/commands/init-section.js +375 -0
- package/dist/cli/commands/init-section.js.map +1 -0
- package/dist/cli/commands/init.d.ts +56 -2
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +562 -351
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/node-move.d.ts +20 -0
- package/dist/cli/commands/node-move.d.ts.map +1 -0
- package/dist/cli/commands/node-move.js +289 -0
- package/dist/cli/commands/node-move.js.map +1 -0
- package/dist/cli/commands/register-owner.d.ts +3 -0
- package/dist/cli/commands/register-owner.d.ts.map +1 -1
- package/dist/cli/commands/register-owner.js +2 -0
- package/dist/cli/commands/register-owner.js.map +1 -1
- package/dist/cli/commands/restore.d.ts +2 -0
- package/dist/cli/commands/restore.d.ts.map +1 -1
- package/dist/cli/commands/restore.js +7 -0
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/service.d.ts +16 -0
- package/dist/cli/commands/service.d.ts.map +1 -1
- package/dist/cli/commands/service.js +36 -8
- package/dist/cli/commands/service.js.map +1 -1
- package/dist/cli/commands/tools.d.ts +1 -1
- package/dist/cli/commands/tools.d.ts.map +1 -1
- package/dist/cli/commands/tools.js +8 -3
- package/dist/cli/commands/tools.js.map +1 -1
- package/dist/cli/commands/uninstall.d.ts.map +1 -1
- package/dist/cli/commands/uninstall.js +78 -5
- package/dist/cli/commands/uninstall.js.map +1 -1
- package/dist/cli/commands/update.d.ts +59 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +948 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.js +8 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/launch-files.d.ts +36 -0
- package/dist/cli/launch-files.d.ts.map +1 -1
- package/dist/cli/launch-files.js +94 -1
- package/dist/cli/launch-files.js.map +1 -1
- package/dist/cli/prompt.d.ts +2 -1
- package/dist/cli/prompt.d.ts.map +1 -1
- package/dist/cli/prompt.js +5 -2
- package/dist/cli/prompt.js.map +1 -1
- package/dist/cli/runtime/backup.d.ts +17 -1
- package/dist/cli/runtime/backup.d.ts.map +1 -1
- package/dist/cli/runtime/backup.js +32 -4
- package/dist/cli/runtime/backup.js.map +1 -1
- package/dist/cli/runtime/daemon-control.d.ts +92 -7
- package/dist/cli/runtime/daemon-control.d.ts.map +1 -1
- package/dist/cli/runtime/daemon-control.js +183 -8
- package/dist/cli/runtime/daemon-control.js.map +1 -1
- package/dist/cli/runtime/default-roots.d.ts +27 -0
- package/dist/cli/runtime/default-roots.d.ts.map +1 -0
- package/dist/cli/runtime/default-roots.js +61 -0
- package/dist/cli/runtime/default-roots.js.map +1 -0
- package/dist/cli/runtime/diagnostics.d.ts +25 -0
- package/dist/cli/runtime/diagnostics.d.ts.map +1 -1
- package/dist/cli/runtime/diagnostics.js +249 -63
- package/dist/cli/runtime/diagnostics.js.map +1 -1
- package/dist/cli/runtime/init-state.d.ts +20 -0
- package/dist/cli/runtime/init-state.d.ts.map +1 -0
- package/dist/cli/runtime/init-state.js +51 -0
- package/dist/cli/runtime/init-state.js.map +1 -0
- package/dist/cli/runtime/install-kind.d.ts +54 -0
- package/dist/cli/runtime/install-kind.d.ts.map +1 -0
- package/dist/cli/runtime/install-kind.js +164 -0
- package/dist/cli/runtime/install-kind.js.map +1 -0
- package/dist/cli/runtime/node-move-journal.d.ts +44 -0
- package/dist/cli/runtime/node-move-journal.d.ts.map +1 -0
- package/dist/cli/runtime/node-move-journal.js +48 -0
- package/dist/cli/runtime/node-move-journal.js.map +1 -0
- package/dist/cli/runtime/release-check.d.ts +94 -0
- package/dist/cli/runtime/release-check.d.ts.map +1 -0
- package/dist/cli/runtime/release-check.js +316 -0
- package/dist/cli/runtime/release-check.js.map +1 -0
- package/dist/cli/runtime/setup-page.d.ts +57 -0
- package/dist/cli/runtime/setup-page.d.ts.map +1 -0
- package/dist/cli/runtime/setup-page.js +266 -0
- package/dist/cli/runtime/setup-page.js.map +1 -0
- package/dist/cli/runtime/source-tools.d.ts +60 -0
- package/dist/cli/runtime/source-tools.d.ts.map +1 -0
- package/dist/cli/runtime/source-tools.js +170 -0
- package/dist/cli/runtime/source-tools.js.map +1 -0
- package/dist/cli/runtime/telegram-pairing.d.ts +73 -0
- package/dist/cli/runtime/telegram-pairing.d.ts.map +1 -0
- package/dist/cli/runtime/telegram-pairing.js +184 -0
- package/dist/cli/runtime/telegram-pairing.js.map +1 -0
- package/dist/cli/runtime/update-journal.d.ts +135 -0
- package/dist/cli/runtime/update-journal.d.ts.map +1 -0
- package/dist/cli/runtime/update-journal.js +144 -0
- package/dist/cli/runtime/update-journal.js.map +1 -0
- package/dist/cli/runtime/update-progress.d.ts +95 -0
- package/dist/cli/runtime/update-progress.d.ts.map +1 -0
- package/dist/cli/runtime/update-progress.js +154 -0
- package/dist/cli/runtime/update-progress.js.map +1 -0
- package/dist/cli/runtime/update-request.d.ts +58 -0
- package/dist/cli/runtime/update-request.d.ts.map +1 -0
- package/dist/cli/runtime/update-request.js +172 -0
- package/dist/cli/runtime/update-request.js.map +1 -0
- package/dist/connectors/calendar/index.d.ts +5 -1
- package/dist/connectors/calendar/index.d.ts.map +1 -1
- package/dist/connectors/calendar/index.js +19 -28
- package/dist/connectors/calendar/index.js.map +1 -1
- package/dist/connectors/chatwork/index.d.ts.map +1 -1
- package/dist/connectors/chatwork/index.js +7 -3
- package/dist/connectors/chatwork/index.js.map +1 -1
- package/dist/connectors/config-loader.d.ts +5 -0
- package/dist/connectors/config-loader.d.ts.map +1 -1
- package/dist/connectors/config-loader.js +8 -0
- package/dist/connectors/config-loader.js.map +1 -1
- package/dist/connectors/discord/index.d.ts.map +1 -1
- package/dist/connectors/discord/index.js +4 -3
- package/dist/connectors/discord/index.js.map +1 -1
- package/dist/connectors/drive/index.d.ts.map +1 -1
- package/dist/connectors/drive/index.js +15 -13
- package/dist/connectors/drive/index.js.map +1 -1
- package/dist/connectors/framework/gws-utils.d.ts +62 -0
- package/dist/connectors/framework/gws-utils.d.ts.map +1 -1
- package/dist/connectors/framework/gws-utils.js +133 -3
- package/dist/connectors/framework/gws-utils.js.map +1 -1
- package/dist/connectors/framework/types.d.ts +24 -0
- package/dist/connectors/framework/types.d.ts.map +1 -1
- package/dist/connectors/framework/types.js +9 -0
- package/dist/connectors/framework/types.js.map +1 -1
- package/dist/connectors/gmail/index.d.ts.map +1 -1
- package/dist/connectors/gmail/index.js +14 -13
- package/dist/connectors/gmail/index.js.map +1 -1
- package/dist/connectors/index.d.ts +4 -4
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +4 -10
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/notion/index.d.ts.map +1 -1
- package/dist/connectors/notion/index.js +5 -3
- package/dist/connectors/notion/index.js.map +1 -1
- package/dist/connectors/sheets/index.d.ts.map +1 -1
- package/dist/connectors/sheets/index.js +17 -12
- package/dist/connectors/sheets/index.js.map +1 -1
- package/dist/connectors/slack/index.d.ts.map +1 -1
- package/dist/connectors/slack/index.js +9 -3
- package/dist/connectors/slack/index.js.map +1 -1
- package/dist/connectors/telegram/index.d.ts.map +1 -1
- package/dist/connectors/telegram/index.js +4 -3
- package/dist/connectors/telegram/index.js.map +1 -1
- package/dist/connectors/trello/index.d.ts +1 -1
- package/dist/connectors/trello/index.d.ts.map +1 -1
- package/dist/connectors/trello/index.js +10 -5
- package/dist/connectors/trello/index.js.map +1 -1
- package/dist/gateways/discord.d.ts +6 -0
- package/dist/gateways/discord.d.ts.map +1 -1
- package/dist/gateways/discord.js +38 -27
- package/dist/gateways/discord.js.map +1 -1
- package/dist/gateways/slack.d.ts +6 -0
- package/dist/gateways/slack.d.ts.map +1 -1
- package/dist/gateways/slack.js +38 -27
- package/dist/gateways/slack.js.map +1 -1
- package/dist/gateways/telegram-commands.d.ts +124 -0
- package/dist/gateways/telegram-commands.d.ts.map +1 -0
- package/dist/gateways/telegram-commands.js +131 -0
- package/dist/gateways/telegram-commands.js.map +1 -0
- package/dist/gateways/telegram.d.ts +20 -0
- package/dist/gateways/telegram.d.ts.map +1 -1
- package/dist/gateways/telegram.js +138 -34
- package/dist/gateways/telegram.js.map +1 -1
- package/dist/gateways/turn-contract.d.ts +11 -0
- package/dist/gateways/turn-contract.d.ts.map +1 -1
- package/dist/runtime/action-surface.d.ts +1 -1
- package/dist/runtime/action-surface.d.ts.map +1 -1
- package/dist/runtime/action-surface.js +10 -0
- package/dist/runtime/action-surface.js.map +1 -1
- package/dist/runtime/backend-security.d.ts +23 -2
- package/dist/runtime/backend-security.d.ts.map +1 -1
- package/dist/runtime/backend-security.js +50 -5
- package/dist/runtime/backend-security.js.map +1 -1
- package/dist/runtime/member-paths.d.ts +15 -7
- package/dist/runtime/member-paths.d.ts.map +1 -1
- package/dist/runtime/member-paths.js +64 -12
- package/dist/runtime/member-paths.js.map +1 -1
- package/dist/runtime/member-session.d.ts +4 -0
- package/dist/runtime/member-session.d.ts.map +1 -1
- package/dist/runtime/member-session.js +23 -2
- package/dist/runtime/member-session.js.map +1 -1
- package/dist/runtime/native-session.d.ts +2 -0
- package/dist/runtime/native-session.d.ts.map +1 -1
- package/dist/runtime/native-session.js +1 -0
- package/dist/runtime/native-session.js.map +1 -1
- package/dist/runtime/owner-runtime.d.ts +63 -1
- package/dist/runtime/owner-runtime.d.ts.map +1 -1
- package/dist/runtime/owner-runtime.js +180 -3
- package/dist/runtime/owner-runtime.js.map +1 -1
- package/dist/runtime/owner-system-prompt.d.ts.map +1 -1
- package/dist/runtime/owner-system-prompt.js +0 -1
- package/dist/runtime/owner-system-prompt.js.map +1 -1
- package/dist/runtime/principal-access.d.ts +2 -0
- package/dist/runtime/principal-access.d.ts.map +1 -1
- package/dist/runtime/principal-access.js +7 -0
- package/dist/runtime/principal-access.js.map +1 -1
- package/dist/runtime/principal-sessions.d.ts.map +1 -1
- package/dist/runtime/principal-sessions.js +8 -1
- package/dist/runtime/principal-sessions.js.map +1 -1
- package/dist/runtime/record-orders.d.ts.map +1 -1
- package/dist/runtime/record-orders.js +3 -29
- package/dist/runtime/record-orders.js.map +1 -1
- package/dist/runtime/report-scheduler.d.ts +9 -2
- package/dist/runtime/report-scheduler.d.ts.map +1 -1
- package/dist/runtime/report-scheduler.js +37 -10
- package/dist/runtime/report-scheduler.js.map +1 -1
- package/dist/runtime/stimulus-delivery.d.ts +3 -0
- package/dist/runtime/stimulus-delivery.d.ts.map +1 -1
- package/dist/runtime/stimulus-delivery.js +19 -3
- package/dist/runtime/stimulus-delivery.js.map +1 -1
- package/dist/runtime/tools-paths.d.ts +7 -0
- package/dist/runtime/tools-paths.d.ts.map +1 -1
- package/dist/runtime/tools-paths.js +11 -5
- package/dist/runtime/tools-paths.js.map +1 -1
- package/dist/runtime/upkeep-close.d.ts +17 -0
- package/dist/runtime/upkeep-close.d.ts.map +1 -0
- package/dist/runtime/upkeep-close.js +127 -0
- package/dist/runtime/upkeep-close.js.map +1 -0
- package/dist/runtime/upkeep-orders.d.ts +124 -0
- package/dist/runtime/upkeep-orders.d.ts.map +1 -0
- package/dist/runtime/upkeep-orders.js +310 -0
- package/dist/runtime/upkeep-orders.js.map +1 -0
- package/dist/runtime/upkeep-reconcile.d.ts +25 -0
- package/dist/runtime/upkeep-reconcile.d.ts.map +1 -0
- package/dist/runtime/upkeep-reconcile.js +231 -0
- package/dist/runtime/upkeep-reconcile.js.map +1 -0
- package/dist/runtime/upkeep-writeback.d.ts +22 -0
- package/dist/runtime/upkeep-writeback.d.ts.map +1 -0
- package/dist/runtime/upkeep-writeback.js +203 -0
- package/dist/runtime/upkeep-writeback.js.map +1 -0
- package/dist/utils/untrusted-content.d.ts.map +1 -1
- package/dist/utils/untrusted-content.js +8 -1
- package/dist/utils/untrusted-content.js.map +1 -1
- package/install/install.sh +457 -0
- package/install/node.json +9 -0
- package/package.json +3 -4
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.botName = botName;
|
|
4
|
+
exports.pairOwner = pairOwner;
|
|
5
|
+
exports.bindCommonGroup = bindCommonGroup;
|
|
6
|
+
exports.confirmUpdates = confirmUpdates;
|
|
7
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
|
+
const prompt_js_1 = require("../prompt.js");
|
|
9
|
+
/** At most this many people get a code in one window; anyone after that is ignored. */
|
|
10
|
+
const MAX_CODES = 10;
|
|
11
|
+
/** How long init waits for /bind before it stops and says how to continue. */
|
|
12
|
+
const BIND_WAIT_MS = 15 * 60_000;
|
|
13
|
+
/** A call whose network failure ends init with a sentence, not an unnamed error. */
|
|
14
|
+
async function request(options, method, params) {
|
|
15
|
+
try {
|
|
16
|
+
return await options.call(options.token, method, params);
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
const cause = error.cause?.code;
|
|
20
|
+
const name = error instanceof Error ? error.name : 'Error';
|
|
21
|
+
throw new prompt_js_1.CliInputError(`Could not reach Telegram (${typeof cause === 'string' ? cause : name}); check the network and run the install command again.`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** Each getUpdates waits up to five seconds for news; doctor's call gives up after eight. */
|
|
25
|
+
async function updates(options, offset, pollSeconds = 5) {
|
|
26
|
+
const reply = await request(options, 'getUpdates', {
|
|
27
|
+
offset: String(offset),
|
|
28
|
+
timeout: String(pollSeconds),
|
|
29
|
+
allowed_updates: JSON.stringify(['message']),
|
|
30
|
+
});
|
|
31
|
+
if (reply.ok === true)
|
|
32
|
+
return reply.result ?? [];
|
|
33
|
+
// Telegram lets one reader at a time take a bot's updates; init and a daemon would keep
|
|
34
|
+
// stopping each other.
|
|
35
|
+
if (reply.error_code === 409)
|
|
36
|
+
throw new prompt_js_1.CliInputError("Another program is reading this bot's messages (another MAMA install?). Use a bot only this install uses, then run the install command again.");
|
|
37
|
+
throw new prompt_js_1.CliInputError(`Telegram refused to hand over the bot's messages (${String(reply.error_code ?? 'no code')}).`);
|
|
38
|
+
}
|
|
39
|
+
/** The bot's @name, which the pairing instructions give. */
|
|
40
|
+
async function botName(options) {
|
|
41
|
+
const reply = await request(options, 'getMe', {});
|
|
42
|
+
const name = reply.result?.username;
|
|
43
|
+
if (reply.ok !== true || typeof name !== 'string')
|
|
44
|
+
throw new prompt_js_1.CliInputError('Telegram refused the bot token; copy it again from BotFather.');
|
|
45
|
+
return name;
|
|
46
|
+
}
|
|
47
|
+
async function send(options, chatId, text) {
|
|
48
|
+
const reply = await request(options, 'sendMessage', { chat_id: String(chatId), text });
|
|
49
|
+
return reply.ok === true;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Make the person setting up the first owner without a typed user ID: everyone who messages the
|
|
53
|
+
* bot privately while init waits gets a code, and the code `ask` returns names the owner. A code
|
|
54
|
+
* reaches only the chat it was sent to, so entering it proves that chat is this person's.
|
|
55
|
+
* Messages the bot held from before are dropped first: they were not sent to this setup, and an
|
|
56
|
+
* old /bind would otherwise name a group without a new word from the owner.
|
|
57
|
+
*/
|
|
58
|
+
async function pairOwner(options) {
|
|
59
|
+
// offset -1 returns only the newest held update and drops the rest; the next poll drops it too.
|
|
60
|
+
const held = await updates(options, -1, 0);
|
|
61
|
+
let offset = held.length > 0 ? held[held.length - 1].update_id + 1 : 0;
|
|
62
|
+
options.write(`Open Telegram and send @${options.botUsername} a new private message (one sent before now is dropped). It answers with a pairing code; enter it on the setup page.`);
|
|
63
|
+
const codes = new Map();
|
|
64
|
+
const senders = new Set();
|
|
65
|
+
// Group messages read while waiting for the code: a /bind sent early must not be lost.
|
|
66
|
+
const groupMessages = [];
|
|
67
|
+
let stopped = false;
|
|
68
|
+
let failure;
|
|
69
|
+
const pollingFailed = new AbortController();
|
|
70
|
+
const polling = (async () => {
|
|
71
|
+
while (!stopped) {
|
|
72
|
+
for (const update of await updates(options, offset)) {
|
|
73
|
+
offset = Math.max(offset, update.update_id + 1);
|
|
74
|
+
const message = update.message;
|
|
75
|
+
if (message?.chat?.type === 'group' || message?.chat?.type === 'supergroup')
|
|
76
|
+
groupMessages.push(update);
|
|
77
|
+
if (!message?.chat || message.chat.type !== 'private' || !message.from)
|
|
78
|
+
continue;
|
|
79
|
+
if (message.from.is_bot)
|
|
80
|
+
continue;
|
|
81
|
+
const sender = String(message.from.id);
|
|
82
|
+
if (senders.has(sender) || senders.size >= MAX_CODES)
|
|
83
|
+
continue;
|
|
84
|
+
let code;
|
|
85
|
+
do
|
|
86
|
+
code = String((0, node_crypto_1.randomInt)(100_000, 1_000_000));
|
|
87
|
+
while (codes.has(code));
|
|
88
|
+
senders.add(sender);
|
|
89
|
+
codes.set(code, sender);
|
|
90
|
+
const sent = await send(options, message.chat.id, `Your MAMA pairing code: ${code}\nEnter it on the setup page.`);
|
|
91
|
+
// A chat that refuses the bot (blocked it, account gone) cannot show its code; that sender
|
|
92
|
+
// may unblock the bot and write again.
|
|
93
|
+
if (!sent) {
|
|
94
|
+
senders.delete(sender);
|
|
95
|
+
codes.delete(code);
|
|
96
|
+
options.write('Telegram refused to deliver a pairing code to one chat. If it was yours, unblock the bot and send it another message.');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
})().catch((error) => {
|
|
101
|
+
failure = error;
|
|
102
|
+
pollingFailed.abort();
|
|
103
|
+
});
|
|
104
|
+
let ownerId;
|
|
105
|
+
try {
|
|
106
|
+
while (ownerId === undefined) {
|
|
107
|
+
let answer;
|
|
108
|
+
try {
|
|
109
|
+
answer = (await options.ask('Pairing code (from the bot)', pollingFailed.signal)).trim();
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
throw failure ?? error;
|
|
113
|
+
}
|
|
114
|
+
if (failure !== undefined)
|
|
115
|
+
throw failure;
|
|
116
|
+
ownerId = codes.get(answer);
|
|
117
|
+
if (ownerId === undefined)
|
|
118
|
+
options.write('That is not a code the bot sent; enter the code from its latest message.');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
stopped = true;
|
|
123
|
+
await polling;
|
|
124
|
+
}
|
|
125
|
+
// Read after polling stopped, so every update it handled is counted.
|
|
126
|
+
return { ownerId, offset, groupMessages };
|
|
127
|
+
}
|
|
128
|
+
/** A `/bind` command at the start of a message, unaddressed or addressed to this bot. */
|
|
129
|
+
function isBind(message, botUsername) {
|
|
130
|
+
const first = message.entities?.[0];
|
|
131
|
+
if (!message.text || first?.type !== 'bot_command' || first.offset !== 0)
|
|
132
|
+
return false;
|
|
133
|
+
const [name, addressee] = message.text.slice(1, first.length).split('@', 2);
|
|
134
|
+
return (name.toLowerCase() === 'bind' &&
|
|
135
|
+
(addressee === undefined || addressee.toLowerCase() === botUsername.toLowerCase()));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The common channel without a typed chat ID: the paired owner sends /bind in the group, and
|
|
139
|
+
* that group becomes it. Anyone else's message, or a /bind in a private chat, is ignored.
|
|
140
|
+
*/
|
|
141
|
+
async function bindCommonGroup(options) {
|
|
142
|
+
options.write(`Add @${options.botUsername} to the group for common work as an administrator (so it reads the group), then send /bind in that group.`);
|
|
143
|
+
const now = options.now ?? Date.now;
|
|
144
|
+
const deadline = now() + (options.waitMs ?? BIND_WAIT_MS);
|
|
145
|
+
let offset = options.offset;
|
|
146
|
+
let batch = options.earlier ?? [];
|
|
147
|
+
let toldAnonymous = false;
|
|
148
|
+
for (;;) {
|
|
149
|
+
for (const update of batch) {
|
|
150
|
+
offset = Math.max(offset, update.update_id + 1);
|
|
151
|
+
const message = update.message;
|
|
152
|
+
if (!message?.chat || !message.from)
|
|
153
|
+
continue;
|
|
154
|
+
if (message.chat.type !== 'group' && message.chat.type !== 'supergroup')
|
|
155
|
+
continue;
|
|
156
|
+
if (!isBind(message, options.botUsername))
|
|
157
|
+
continue;
|
|
158
|
+
// An anonymous administrator's message names the group, not the person, so it cannot count.
|
|
159
|
+
if (message.sender_chat !== undefined && !toldAnonymous) {
|
|
160
|
+
toldAnonymous = true;
|
|
161
|
+
options.write("A /bind came from an anonymous administrator, so it cannot count as yours. Turn off 'Remain anonymous' for yourself in the group's administrator settings and send /bind again.");
|
|
162
|
+
}
|
|
163
|
+
if (message.sender_chat !== undefined || String(message.from.id) !== options.ownerId)
|
|
164
|
+
continue;
|
|
165
|
+
// MAMA posts reports and notices there, so a group the bot cannot post in cannot be it.
|
|
166
|
+
if (await send(options, message.chat.id, "This group is now MAMA's common channel."))
|
|
167
|
+
return { chatId: String(message.chat.id), offset };
|
|
168
|
+
options.write('Telegram refused to let the bot post in that group. Let it post there, then send /bind again.');
|
|
169
|
+
}
|
|
170
|
+
if (now() >= deadline)
|
|
171
|
+
throw new prompt_js_1.CliInputError('No /bind arrived in the group; run the install command again to pair again.');
|
|
172
|
+
batch = await updates(options, offset);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Mark every update init read as handled, so the daemon's first poll does not take the pairing
|
|
177
|
+
* messages for an owner's questions.
|
|
178
|
+
*/
|
|
179
|
+
async function confirmUpdates(options) {
|
|
180
|
+
if (options.offset === 0)
|
|
181
|
+
return;
|
|
182
|
+
await updates(options, options.offset, 0);
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=telegram-pairing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-pairing.js","sourceRoot":"","sources":["../../../src/cli/runtime/telegram-pairing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { LockPaths } from './daemon-control.js';
|
|
2
|
+
/**
|
|
3
|
+
* `mama update`'s journal (docs/development/work/update.md, PR 3). The parent (the old CLI) writes
|
|
4
|
+
* it before it stops anything; the child (the new CLI) carries it on; a rollback, from either or
|
|
5
|
+
* from `mama update --rollback` after a killed updater, reads only it. Under runtime/, which the
|
|
6
|
+
* agents' native reads deny and a backup does not archive.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* prepare: the parent's steps 6-9; candidate: the new version boots with its claims held;
|
|
10
|
+
* committed: it runs at the new version and is never rolled back; rollback: the old version is
|
|
11
|
+
* being put back, and boots without a hold.
|
|
12
|
+
*/
|
|
13
|
+
export type UpdatePhase = 'prepare' | 'candidate' | 'committed' | 'rollback';
|
|
14
|
+
export interface UpdateJournal {
|
|
15
|
+
readonly format: 'mama-update';
|
|
16
|
+
phase: UpdatePhase;
|
|
17
|
+
/** The step last begun (the step table's numbers). */
|
|
18
|
+
step: number;
|
|
19
|
+
readonly from: string;
|
|
20
|
+
readonly to: string;
|
|
21
|
+
/** npm's prefix, from the package's path. */
|
|
22
|
+
readonly prefix: string;
|
|
23
|
+
/** What `npm config get registry` answered at step 2. */
|
|
24
|
+
readonly registry: string;
|
|
25
|
+
/** start.sh's pinned Node. */
|
|
26
|
+
readonly nodePath: string;
|
|
27
|
+
/** The MAMA command inside the package (`dist/cli/index.js`). */
|
|
28
|
+
readonly packageCli: string;
|
|
29
|
+
/** The previous CLI's absolute path once the old package is set aside at step 8. */
|
|
30
|
+
readonly previousCli: string;
|
|
31
|
+
/** Step 3's doctor failures, which step 11 compares with its own. */
|
|
32
|
+
readonly failuresBefore: readonly DoctorFailure[];
|
|
33
|
+
/**
|
|
34
|
+
* The snapshot's archive, named before step 7's backup starts so an update cut off mid-backup
|
|
35
|
+
* still finds what it left; it is a complete snapshot only once `schemaBefore` is set.
|
|
36
|
+
*/
|
|
37
|
+
snapshot: string | null;
|
|
38
|
+
/** That backup's staging folder, removed with the archive and its partial file. */
|
|
39
|
+
snapshotStaging: string | null;
|
|
40
|
+
/** Each migration source's stored version when the snapshot was taken. */
|
|
41
|
+
schemaBefore: readonly {
|
|
42
|
+
name: string;
|
|
43
|
+
stored: number;
|
|
44
|
+
}[] | null;
|
|
45
|
+
/** The newest mailbox input when the snapshot was taken; a restore drops those after it. */
|
|
46
|
+
lastInputId: number | null;
|
|
47
|
+
/** The installed toolkit's requirementsSha256 at step 7; null without a toolkit. */
|
|
48
|
+
toolkitBefore: string | null;
|
|
49
|
+
/** Step 12 ran `mama tools install`; a rollback runs the previous version's. */
|
|
50
|
+
toolkitInstalled: boolean;
|
|
51
|
+
/** start.sh and the service file, copied at step 7, which a rollback copies back. */
|
|
52
|
+
copies: readonly {
|
|
53
|
+
path: string;
|
|
54
|
+
copy: string;
|
|
55
|
+
}[];
|
|
56
|
+
/** The step that failed and its message, for the rollback's report. */
|
|
57
|
+
failure: {
|
|
58
|
+
step: number;
|
|
59
|
+
message: string;
|
|
60
|
+
} | null;
|
|
61
|
+
readonly startedAt: string;
|
|
62
|
+
}
|
|
63
|
+
/** A doctor failure as `mama update` compares them: its name and its stable code (or detail). */
|
|
64
|
+
export interface DoctorFailure {
|
|
65
|
+
readonly name: string;
|
|
66
|
+
readonly code: string;
|
|
67
|
+
}
|
|
68
|
+
export interface UpdatePaths {
|
|
69
|
+
readonly journal: string;
|
|
70
|
+
readonly hold: string;
|
|
71
|
+
/** Where step 7 copies start.sh and the service file. */
|
|
72
|
+
readonly copies: string;
|
|
73
|
+
/** `update.lock`: one updater per install, CLI or chat (PR 4 reads its holder). */
|
|
74
|
+
readonly lock: LockPaths;
|
|
75
|
+
/**
|
|
76
|
+
* Held by the continuation child (`--continue`, `--rollback --continue`) for its life. A parent
|
|
77
|
+
* killed while its child runs frees update.lock; this one tells `--rollback` the child still
|
|
78
|
+
* writes the journal.
|
|
79
|
+
*/
|
|
80
|
+
readonly continuation: LockPaths;
|
|
81
|
+
}
|
|
82
|
+
export declare function updatePaths(mamaRoot: string): UpdatePaths;
|
|
83
|
+
export declare const PACKAGE_SCOPE = "@jungjaehoon";
|
|
84
|
+
export declare const PACKAGE_BASENAME = "mama-os";
|
|
85
|
+
/** The staging prefix's name, in the scope folder: same filesystem, so the swap is two renames. */
|
|
86
|
+
export declare const STAGING_PREFIX = ".mama-update-";
|
|
87
|
+
/** The previous package, set aside beside it; npm skips dot folders. */
|
|
88
|
+
export declare const ASIDE_PREFIX = ".mama-os-";
|
|
89
|
+
export interface PackagePlaces {
|
|
90
|
+
/** `<prefix>/lib/node_modules/@jungjaehoon`. */
|
|
91
|
+
readonly scope: string;
|
|
92
|
+
/** Where the service's package lives: the old one before the swap, the new one after. */
|
|
93
|
+
readonly package: string;
|
|
94
|
+
/** The previous package once set aside. */
|
|
95
|
+
readonly aside: string;
|
|
96
|
+
/** The staging prefix npm installs `<to>` into. */
|
|
97
|
+
readonly staging: string;
|
|
98
|
+
/** The package npm installed under the staging prefix. */
|
|
99
|
+
readonly staged: string;
|
|
100
|
+
}
|
|
101
|
+
export declare function packagePlaces(prefix: string, from: string, to: string): PackagePlaces;
|
|
102
|
+
/** Staging prefixes left in a scope folder by an updater killed before its journal. */
|
|
103
|
+
export declare function leftoverStaging(scope: string): string[];
|
|
104
|
+
/** The open journal, or null when no update is unfinished. */
|
|
105
|
+
export declare function readUpdateJournal(path: string): UpdateJournal | null;
|
|
106
|
+
/** fsync a file or a folder (a folder's entries: a rename or a removal in it). */
|
|
107
|
+
export declare function syncFile(path: string): void;
|
|
108
|
+
/**
|
|
109
|
+
* Write the journal durably: a staged file, synced, renamed over the old one, and the folder
|
|
110
|
+
* synced, so a power cut leaves the old journal or the new one. `committed` must be on disk before
|
|
111
|
+
* the candidate is released (step 14).
|
|
112
|
+
*/
|
|
113
|
+
export declare function writeUpdateJournal(path: string, journal: UpdateJournal): void;
|
|
114
|
+
/** The durable write both journals use (the Node move's is read by install.sh, line by line). */
|
|
115
|
+
export declare function writeJournalFile(path: string, value: object): void;
|
|
116
|
+
/** Remove a journal, and sync its folder so the removal is on disk. */
|
|
117
|
+
export declare function removeUpdateJournal(path: string): void;
|
|
118
|
+
/** The snapshot's archive, its partial file and its backup's staging folder, whatever exists. */
|
|
119
|
+
export declare function removeSnapshot(journal: UpdateJournal): void;
|
|
120
|
+
/**
|
|
121
|
+
* What an unfinished update leaves for `mama status` and doctor to name: an open journal and the
|
|
122
|
+
* command that resolves it, or a hold file with no journal, which start.sh exits on.
|
|
123
|
+
*/
|
|
124
|
+
export declare function unfinishedUpdate(mamaRoot: string): {
|
|
125
|
+
journal: UpdateJournal;
|
|
126
|
+
command: string;
|
|
127
|
+
} | {
|
|
128
|
+
hold: string;
|
|
129
|
+
} | null;
|
|
130
|
+
/**
|
|
131
|
+
* The command that resolves an open journal, with absolute paths: the previous CLI where it is
|
|
132
|
+
* now (set aside after step 8, in place before it or once a rollback put it back).
|
|
133
|
+
*/
|
|
134
|
+
export declare function rollbackCommand(journal: UpdateJournal): string;
|
|
135
|
+
//# sourceMappingURL=update-journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-journal.d.ts","sourceRoot":"","sources":["../../../src/cli/runtime/update-journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ASIDE_PREFIX = exports.STAGING_PREFIX = exports.PACKAGE_BASENAME = exports.PACKAGE_SCOPE = void 0;
|
|
4
|
+
exports.updatePaths = updatePaths;
|
|
5
|
+
exports.packagePlaces = packagePlaces;
|
|
6
|
+
exports.leftoverStaging = leftoverStaging;
|
|
7
|
+
exports.readUpdateJournal = readUpdateJournal;
|
|
8
|
+
exports.syncFile = syncFile;
|
|
9
|
+
exports.writeUpdateJournal = writeUpdateJournal;
|
|
10
|
+
exports.writeJournalFile = writeJournalFile;
|
|
11
|
+
exports.removeUpdateJournal = removeUpdateJournal;
|
|
12
|
+
exports.removeSnapshot = removeSnapshot;
|
|
13
|
+
exports.unfinishedUpdate = unfinishedUpdate;
|
|
14
|
+
exports.rollbackCommand = rollbackCommand;
|
|
15
|
+
const node_fs_1 = require("node:fs");
|
|
16
|
+
const node_path_1 = require("node:path");
|
|
17
|
+
const secrets_js_1 = require("../secrets.js");
|
|
18
|
+
function updatePaths(mamaRoot) {
|
|
19
|
+
const runtime = (0, node_path_1.join)(mamaRoot, 'runtime');
|
|
20
|
+
return {
|
|
21
|
+
journal: (0, node_path_1.join)(runtime, 'update.json'),
|
|
22
|
+
// start.sh tests it relative to the MAMA root (UPDATE_HOLD_LINE).
|
|
23
|
+
hold: (0, node_path_1.join)(runtime, 'update.hold'),
|
|
24
|
+
copies: (0, node_path_1.join)(runtime, 'update'),
|
|
25
|
+
lock: {
|
|
26
|
+
lockPath: (0, node_path_1.join)(runtime, 'update.lock'),
|
|
27
|
+
holderPath: (0, node_path_1.join)(runtime, 'update.holder.json'),
|
|
28
|
+
},
|
|
29
|
+
continuation: {
|
|
30
|
+
lockPath: (0, node_path_1.join)(runtime, 'update.continue.lock'),
|
|
31
|
+
holderPath: (0, node_path_1.join)(runtime, 'update.continue.holder.json'),
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
exports.PACKAGE_SCOPE = '@jungjaehoon';
|
|
36
|
+
exports.PACKAGE_BASENAME = 'mama-os';
|
|
37
|
+
/** The staging prefix's name, in the scope folder: same filesystem, so the swap is two renames. */
|
|
38
|
+
exports.STAGING_PREFIX = '.mama-update-';
|
|
39
|
+
/** The previous package, set aside beside it; npm skips dot folders. */
|
|
40
|
+
exports.ASIDE_PREFIX = '.mama-os-';
|
|
41
|
+
function packagePlaces(prefix, from, to) {
|
|
42
|
+
const scope = (0, node_path_1.join)(prefix, 'lib', 'node_modules', exports.PACKAGE_SCOPE);
|
|
43
|
+
const staging = (0, node_path_1.join)(scope, `${exports.STAGING_PREFIX}${to}`);
|
|
44
|
+
return {
|
|
45
|
+
scope,
|
|
46
|
+
package: (0, node_path_1.join)(scope, exports.PACKAGE_BASENAME),
|
|
47
|
+
aside: (0, node_path_1.join)(scope, `${exports.ASIDE_PREFIX}${from}`),
|
|
48
|
+
staging,
|
|
49
|
+
staged: (0, node_path_1.join)(staging, 'lib', 'node_modules', exports.PACKAGE_SCOPE, exports.PACKAGE_BASENAME),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/** Staging prefixes left in a scope folder by an updater killed before its journal. */
|
|
53
|
+
function leftoverStaging(scope) {
|
|
54
|
+
if (!(0, node_fs_1.existsSync)(scope))
|
|
55
|
+
return [];
|
|
56
|
+
return (0, node_fs_1.readdirSync)(scope)
|
|
57
|
+
.filter((name) => name.startsWith(exports.STAGING_PREFIX))
|
|
58
|
+
.map((name) => (0, node_path_1.join)(scope, name));
|
|
59
|
+
}
|
|
60
|
+
const PHASES = new Set(['prepare', 'candidate', 'committed', 'rollback']);
|
|
61
|
+
/** The open journal, or null when no update is unfinished. */
|
|
62
|
+
function readUpdateJournal(path) {
|
|
63
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
64
|
+
return null;
|
|
65
|
+
const value = JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
|
|
66
|
+
if (value === null ||
|
|
67
|
+
typeof value !== 'object' ||
|
|
68
|
+
value.format !== 'mama-update' ||
|
|
69
|
+
!PHASES.has(String(value.phase)) ||
|
|
70
|
+
typeof value.step !== 'number' ||
|
|
71
|
+
typeof value.from !== 'string' ||
|
|
72
|
+
typeof value.to !== 'string' ||
|
|
73
|
+
typeof value.prefix !== 'string' ||
|
|
74
|
+
typeof value.nodePath !== 'string' ||
|
|
75
|
+
typeof value.previousCli !== 'string' ||
|
|
76
|
+
typeof value.packageCli !== 'string') {
|
|
77
|
+
throw new Error(`${path} is not a journal mama update wrote`);
|
|
78
|
+
}
|
|
79
|
+
return value;
|
|
80
|
+
}
|
|
81
|
+
/** fsync a file or a folder (a folder's entries: a rename or a removal in it). */
|
|
82
|
+
function syncFile(path) {
|
|
83
|
+
const fd = (0, node_fs_1.openSync)(path, 'r');
|
|
84
|
+
try {
|
|
85
|
+
(0, node_fs_1.fsyncSync)(fd);
|
|
86
|
+
}
|
|
87
|
+
finally {
|
|
88
|
+
(0, node_fs_1.closeSync)(fd);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Write the journal durably: a staged file, synced, renamed over the old one, and the folder
|
|
93
|
+
* synced, so a power cut leaves the old journal or the new one. `committed` must be on disk before
|
|
94
|
+
* the candidate is released (step 14).
|
|
95
|
+
*/
|
|
96
|
+
function writeUpdateJournal(path, journal) {
|
|
97
|
+
writeJournalFile(path, journal);
|
|
98
|
+
}
|
|
99
|
+
/** The durable write both journals use (the Node move's is read by install.sh, line by line). */
|
|
100
|
+
function writeJournalFile(path, value) {
|
|
101
|
+
const staged = `${path}.${process.pid}.tmp`;
|
|
102
|
+
(0, node_fs_1.writeFileSync)(staged, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 });
|
|
103
|
+
syncFile(staged);
|
|
104
|
+
(0, node_fs_1.renameSync)(staged, path);
|
|
105
|
+
syncFile((0, node_path_1.dirname)(path));
|
|
106
|
+
}
|
|
107
|
+
/** Remove a journal, and sync its folder so the removal is on disk. */
|
|
108
|
+
function removeUpdateJournal(path) {
|
|
109
|
+
(0, node_fs_1.rmSync)(path, { force: true });
|
|
110
|
+
syncFile((0, node_path_1.dirname)(path));
|
|
111
|
+
}
|
|
112
|
+
/** The snapshot's archive, its partial file and its backup's staging folder, whatever exists. */
|
|
113
|
+
function removeSnapshot(journal) {
|
|
114
|
+
if (journal.snapshot !== null) {
|
|
115
|
+
(0, node_fs_1.rmSync)(journal.snapshot, { force: true });
|
|
116
|
+
(0, node_fs_1.rmSync)(`${journal.snapshot}.partial`, { force: true });
|
|
117
|
+
}
|
|
118
|
+
if (journal.snapshotStaging !== null) {
|
|
119
|
+
(0, node_fs_1.rmSync)(journal.snapshotStaging, { recursive: true, force: true });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* What an unfinished update leaves for `mama status` and doctor to name: an open journal and the
|
|
124
|
+
* command that resolves it, or a hold file with no journal, which start.sh exits on.
|
|
125
|
+
*/
|
|
126
|
+
function unfinishedUpdate(mamaRoot) {
|
|
127
|
+
const paths = updatePaths(mamaRoot);
|
|
128
|
+
const journal = readUpdateJournal(paths.journal);
|
|
129
|
+
if (journal !== null)
|
|
130
|
+
return { journal, command: rollbackCommand(journal) };
|
|
131
|
+
return (0, node_fs_1.existsSync)(paths.hold) ? { hold: paths.hold } : null;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The command that resolves an open journal, with absolute paths: the previous CLI where it is
|
|
135
|
+
* now (set aside after step 8, in place before it or once a rollback put it back).
|
|
136
|
+
*/
|
|
137
|
+
function rollbackCommand(journal) {
|
|
138
|
+
const places = packagePlaces(journal.prefix, journal.from, journal.to);
|
|
139
|
+
const cli = (0, node_fs_1.existsSync)(places.aside)
|
|
140
|
+
? journal.previousCli
|
|
141
|
+
: (0, node_path_1.join)(places.package, journal.packageCli);
|
|
142
|
+
return `${(0, secrets_js_1.shellQuote)(journal.nodePath)} ${(0, secrets_js_1.shellQuote)(cli)} update --rollback`;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=update-journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-journal.js","sourceRoot":"","sources":["../../../src/cli/runtime/update-journal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { defaultTelegramCall } from './diagnostics.js';
|
|
2
|
+
export type UpdateProgress = {
|
|
3
|
+
readonly kind: 'plan';
|
|
4
|
+
readonly from: string;
|
|
5
|
+
readonly to: string;
|
|
6
|
+
} | {
|
|
7
|
+
readonly kind: 'current';
|
|
8
|
+
readonly version: string;
|
|
9
|
+
} | {
|
|
10
|
+
readonly kind: 'step';
|
|
11
|
+
readonly from: string;
|
|
12
|
+
readonly to: string;
|
|
13
|
+
readonly step: number;
|
|
14
|
+
}
|
|
15
|
+
/** A step of the new version failed; the rollback reports next. */
|
|
16
|
+
| {
|
|
17
|
+
readonly kind: 'failed';
|
|
18
|
+
readonly from: string;
|
|
19
|
+
readonly to: string;
|
|
20
|
+
readonly step: number;
|
|
21
|
+
readonly code: string | null;
|
|
22
|
+
}
|
|
23
|
+
/** The stop or the snapshot failed; nothing was swapped. */
|
|
24
|
+
| {
|
|
25
|
+
readonly kind: 'not_updated';
|
|
26
|
+
readonly from: string;
|
|
27
|
+
readonly to: string;
|
|
28
|
+
readonly step: number;
|
|
29
|
+
readonly code: string;
|
|
30
|
+
} | {
|
|
31
|
+
readonly kind: 'rolling_back';
|
|
32
|
+
readonly from: string;
|
|
33
|
+
readonly to: string;
|
|
34
|
+
} | {
|
|
35
|
+
readonly kind: 'rolled_back';
|
|
36
|
+
readonly from: string;
|
|
37
|
+
readonly to: string;
|
|
38
|
+
readonly step: number;
|
|
39
|
+
} | {
|
|
40
|
+
readonly kind: 'rollback_stopped';
|
|
41
|
+
readonly from: string;
|
|
42
|
+
readonly to: string;
|
|
43
|
+
}
|
|
44
|
+
/** `running`: the daemon answered the release; false when it is not running now. */
|
|
45
|
+
| {
|
|
46
|
+
readonly kind: 'updated';
|
|
47
|
+
readonly from: string;
|
|
48
|
+
readonly to: string;
|
|
49
|
+
readonly running: boolean;
|
|
50
|
+
}
|
|
51
|
+
/** The update ended on an error: a refusal before anything changed, or a step that threw. */
|
|
52
|
+
| {
|
|
53
|
+
readonly kind: 'error';
|
|
54
|
+
readonly code: string;
|
|
55
|
+
};
|
|
56
|
+
/** The step table's names (update.md, PR 3), for the chat. */
|
|
57
|
+
export declare const UPDATE_STEP_NAMES: Readonly<Record<number, string>>;
|
|
58
|
+
/** A code as the chat may see it: a token, never free text. */
|
|
59
|
+
export declare function progressCode(value: unknown): string | null;
|
|
60
|
+
export declare function progressText(event: UpdateProgress): string;
|
|
61
|
+
export interface ProgressSink {
|
|
62
|
+
send(event: UpdateProgress): void;
|
|
63
|
+
/**
|
|
64
|
+
* Wait until every event sent so far has gone out (or failed and been logged). Past
|
|
65
|
+
* PROGRESS_FLUSH_DEADLINE_MS, step messages not yet sent are dropped and counted in the log;
|
|
66
|
+
* the outcomes (updated, failed, rolled back, …) are still sent, each within its own timeout.
|
|
67
|
+
*/
|
|
68
|
+
flush(): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* One send's limit. The flushes before a child CLI and at the end run while MAMA is stopped, so
|
|
72
|
+
* a Bot API that does not answer must not hold the install down; Telegram answers in well under
|
|
73
|
+
* a second when it answers at all.
|
|
74
|
+
*/
|
|
75
|
+
export declare const PROGRESS_SEND_TIMEOUT_MS = 3000;
|
|
76
|
+
/**
|
|
77
|
+
* How long a flush waits for step messages: past it, the steps still queued are dropped, so a
|
|
78
|
+
* slow Bot API holds the stopped install for this plus the few outcome sends at most.
|
|
79
|
+
*/
|
|
80
|
+
export declare const PROGRESS_FLUSH_DEADLINE_MS = 5000;
|
|
81
|
+
export declare const NO_PROGRESS: ProgressSink;
|
|
82
|
+
export type TelegramCall = typeof defaultTelegramCall;
|
|
83
|
+
/**
|
|
84
|
+
* Progress to the /update's chat through the Bot API's sendMessage alone: the daemon may be
|
|
85
|
+
* stopped, and a getUpdates here would take its updates. The chat comes from
|
|
86
|
+
* runtime/update-request.json and the bot token alone from auth.env, as doctor reads it. A send
|
|
87
|
+
* that fails is logged (to update.log, the job's output) and the update goes on. Repeats of a step
|
|
88
|
+
* (the journal is saved more than once in a step) are sent once.
|
|
89
|
+
*/
|
|
90
|
+
export declare function telegramProgress(options: {
|
|
91
|
+
root: string;
|
|
92
|
+
log: (line: string) => void;
|
|
93
|
+
call?: TelegramCall;
|
|
94
|
+
}): ProgressSink;
|
|
95
|
+
//# sourceMappingURL=update-progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-progress.d.ts","sourceRoot":"","sources":["../../../src/cli/runtime/update-progress.ts"],"names":[],"mappings":"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"}
|