@craftsamo/telegram-tools 0.1.0 → 0.3.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/.antigravity-plugin/plugin.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -1
- package/README.md +69 -22
- package/dist/cli.js +961 -865
- package/dist/mcp.js +463 -351
- package/dist/opencode.js +531 -398
- package/package.json +1 -1
- package/plugin.yaml +7 -4
- package/src/hermes/telegram_tools_hermes/approval.py +18 -14
- package/src/hermes/telegram_tools_hermes/plugin.py +3 -3
- package/src/hermes/telegram_tools_hermes/project.py +6 -0
- package/src/hermes/telegram_tools_hermes/settings.py +61 -63
- package/src/hermes/telegram_tools_hermes/tools.py +10 -3
package/dist/cli.js
CHANGED
|
@@ -27,6 +27,21 @@ var PROJECT = {
|
|
|
27
27
|
toolsets: ["account", "chats", "sync", "files", "sends", "actions"],
|
|
28
28
|
/** The toolsets on when a setting names none. */
|
|
29
29
|
defaultToolsets: ["account", "chats", "sync", "sends"],
|
|
30
|
+
/** The package's own settings, which the tools themselves read: each snake_case name and its type, with bounds when it needs them. */
|
|
31
|
+
options: {
|
|
32
|
+
/** Where every account's state lives. */
|
|
33
|
+
state_dir: "path",
|
|
34
|
+
/** Where received files are saved. */
|
|
35
|
+
download_dir: "path",
|
|
36
|
+
/** The largest received file a call may download, in megabytes. */
|
|
37
|
+
download_max_mb: { type: "number", integer: true, min: 1, max: 2e3 },
|
|
38
|
+
/** The directories files may be sent from, besides the working directory. */
|
|
39
|
+
send_dirs: "paths",
|
|
40
|
+
/** Whether messages that disappear are kept; read by the sync service's commands. */
|
|
41
|
+
keep_disappearing: "boolean",
|
|
42
|
+
/** Whether channels are listed and their messages received; read by the sync service's commands. */
|
|
43
|
+
channels: "boolean"
|
|
44
|
+
},
|
|
30
45
|
/** The environment variables the tools read besides the settings, which Codex forwards to the server after them. */
|
|
31
46
|
toolVariables: []
|
|
32
47
|
};
|
|
@@ -5101,7 +5116,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
|
|
|
5101
5116
|
var NONE = 0;
|
|
5102
5117
|
var ASSUMED = 1;
|
|
5103
5118
|
var PROVEN = 2;
|
|
5104
|
-
function isRecursive(inst, stack,
|
|
5119
|
+
function isRecursive(inst, stack, resolve6) {
|
|
5105
5120
|
const cached2 = recursive.get(inst);
|
|
5106
5121
|
if (cached2 !== void 0)
|
|
5107
5122
|
return cached2 ? PROVEN : NONE;
|
|
@@ -5111,7 +5126,7 @@ function isRecursive(inst, stack, resolve8) {
|
|
|
5111
5126
|
let result = NONE;
|
|
5112
5127
|
const check2 = (child) => {
|
|
5113
5128
|
if (result !== PROVEN && child?._zod) {
|
|
5114
|
-
const answer = isRecursive(child, stack,
|
|
5129
|
+
const answer = isRecursive(child, stack, resolve6);
|
|
5115
5130
|
if (answer > result)
|
|
5116
5131
|
result = answer;
|
|
5117
5132
|
}
|
|
@@ -5122,7 +5137,7 @@ function isRecursive(inst, stack, resolve8) {
|
|
|
5122
5137
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
5123
5138
|
if (spread && !desc.enumerable)
|
|
5124
5139
|
continue;
|
|
5125
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
5140
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve6) : NONE;
|
|
5126
5141
|
if (child > answer)
|
|
5127
5142
|
answer = child;
|
|
5128
5143
|
}
|
|
@@ -5186,7 +5201,7 @@ function isRecursive(inst, stack, resolve8) {
|
|
|
5186
5201
|
break;
|
|
5187
5202
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
5188
5203
|
case "lazy": {
|
|
5189
|
-
const inner = def._cachedInner ?? (
|
|
5204
|
+
const inner = def._cachedInner ?? (resolve6 ? inst._zod.innerType : void 0);
|
|
5190
5205
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
5191
5206
|
break;
|
|
5192
5207
|
}
|
|
@@ -9384,8 +9399,8 @@ function ko_default() {
|
|
|
9384
9399
|
}
|
|
9385
9400
|
|
|
9386
9401
|
// node_modules/.pnpm/zod@4.6.7/node_modules/zod/v4/locales/lt.js
|
|
9387
|
-
var capitalizeFirstCharacter = (
|
|
9388
|
-
return
|
|
9402
|
+
var capitalizeFirstCharacter = (text2) => {
|
|
9403
|
+
return text2.charAt(0).toUpperCase() + text2.slice(1);
|
|
9389
9404
|
};
|
|
9390
9405
|
function getUnitTypeFromNumber(number4) {
|
|
9391
9406
|
const abs2 = Math.abs(number4);
|
|
@@ -19792,8 +19807,8 @@ function quoteBadLabel(value) {
|
|
|
19792
19807
|
const truncated = value.length > MAX_BAD_LABEL_PREVIEW ? `${value.slice(0, MAX_BAD_LABEL_PREVIEW)}\u2026` : value;
|
|
19793
19808
|
return JSON.stringify(truncated);
|
|
19794
19809
|
}
|
|
19795
|
-
function isLabel(
|
|
19796
|
-
return typeof
|
|
19810
|
+
function isLabel(text2) {
|
|
19811
|
+
return typeof text2 === "string" && LABEL_PATTERN.test(text2);
|
|
19797
19812
|
}
|
|
19798
19813
|
function checkLabel(label) {
|
|
19799
19814
|
if (!isLabel(label)) {
|
|
@@ -20229,6 +20244,7 @@ function acquireSyncLock(path) {
|
|
|
20229
20244
|
}
|
|
20230
20245
|
|
|
20231
20246
|
// src/core/time.ts
|
|
20247
|
+
var MS_PER_S = 1e3;
|
|
20232
20248
|
var MS_PER_MINUTE = 6e4;
|
|
20233
20249
|
var MINUTES_PER_HOUR = 60;
|
|
20234
20250
|
var localOffsetMinutes = (ms) => -new Date(ms).getTimezoneOffset();
|
|
@@ -20248,10 +20264,10 @@ var MILLISECOND_DIGITS = 3;
|
|
|
20248
20264
|
var MIN_YEAR = 1e3;
|
|
20249
20265
|
var MAX_HOUR = 23;
|
|
20250
20266
|
var MAX_MINUTE = 59;
|
|
20251
|
-
function badTime(
|
|
20267
|
+
function badTime(text2, name) {
|
|
20252
20268
|
return new ToolError(
|
|
20253
20269
|
"invalid_argument",
|
|
20254
|
-
`${name} is not a time: ${JSON.stringify(
|
|
20270
|
+
`${name} is not a time: ${JSON.stringify(text2)}. Use RFC 3339 with an offset (2026-11-07T14:03:12+09:00), or a date or time without one (2026-11-07, 2026-11-07T14:03), which reads as local time.`
|
|
20255
20271
|
);
|
|
20256
20272
|
}
|
|
20257
20273
|
function isCalendarDay(year, month, day) {
|
|
@@ -20259,21 +20275,21 @@ function isCalendarDay(year, month, day) {
|
|
|
20259
20275
|
date5.setUTCFullYear(year, month - 1, day);
|
|
20260
20276
|
return date5.getUTCFullYear() === year && date5.getUTCMonth() === month - 1 && date5.getUTCDate() === day;
|
|
20261
20277
|
}
|
|
20262
|
-
function parseTimeArgument(
|
|
20263
|
-
const match = TIME_PATTERN.exec(
|
|
20264
|
-
if (!match) throw badTime(
|
|
20278
|
+
function parseTimeArgument(text2, name) {
|
|
20279
|
+
const match = TIME_PATTERN.exec(text2.trim());
|
|
20280
|
+
if (!match) throw badTime(text2, name);
|
|
20265
20281
|
const [, year, month, day, hour = "0", minute = "0", second = "0", fraction = "", zulu, sign, offsetHour, offsetMin] = match;
|
|
20266
20282
|
const [y, mon, d, h2, mi, s] = [year, month, day, hour, minute, second].map(Number);
|
|
20267
20283
|
const ms = Number(fraction.padEnd(MILLISECOND_DIGITS, "0").slice(0, MILLISECOND_DIGITS));
|
|
20268
20284
|
if (y < MIN_YEAR || !isCalendarDay(y, mon, d) || h2 > MAX_HOUR || mi > MAX_MINUTE || s > MAX_MINUTE) {
|
|
20269
|
-
throw badTime(
|
|
20285
|
+
throw badTime(text2, name);
|
|
20270
20286
|
}
|
|
20271
20287
|
if (sign === void 0 && zulu === void 0) return new Date(y, mon - 1, d, h2, mi, s, ms).getTime();
|
|
20272
20288
|
const wall = Date.UTC(y, mon - 1, d, h2, mi, s, ms);
|
|
20273
20289
|
if (zulu) return wall;
|
|
20274
20290
|
const offsetH = Number(offsetHour);
|
|
20275
20291
|
const offsetM = Number(offsetMin);
|
|
20276
|
-
if (offsetH > MAX_HOUR || offsetM > MAX_MINUTE) throw badTime(
|
|
20292
|
+
if (offsetH > MAX_HOUR || offsetM > MAX_MINUTE) throw badTime(text2, name);
|
|
20277
20293
|
const offset = (offsetH * MINUTES_PER_HOUR + offsetM) * MS_PER_MINUTE;
|
|
20278
20294
|
return sign === "-" ? wall + offset : wall - offset;
|
|
20279
20295
|
}
|
|
@@ -20622,23 +20638,23 @@ function encodeCursor(value) {
|
|
|
20622
20638
|
function notACursor(name) {
|
|
20623
20639
|
return new ToolError("invalid_argument", `${name} is not a cursor this tool returned.`);
|
|
20624
20640
|
}
|
|
20625
|
-
function decodeCursor(
|
|
20626
|
-
const bytes2 = Buffer3.from(
|
|
20627
|
-
if (bytes2.toString("base64url") !==
|
|
20641
|
+
function decodeCursor(text2, name) {
|
|
20642
|
+
const bytes2 = Buffer3.from(text2, "base64url");
|
|
20643
|
+
if (bytes2.toString("base64url") !== text2) throw notACursor(name);
|
|
20628
20644
|
try {
|
|
20629
20645
|
return JSON.parse(bytes2.toString("utf8"));
|
|
20630
20646
|
} catch {
|
|
20631
20647
|
throw notACursor(name);
|
|
20632
20648
|
}
|
|
20633
20649
|
}
|
|
20634
|
-
function readCursor(
|
|
20635
|
-
const parsed = schema.safeParse(decodeCursor(
|
|
20650
|
+
function readCursor(text2, name, schema) {
|
|
20651
|
+
const parsed = schema.safeParse(decodeCursor(text2, name));
|
|
20636
20652
|
if (!parsed.success) throw notACursor(name);
|
|
20637
20653
|
return parsed.data;
|
|
20638
20654
|
}
|
|
20639
20655
|
var HIGH_SURROGATE = /[\uD800-\uDBFF]$/;
|
|
20640
|
-
function cutText(
|
|
20641
|
-
return
|
|
20656
|
+
function cutText(text2, keep) {
|
|
20657
|
+
return text2.length <= keep ? text2 : text2.slice(0, keep).replace(HIGH_SURROGATE, "");
|
|
20642
20658
|
}
|
|
20643
20659
|
function jsonLength(value) {
|
|
20644
20660
|
return JSON.stringify(value).length;
|
|
@@ -20788,15 +20804,15 @@ var ERROR_CODES = {
|
|
|
20788
20804
|
function isErrorCode(value) {
|
|
20789
20805
|
return typeof value === "string" && Object.hasOwn(ERROR_CODES, value);
|
|
20790
20806
|
}
|
|
20791
|
-
function maskPhoneNumbers(
|
|
20792
|
-
return
|
|
20807
|
+
function maskPhoneNumbers(text2) {
|
|
20808
|
+
return text2.replace(PHONE_NUMBER, "[number]");
|
|
20793
20809
|
}
|
|
20794
20810
|
function cut(message2) {
|
|
20795
20811
|
return maskPhoneNumbers(message2).trim().slice(0, MAX_DETAIL_LENGTH);
|
|
20796
20812
|
}
|
|
20797
20813
|
function detail(message2) {
|
|
20798
|
-
const
|
|
20799
|
-
return
|
|
20814
|
+
const text2 = cut(message2);
|
|
20815
|
+
return text2 ? `: ${text2}` : "";
|
|
20800
20816
|
}
|
|
20801
20817
|
function afterWriteError(method, effect, reason) {
|
|
20802
20818
|
return effect === "write" ? new ToolError("uncertain", `${method} may have taken effect (${reason}). ${UNCERTAIN_ADVICE}`) : new ToolError("upstream_error", `${method} failed (${reason}).`);
|
|
@@ -20917,7 +20933,7 @@ function abortError(signal) {
|
|
|
20917
20933
|
}
|
|
20918
20934
|
function exec(argv, options) {
|
|
20919
20935
|
const { signal } = options;
|
|
20920
|
-
return new Promise((
|
|
20936
|
+
return new Promise((resolve6, reject) => {
|
|
20921
20937
|
if (signal?.aborted) {
|
|
20922
20938
|
reject(abortError(signal));
|
|
20923
20939
|
return;
|
|
@@ -20976,7 +20992,7 @@ function exec(argv, options) {
|
|
|
20976
20992
|
}
|
|
20977
20993
|
const finish2 = () => settle3(() => {
|
|
20978
20994
|
const { code, killedBy } = exitedWith ?? { code: null, killedBy: null };
|
|
20979
|
-
|
|
20995
|
+
resolve6({
|
|
20980
20996
|
code: code ?? -1,
|
|
20981
20997
|
stdout,
|
|
20982
20998
|
stderr,
|
|
@@ -21070,19 +21086,19 @@ var ServiceConnection = class _ServiceConnection {
|
|
|
21070
21086
|
socket.on("error", (error62) => {
|
|
21071
21087
|
this.endReason ??= `the connection to the service broke${error62.code ? ` (${error62.code})` : ""}`;
|
|
21072
21088
|
});
|
|
21073
|
-
this.closed = new Promise((
|
|
21089
|
+
this.closed = new Promise((resolve6) => {
|
|
21074
21090
|
socket.once("close", () => {
|
|
21075
21091
|
this.endReason ??= "the service closed the connection";
|
|
21076
21092
|
const lost = { lost: this.endReason };
|
|
21077
21093
|
for (const settle3 of [...this.pending.values()]) settle3(lost);
|
|
21078
|
-
|
|
21094
|
+
resolve6();
|
|
21079
21095
|
});
|
|
21080
21096
|
});
|
|
21081
21097
|
}
|
|
21082
21098
|
/** Connects to the service's socket; rejects as `upstream_error` when nothing is listening there. */
|
|
21083
21099
|
static connect(socketPath, options = {}) {
|
|
21084
21100
|
const { timeoutMs = DEFAULT_CONNECT_TIMEOUT_MS, signal, maxLineLength = DEFAULT_MAX_LINE_LENGTH } = options;
|
|
21085
|
-
return new Promise((
|
|
21101
|
+
return new Promise((resolve6, reject) => {
|
|
21086
21102
|
if (signal?.aborted) {
|
|
21087
21103
|
reject(abortError(signal));
|
|
21088
21104
|
return;
|
|
@@ -21104,7 +21120,7 @@ var ServiceConnection = class _ServiceConnection {
|
|
|
21104
21120
|
};
|
|
21105
21121
|
const onConnect = () => {
|
|
21106
21122
|
detach();
|
|
21107
|
-
|
|
21123
|
+
resolve6(new _ServiceConnection(socket, maxLineLength));
|
|
21108
21124
|
};
|
|
21109
21125
|
const onFailure = () => stop(new ToolError("upstream_error", NOT_RUNNING_MESSAGE));
|
|
21110
21126
|
const onAbort2 = () => stop(abortError(signal));
|
|
@@ -21127,7 +21143,7 @@ var ServiceConnection = class _ServiceConnection {
|
|
|
21127
21143
|
*/
|
|
21128
21144
|
call(method, params, options) {
|
|
21129
21145
|
const { effect, timeoutMs = DEFAULT_CALL_TIMEOUT_MS, signal } = options;
|
|
21130
|
-
return new Promise((
|
|
21146
|
+
return new Promise((resolve6, reject) => {
|
|
21131
21147
|
if (signal?.aborted) {
|
|
21132
21148
|
reject(abortError(signal));
|
|
21133
21149
|
return;
|
|
@@ -21156,7 +21172,7 @@ var ServiceConnection = class _ServiceConnection {
|
|
|
21156
21172
|
clearTimeout(timer);
|
|
21157
21173
|
signal?.removeEventListener("abort", onAbort2);
|
|
21158
21174
|
try {
|
|
21159
|
-
|
|
21175
|
+
resolve6(produce());
|
|
21160
21176
|
} catch (error62) {
|
|
21161
21177
|
reject(error62);
|
|
21162
21178
|
}
|
|
@@ -21229,7 +21245,6 @@ async function callService(socketPath, method, params, options) {
|
|
|
21229
21245
|
// src/core/chat/live.ts
|
|
21230
21246
|
var REFRESH_TIMEOUT_MS = 12e4;
|
|
21231
21247
|
var FETCH_TIMEOUT_MS = 18e4;
|
|
21232
|
-
var MS_PER_S = 1e3;
|
|
21233
21248
|
function requestHistory(socket, params, signal) {
|
|
21234
21249
|
return callService(socket, SERVICE_REQUESTS.history, params, { effect: "read", signal });
|
|
21235
21250
|
}
|
|
@@ -21357,113 +21372,6 @@ var messageEntry = external_exports.object({
|
|
|
21357
21372
|
private_note: external_exports.string().optional()
|
|
21358
21373
|
});
|
|
21359
21374
|
|
|
21360
|
-
// src/core/chat/schema.ts
|
|
21361
|
-
var METHODS = ["list", "view", "topics", "search", "around", "fetch"];
|
|
21362
|
-
var GENERAL_TOPIC2 = 1;
|
|
21363
|
-
var LIMITS = {
|
|
21364
|
-
list: { default: 30, max: 200 },
|
|
21365
|
-
view: { default: 50, max: 300 },
|
|
21366
|
-
topics: { default: 30, max: TOPICS_LIMIT },
|
|
21367
|
-
search: { default: 30, max: 200 }
|
|
21368
|
-
};
|
|
21369
|
-
var AROUND_COUNT = { default: 5, max: AROUND_LIMIT };
|
|
21370
|
-
var FETCH_PAGES = { default: 1, max: FETCH_PAGE_LIMIT };
|
|
21371
|
-
var accountArgument = external_exports.string().optional().describe("The account label; may be left out when only one account is logged in.");
|
|
21372
|
-
var input3 = external_exports.object({
|
|
21373
|
-
method: external_exports.enum(METHODS).describe(
|
|
21374
|
-
"`list` finds chats; `view` reads the newest messages of one chat between two times, oldest first; `topics` lists the topics of a forum chat; `search` finds messages in the mirror by words; `around` reads the messages around one; `fetch` adds older history of a mirrored chat to the mirror."
|
|
21375
|
-
),
|
|
21376
|
-
account: accountArgument,
|
|
21377
|
-
query: external_exports.string().optional().describe(
|
|
21378
|
-
"list: only chats whose name or username holds this text; a leading @ is ignored. search (required): the words to look for, all of which a message must hold in its text, caption or file name, in any order. Both ignore case and letter width."
|
|
21379
|
-
),
|
|
21380
|
-
unread: external_exports.boolean().optional().describe("list: only chats with unread messages."),
|
|
21381
|
-
last: external_exports.boolean().optional().describe("list: add each chat's newest mirrored message as `last_message`."),
|
|
21382
|
-
refresh: external_exports.boolean().optional().describe(
|
|
21383
|
-
"list: first take the chat list from Telegram (needs the sync service), then read it, and report when in `refreshed_at`."
|
|
21384
|
-
),
|
|
21385
|
-
chat: external_exports.string().optional().describe(
|
|
21386
|
-
"view, topics, around, fetch (required) and search (optional, to search one chat): the chat id, from `list`, such as 123456789 or -1001234567890. A name, username or phone number is not a chat."
|
|
21387
|
-
),
|
|
21388
|
-
topic: external_exports.number().int().positive().optional().describe(
|
|
21389
|
-
`view, around: only messages of this topic of a forum chat (ids from \`topics\`); the General topic is ${GENERAL_TOPIC2}. Refused for a chat without topics.`
|
|
21390
|
-
),
|
|
21391
|
-
after: external_exports.string().optional().describe(
|
|
21392
|
-
"view, search: only messages after this time (exclusive): RFC 3339 with an offset, or a date or time without one, read as local time, such as 2026-11-07 or 2026-11-07T14:03."
|
|
21393
|
-
),
|
|
21394
|
-
before: external_exports.string().optional().describe("view, search: only messages before this time (exclusive); the same forms as `after`."),
|
|
21395
|
-
limit: external_exports.number().int().optional().describe(
|
|
21396
|
-
`How many to return. list: default ${LIMITS.list.default}, at most ${LIMITS.list.max}. view: default ${LIMITS.view.default}, at most ${LIMITS.view.max} (${HISTORY_LIMIT} for a chat read live). topics: default ${LIMITS.topics.default}, at most ${LIMITS.topics.max}. search: default ${LIMITS.search.default}, at most ${LIMITS.search.max}. A larger value is lowered to the most; a result may hold fewer to stay a size a model can read.`
|
|
21397
|
-
),
|
|
21398
|
-
cursor: external_exports.string().optional().describe("The `next` of the previous result, to continue where it stopped."),
|
|
21399
|
-
id: external_exports.number().int().positive().optional().describe("around (required): the id of the message to read around."),
|
|
21400
|
-
before_count: external_exports.number().int().optional().describe(
|
|
21401
|
-
`around: how many older messages to return, default ${AROUND_COUNT.default}, at most ${AROUND_COUNT.max}; 0 asks for none.`
|
|
21402
|
-
),
|
|
21403
|
-
after_count: external_exports.number().int().optional().describe(
|
|
21404
|
-
`around: how many newer messages to return, default ${AROUND_COUNT.default}, at most ${AROUND_COUNT.max}; 0 asks for none.`
|
|
21405
|
-
),
|
|
21406
|
-
pages: external_exports.number().int().optional().describe(
|
|
21407
|
-
`fetch: how many pages of ${FETCH_PAGE_SIZE} older messages to add, default ${FETCH_PAGES.default}, at most ${FETCH_PAGES.max}.`
|
|
21408
|
-
)
|
|
21409
|
-
});
|
|
21410
|
-
var nameCut = external_exports.literal(true).optional().describe("Set when the name was longer than the most a result carries and was cut.");
|
|
21411
|
-
var chatEntry2 = external_exports.object({
|
|
21412
|
-
id: external_exports.string().describe("The chat id: Telegram's signed id as text, such as `123456789` or `-1001234567890`."),
|
|
21413
|
-
kind: external_exports.enum(CHAT_KINDS).describe("`self` is Saved Messages."),
|
|
21414
|
-
name: external_exports.string().nullable().describe("The person's or chat's name; null when none is known."),
|
|
21415
|
-
name_cut: nameCut,
|
|
21416
|
-
username: external_exports.string().optional(),
|
|
21417
|
-
mirrored: external_exports.boolean().describe("Whether the mirror keeps this chat's messages."),
|
|
21418
|
-
unread: external_exports.number().int().describe("Incoming messages not read yet."),
|
|
21419
|
-
last_activity_at: localTimeSchema.nullable().describe("The latest message's time, in local time with offset; null when none is known."),
|
|
21420
|
-
forum: external_exports.literal(true).optional().describe("Set for a supergroup with topics."),
|
|
21421
|
-
archived: external_exports.literal(true).optional(),
|
|
21422
|
-
left: external_exports.literal(true).optional().describe("Set for a group or channel the user has left or been removed from."),
|
|
21423
|
-
can_send: external_exports.literal(false).optional().describe("Set when the user is known not to be able to write here."),
|
|
21424
|
-
auto_delete_seconds: external_exports.number().int().optional().describe("The chat's auto-delete period, when on."),
|
|
21425
|
-
last_message: messageEntry.nullable().optional().describe("With `last`: the newest mirrored message of the chat, or null when none is mirrored.")
|
|
21426
|
-
});
|
|
21427
|
-
var topicEntry = external_exports.object({
|
|
21428
|
-
id: external_exports.number().int().describe(`The topic id, to pass as \`topic\` to \`view\`; ${GENERAL_TOPIC2} is the General topic.`),
|
|
21429
|
-
title: external_exports.string().nullable().describe("The topic's title; null when none is known."),
|
|
21430
|
-
closed: external_exports.literal(true).optional().describe("Set for a topic that is closed."),
|
|
21431
|
-
pinned: external_exports.literal(true).optional().describe("Set for a topic that is pinned."),
|
|
21432
|
-
unread: external_exports.number().int().describe("Messages in it not read yet."),
|
|
21433
|
-
last_activity_at: localTimeSchema.nullable().describe("The newest message's time, in local time with offset; null when none is known.")
|
|
21434
|
-
});
|
|
21435
|
-
var output3 = external_exports.object({
|
|
21436
|
-
chats: external_exports.array(chatEntry2).optional().describe("list: the chats, newest activity first."),
|
|
21437
|
-
refreshed_at: localTimeSchema.optional().describe("list with `refresh`: when the chat list was taken from Telegram, in local time with offset."),
|
|
21438
|
-
chat: chatEntry2.optional().describe("view, topics, around, fetch: the chat read."),
|
|
21439
|
-
messages: external_exports.array(messageEntry).optional().describe("view, around: the messages, oldest first. search: the hits, newest first."),
|
|
21440
|
-
live: external_exports.literal(true).optional().describe(
|
|
21441
|
-
"view, around: set when the chat is not mirrored, so the messages were read from Telegram and stored nowhere."
|
|
21442
|
-
),
|
|
21443
|
-
topics: external_exports.array(topicEntry).optional().describe("topics: the topics, most recently active first."),
|
|
21444
|
-
anchor: external_exports.number().int().optional().describe("around: the id of the message read around, among `messages`."),
|
|
21445
|
-
trimmed_before: external_exports.number().int().optional().describe(
|
|
21446
|
-
"around: how many older messages were left out, farthest first, to keep the result a size that can be read."
|
|
21447
|
-
),
|
|
21448
|
-
trimmed_after: external_exports.number().int().optional().describe(
|
|
21449
|
-
"around: how many newer messages were left out, farthest first, to keep the result a size that can be read."
|
|
21450
|
-
),
|
|
21451
|
-
scanned_to: localTimeSchema.optional().describe(
|
|
21452
|
-
"search: set when the search stopped before the end of the history it covers: the time of the oldest message looked at, in local time with offset. `next` continues from there."
|
|
21453
|
-
),
|
|
21454
|
-
scope: external_exports.string().optional().describe("search: what the search covers and what it does not."),
|
|
21455
|
-
fetched: external_exports.object({
|
|
21456
|
-
added: external_exports.number().int().describe("How many messages the mirror gained."),
|
|
21457
|
-
pages: external_exports.number().int().describe("How many pages were read."),
|
|
21458
|
-
complete: external_exports.boolean().describe("Whether Telegram has nothing older for this chat."),
|
|
21459
|
-
oldest_at: localTimeSchema.nullable().describe(
|
|
21460
|
-
"The time of the oldest message the mirror now holds of this chat, in local time with offset; null when none."
|
|
21461
|
-
)
|
|
21462
|
-
}).optional().describe("fetch: what the history fetch stored."),
|
|
21463
|
-
next: external_exports.string().optional().describe("Pass back as `cursor` to continue; absent when there is no more."),
|
|
21464
|
-
note: external_exports.string().describe("Says that what the result carries is data written by other people.")
|
|
21465
|
-
});
|
|
21466
|
-
|
|
21467
21375
|
// src/core/chat/message-rows.ts
|
|
21468
21376
|
var MESSAGE_COLUMNS = "chat, id, topic, ts, from_me, sender, sender_name, kind, body, entities, media, action, reply, forward, grouped, reactions, edited, expires, view_once, self_destruct";
|
|
21469
21377
|
function liveMessages(now) {
|
|
@@ -21471,7 +21379,7 @@ function liveMessages(now) {
|
|
|
21471
21379
|
}
|
|
21472
21380
|
function inTopic(topic) {
|
|
21473
21381
|
return {
|
|
21474
|
-
condition: topic ===
|
|
21382
|
+
condition: topic === GENERAL_TOPIC ? "(topic IS NULL OR topic = ?)" : "topic = ?",
|
|
21475
21383
|
params: [topic]
|
|
21476
21384
|
};
|
|
21477
21385
|
}
|
|
@@ -21584,10 +21492,10 @@ function replyTo(parsed, related) {
|
|
|
21584
21492
|
if (reply.chat !== void 0) entry2.chat = reply.chat;
|
|
21585
21493
|
if (reply.topic !== void 0) entry2.topic = reply.topic;
|
|
21586
21494
|
if (reply.quote !== void 0) entry2.quote = reply.quote;
|
|
21587
|
-
const
|
|
21588
|
-
if (
|
|
21589
|
-
entry2.text = cutText(
|
|
21590
|
-
if (entry2.text.length <
|
|
21495
|
+
const text2 = repliedText(parsed, related)?.text;
|
|
21496
|
+
if (text2 !== void 0) {
|
|
21497
|
+
entry2.text = cutText(text2, REPLY_TEXT_LENGTH);
|
|
21498
|
+
if (entry2.text.length < text2.length) entry2.text_cut = true;
|
|
21591
21499
|
}
|
|
21592
21500
|
return entry2;
|
|
21593
21501
|
}
|
|
@@ -21656,25 +21564,25 @@ function texts(entry2) {
|
|
|
21656
21564
|
];
|
|
21657
21565
|
}
|
|
21658
21566
|
function messageTextLength(entry2) {
|
|
21659
|
-
return texts(entry2).reduce((total,
|
|
21567
|
+
return texts(entry2).reduce((total, text2) => total + text2.length, 0);
|
|
21660
21568
|
}
|
|
21661
21569
|
function cutMessage(entry2, keep) {
|
|
21662
21570
|
let room = keep;
|
|
21663
21571
|
let cut3 = false;
|
|
21664
|
-
const take = (
|
|
21665
|
-
const kept = cutText(
|
|
21666
|
-
room = Math.max(0, room -
|
|
21667
|
-
if (kept.length <
|
|
21572
|
+
const take = (text2) => {
|
|
21573
|
+
const kept = cutText(text2, room);
|
|
21574
|
+
room = Math.max(0, room - text2.length);
|
|
21575
|
+
if (kept.length < text2.length) cut3 = true;
|
|
21668
21576
|
return kept;
|
|
21669
21577
|
};
|
|
21670
21578
|
const cutEntry = { ...entry2 };
|
|
21671
21579
|
if (entry2.text !== void 0) cutEntry.text = take(entry2.text);
|
|
21672
21580
|
if (entry2.reply_to) {
|
|
21673
|
-
const { quote, text } = entry2.reply_to;
|
|
21581
|
+
const { quote, text: text2 } = entry2.reply_to;
|
|
21674
21582
|
cutEntry.reply_to = {
|
|
21675
21583
|
...entry2.reply_to,
|
|
21676
21584
|
...quote === void 0 ? {} : { quote: take(quote) },
|
|
21677
|
-
...
|
|
21585
|
+
...text2 === void 0 ? {} : { text: take(text2) }
|
|
21678
21586
|
};
|
|
21679
21587
|
}
|
|
21680
21588
|
if (entry2.earlier_versions)
|
|
@@ -21696,6 +21604,112 @@ var cuttableMessage = {
|
|
|
21696
21604
|
drop: dropMetadata
|
|
21697
21605
|
};
|
|
21698
21606
|
|
|
21607
|
+
// src/core/chat/schema.ts
|
|
21608
|
+
var METHODS = ["list", "view", "topics", "search", "around", "fetch"];
|
|
21609
|
+
var LIMITS = {
|
|
21610
|
+
list: { default: 30, max: 200 },
|
|
21611
|
+
view: { default: 50, max: 300 },
|
|
21612
|
+
topics: { default: 30, max: TOPICS_LIMIT },
|
|
21613
|
+
search: { default: 30, max: 200 }
|
|
21614
|
+
};
|
|
21615
|
+
var AROUND_COUNT = { default: 5, max: AROUND_LIMIT };
|
|
21616
|
+
var FETCH_PAGES = { default: 1, max: FETCH_PAGE_LIMIT };
|
|
21617
|
+
var accountArgument = external_exports.string().optional().describe("The account label; may be left out when only one account is logged in.");
|
|
21618
|
+
var input3 = external_exports.object({
|
|
21619
|
+
method: external_exports.enum(METHODS).describe(
|
|
21620
|
+
"`list` finds chats; `view` reads the newest messages of one chat between two times, oldest first; `topics` lists the topics of a forum chat; `search` finds messages in the mirror by words; `around` reads the messages around one; `fetch` adds older history of a mirrored chat to the mirror."
|
|
21621
|
+
),
|
|
21622
|
+
account: accountArgument,
|
|
21623
|
+
query: external_exports.string().optional().describe(
|
|
21624
|
+
"list: only chats whose name or username holds this text; a leading @ is ignored. search (required): the words to look for, all of which a message must hold in its text, caption or file name, in any order. Both ignore case and letter width."
|
|
21625
|
+
),
|
|
21626
|
+
unread: external_exports.boolean().optional().describe("list: only chats with unread messages."),
|
|
21627
|
+
last: external_exports.boolean().optional().describe("list: add each chat's newest mirrored message as `last_message`."),
|
|
21628
|
+
refresh: external_exports.boolean().optional().describe(
|
|
21629
|
+
"list: first take the chat list from Telegram (needs the sync service), then read it, and report when in `refreshed_at`."
|
|
21630
|
+
),
|
|
21631
|
+
chat: external_exports.string().optional().describe(
|
|
21632
|
+
"view, topics, around, fetch (required) and search (optional, to search one chat): the chat id, from `list`, such as 123456789 or -1001234567890. A name, username or phone number is not a chat."
|
|
21633
|
+
),
|
|
21634
|
+
topic: external_exports.number().int().positive().optional().describe(
|
|
21635
|
+
`view, around: only messages of this topic of a forum chat (ids from \`topics\`); the General topic is ${GENERAL_TOPIC}. Refused for a chat without topics.`
|
|
21636
|
+
),
|
|
21637
|
+
after: external_exports.string().optional().describe(
|
|
21638
|
+
"view, search: only messages after this time (exclusive): RFC 3339 with an offset, or a date or time without one, read as local time, such as 2026-11-07 or 2026-11-07T14:03."
|
|
21639
|
+
),
|
|
21640
|
+
before: external_exports.string().optional().describe("view, search: only messages before this time (exclusive); the same forms as `after`."),
|
|
21641
|
+
limit: external_exports.number().int().optional().describe(
|
|
21642
|
+
`How many to return. list: default ${LIMITS.list.default}, at most ${LIMITS.list.max}. view: default ${LIMITS.view.default}, at most ${LIMITS.view.max} (${HISTORY_LIMIT} for a chat read live). topics: default ${LIMITS.topics.default}, at most ${LIMITS.topics.max}. search: default ${LIMITS.search.default}, at most ${LIMITS.search.max}. A larger value is lowered to the most; a result may hold fewer to stay a size a model can read.`
|
|
21643
|
+
),
|
|
21644
|
+
cursor: external_exports.string().optional().describe("The `next` of the previous result, to continue where it stopped."),
|
|
21645
|
+
id: external_exports.number().int().positive().optional().describe("around (required): the id of the message to read around."),
|
|
21646
|
+
before_count: external_exports.number().int().optional().describe(
|
|
21647
|
+
`around: how many older messages to return, default ${AROUND_COUNT.default}, at most ${AROUND_COUNT.max}; 0 asks for none.`
|
|
21648
|
+
),
|
|
21649
|
+
after_count: external_exports.number().int().optional().describe(
|
|
21650
|
+
`around: how many newer messages to return, default ${AROUND_COUNT.default}, at most ${AROUND_COUNT.max}; 0 asks for none.`
|
|
21651
|
+
),
|
|
21652
|
+
pages: external_exports.number().int().optional().describe(
|
|
21653
|
+
`fetch: how many pages of ${FETCH_PAGE_SIZE} older messages to add, default ${FETCH_PAGES.default}, at most ${FETCH_PAGES.max}.`
|
|
21654
|
+
)
|
|
21655
|
+
});
|
|
21656
|
+
var nameCut = external_exports.literal(true).optional().describe("Set when the name was longer than the most a result carries and was cut.");
|
|
21657
|
+
var chatEntry2 = external_exports.object({
|
|
21658
|
+
id: external_exports.string().describe("The chat id: Telegram's signed id as text, such as `123456789` or `-1001234567890`."),
|
|
21659
|
+
kind: external_exports.enum(CHAT_KINDS).describe("`self` is Saved Messages."),
|
|
21660
|
+
name: external_exports.string().nullable().describe("The person's or chat's name; null when none is known."),
|
|
21661
|
+
name_cut: nameCut,
|
|
21662
|
+
username: external_exports.string().optional(),
|
|
21663
|
+
mirrored: external_exports.boolean().describe("Whether the mirror keeps this chat's messages."),
|
|
21664
|
+
unread: external_exports.number().int().describe("Incoming messages not read yet."),
|
|
21665
|
+
last_activity_at: localTimeSchema.nullable().describe("The latest message's time, in local time with offset; null when none is known."),
|
|
21666
|
+
forum: external_exports.literal(true).optional().describe("Set for a supergroup with topics."),
|
|
21667
|
+
archived: external_exports.literal(true).optional(),
|
|
21668
|
+
left: external_exports.literal(true).optional().describe("Set for a group or channel the user has left or been removed from."),
|
|
21669
|
+
can_send: external_exports.literal(false).optional().describe("Set when the user is known not to be able to write here."),
|
|
21670
|
+
auto_delete_seconds: external_exports.number().int().optional().describe("The chat's auto-delete period, when on."),
|
|
21671
|
+
last_message: messageEntry.nullable().optional().describe("With `last`: the newest mirrored message of the chat, or null when none is mirrored.")
|
|
21672
|
+
});
|
|
21673
|
+
var topicEntry = external_exports.object({
|
|
21674
|
+
id: external_exports.number().int().describe(`The topic id, to pass as \`topic\` to \`view\`; ${GENERAL_TOPIC} is the General topic.`),
|
|
21675
|
+
title: external_exports.string().nullable().describe("The topic's title; null when none is known."),
|
|
21676
|
+
closed: external_exports.literal(true).optional().describe("Set for a topic that is closed."),
|
|
21677
|
+
pinned: external_exports.literal(true).optional().describe("Set for a topic that is pinned."),
|
|
21678
|
+
unread: external_exports.number().int().describe("Messages in it not read yet."),
|
|
21679
|
+
last_activity_at: localTimeSchema.nullable().describe("The newest message's time, in local time with offset; null when none is known.")
|
|
21680
|
+
});
|
|
21681
|
+
var output3 = external_exports.object({
|
|
21682
|
+
chats: external_exports.array(chatEntry2).optional().describe("list: the chats, newest activity first."),
|
|
21683
|
+
refreshed_at: localTimeSchema.optional().describe("list with `refresh`: when the chat list was taken from Telegram, in local time with offset."),
|
|
21684
|
+
chat: chatEntry2.optional().describe("view, topics, around, fetch: the chat read."),
|
|
21685
|
+
messages: external_exports.array(messageEntry).optional().describe("view, around: the messages, oldest first. search: the hits, newest first."),
|
|
21686
|
+
live: external_exports.literal(true).optional().describe(
|
|
21687
|
+
"view, around: set when the chat is not mirrored, so the messages were read from Telegram and stored nowhere."
|
|
21688
|
+
),
|
|
21689
|
+
topics: external_exports.array(topicEntry).optional().describe("topics: the topics, most recently active first."),
|
|
21690
|
+
anchor: external_exports.number().int().optional().describe("around: the id of the message read around, among `messages`."),
|
|
21691
|
+
trimmed_before: external_exports.number().int().optional().describe(
|
|
21692
|
+
"around: how many older messages were left out, farthest first, to keep the result a size that can be read."
|
|
21693
|
+
),
|
|
21694
|
+
trimmed_after: external_exports.number().int().optional().describe(
|
|
21695
|
+
"around: how many newer messages were left out, farthest first, to keep the result a size that can be read."
|
|
21696
|
+
),
|
|
21697
|
+
scanned_to: localTimeSchema.optional().describe(
|
|
21698
|
+
"search: set when the search stopped before the end of the history it covers: the time of the oldest message looked at, in local time with offset. `next` continues from there."
|
|
21699
|
+
),
|
|
21700
|
+
scope: external_exports.string().optional().describe("search: what the search covers and what it does not."),
|
|
21701
|
+
fetched: external_exports.object({
|
|
21702
|
+
added: external_exports.number().int().describe("How many messages the mirror gained."),
|
|
21703
|
+
pages: external_exports.number().int().describe("How many pages were read."),
|
|
21704
|
+
complete: external_exports.boolean().describe("Whether Telegram has nothing older for this chat."),
|
|
21705
|
+
oldest_at: localTimeSchema.nullable().describe(
|
|
21706
|
+
"The time of the oldest message the mirror now holds of this chat, in local time with offset; null when none."
|
|
21707
|
+
)
|
|
21708
|
+
}).optional().describe("fetch: what the history fetch stored."),
|
|
21709
|
+
next: external_exports.string().optional().describe("Pass back as `cursor` to continue; absent when there is no more."),
|
|
21710
|
+
note: external_exports.string().describe("Says that what the result carries is data written by other people.")
|
|
21711
|
+
});
|
|
21712
|
+
|
|
21699
21713
|
// src/core/chat/around.ts
|
|
21700
21714
|
var TRIMMED_RESERVE = 100;
|
|
21701
21715
|
var NO_MESSAGE = "No message with this id in this chat.";
|
|
@@ -21817,8 +21831,8 @@ function fetchResult(read, stored) {
|
|
|
21817
21831
|
}
|
|
21818
21832
|
|
|
21819
21833
|
// src/core/fold.ts
|
|
21820
|
-
function foldCase(
|
|
21821
|
-
return
|
|
21834
|
+
function foldCase(text2) {
|
|
21835
|
+
return text2.normalize("NFKC").toUpperCase().toLowerCase().replace(/ς/g, "\u03C3");
|
|
21822
21836
|
}
|
|
21823
21837
|
|
|
21824
21838
|
// src/core/chat/filter.ts
|
|
@@ -21898,7 +21912,7 @@ function listChats(mirror, args, now) {
|
|
|
21898
21912
|
return result;
|
|
21899
21913
|
}
|
|
21900
21914
|
|
|
21901
|
-
// src/core/
|
|
21915
|
+
// src/core/open.ts
|
|
21902
21916
|
async function pickPaths(ctx, account2) {
|
|
21903
21917
|
if (!ctx.stateDir) throw new ToolError("internal_error", "The entry point did not supply a state directory.");
|
|
21904
21918
|
return pickLabel(ctx.stateDir, account2);
|
|
@@ -21957,8 +21971,8 @@ function foldedFileName(media) {
|
|
|
21957
21971
|
return isRecord(info) && typeof info.name === "string" ? foldCase(info.name) : void 0;
|
|
21958
21972
|
}
|
|
21959
21973
|
function matchesAllWords(row, words2) {
|
|
21960
|
-
const
|
|
21961
|
-
const unmatched = words2.filter((word) => !
|
|
21974
|
+
const text2 = foldCase(row.body ?? "");
|
|
21975
|
+
const unmatched = words2.filter((word) => !text2.includes(word));
|
|
21962
21976
|
if (unmatched.length === 0) return true;
|
|
21963
21977
|
const name = row.media === null ? void 0 : foldedFileName(row.media);
|
|
21964
21978
|
return name !== void 0 && unmatched.every((word) => name.includes(word));
|
|
@@ -22318,6 +22332,56 @@ var CHAT_FACT_TRANSLATIONS = {
|
|
|
22318
22332
|
}
|
|
22319
22333
|
};
|
|
22320
22334
|
|
|
22335
|
+
// src/core/chat/media-facts.ts
|
|
22336
|
+
var MEDIA_KIND_WORDS = {
|
|
22337
|
+
photo: "Photo",
|
|
22338
|
+
document: "Document",
|
|
22339
|
+
audio: "Audio",
|
|
22340
|
+
voice: "Voice message",
|
|
22341
|
+
video: "Video",
|
|
22342
|
+
sticker: "Sticker",
|
|
22343
|
+
dice: "Dice",
|
|
22344
|
+
contact: "Contact",
|
|
22345
|
+
venue: "Venue",
|
|
22346
|
+
geo: "Location",
|
|
22347
|
+
geo_live: "Live location",
|
|
22348
|
+
game: "Game",
|
|
22349
|
+
invoice: "Invoice",
|
|
22350
|
+
webpage: "Link preview",
|
|
22351
|
+
poll: "Poll",
|
|
22352
|
+
todo: "Checklist",
|
|
22353
|
+
story: "Story",
|
|
22354
|
+
paid: "Paid media",
|
|
22355
|
+
unsupported: "Unsupported media"
|
|
22356
|
+
};
|
|
22357
|
+
function mediaKindValue(type3) {
|
|
22358
|
+
return Object.hasOwn(MEDIA_KIND_WORDS, type3) ? { text: MEDIA_KIND_WORDS[type3] } : type3;
|
|
22359
|
+
}
|
|
22360
|
+
var MEDIA_FACT_TRANSLATIONS = {
|
|
22361
|
+
ja: {
|
|
22362
|
+
Media: "\u30E1\u30C7\u30A3\u30A2",
|
|
22363
|
+
Photo: "\u5199\u771F",
|
|
22364
|
+
Document: "\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8",
|
|
22365
|
+
Audio: "\u97F3\u58F0",
|
|
22366
|
+
"Voice message": "\u30DC\u30A4\u30B9\u30E1\u30C3\u30BB\u30FC\u30B8",
|
|
22367
|
+
Video: "\u52D5\u753B",
|
|
22368
|
+
Sticker: "\u30B9\u30BF\u30F3\u30D7",
|
|
22369
|
+
Dice: "\u30B5\u30A4\u30B3\u30ED",
|
|
22370
|
+
Contact: "\u9023\u7D61\u5148",
|
|
22371
|
+
Venue: "\u5834\u6240",
|
|
22372
|
+
Location: "\u4F4D\u7F6E\u60C5\u5831",
|
|
22373
|
+
"Live location": "\u30E9\u30A4\u30D6\u4F4D\u7F6E\u60C5\u5831",
|
|
22374
|
+
Game: "\u30B2\u30FC\u30E0",
|
|
22375
|
+
Invoice: "\u8ACB\u6C42\u66F8",
|
|
22376
|
+
"Link preview": "\u30EA\u30F3\u30AF\u306E\u30D7\u30EC\u30D3\u30E5\u30FC",
|
|
22377
|
+
Poll: "\u6295\u7968",
|
|
22378
|
+
Checklist: "\u30C1\u30A7\u30C3\u30AF\u30EA\u30B9\u30C8",
|
|
22379
|
+
Story: "\u30B9\u30C8\u30FC\u30EA\u30FC",
|
|
22380
|
+
"Paid media": "\u6709\u6599\u30E1\u30C7\u30A3\u30A2",
|
|
22381
|
+
"Unsupported media": "\u672A\u5BFE\u5FDC\u306E\u30E1\u30C7\u30A3\u30A2"
|
|
22382
|
+
}
|
|
22383
|
+
};
|
|
22384
|
+
|
|
22321
22385
|
// src/core/facts.ts
|
|
22322
22386
|
function sizeFact(bytes2) {
|
|
22323
22387
|
return { label: "Size", value: { text: bytes2 === 1 ? "{bytes} byte" : "{bytes} bytes", values: { bytes: bytes2 } } };
|
|
@@ -22552,11 +22616,11 @@ var ANIMATED_STICKER = "an animated sticker (.tgs), which cannot be inspected";
|
|
|
22552
22616
|
function unreadableArchive(label) {
|
|
22553
22617
|
return `an archive that cannot be inspected (${label})`;
|
|
22554
22618
|
}
|
|
22555
|
-
function words(
|
|
22556
|
-
return
|
|
22619
|
+
function words(text2) {
|
|
22620
|
+
return text2.split(/\s+/).filter((word) => word !== "");
|
|
22557
22621
|
}
|
|
22558
|
-
function ascii(
|
|
22559
|
-
return Array.from(
|
|
22622
|
+
function ascii(text2) {
|
|
22623
|
+
return Array.from(text2, (character) => character.charCodeAt(0));
|
|
22560
22624
|
}
|
|
22561
22625
|
function at(offset, bytes2) {
|
|
22562
22626
|
return { offset, bytes: bytes2 };
|
|
@@ -22814,9 +22878,9 @@ function parseHeader(block) {
|
|
|
22814
22878
|
}
|
|
22815
22879
|
return { path, size: parseNumber(block.subarray(SIZE_START, SIZE_END)), type: block[TYPE_OFFSET] };
|
|
22816
22880
|
}
|
|
22817
|
-
function parseDecimal(
|
|
22818
|
-
if (!/^[0-9]{1,15}$/.test(
|
|
22819
|
-
return Number(
|
|
22881
|
+
function parseDecimal(text2) {
|
|
22882
|
+
if (!/^[0-9]{1,15}$/.test(text2)) return void 0;
|
|
22883
|
+
return Number(text2);
|
|
22820
22884
|
}
|
|
22821
22885
|
function parsePaxRecords(data, maxRecords = Infinity) {
|
|
22822
22886
|
const records = [];
|
|
@@ -23006,8 +23070,8 @@ var EXTENSIONS = {
|
|
|
23006
23070
|
};
|
|
23007
23071
|
var KIND_PATTERN = /^[a-z]{1,16}$/;
|
|
23008
23072
|
var UNKNOWN_KIND = "file";
|
|
23009
|
-
function byteLength(
|
|
23010
|
-
return Buffer5.byteLength(
|
|
23073
|
+
function byteLength(text2) {
|
|
23074
|
+
return Buffer5.byteLength(text2);
|
|
23011
23075
|
}
|
|
23012
23076
|
function extensionOf2(type3) {
|
|
23013
23077
|
return type3 == null ? "" : EXTENSIONS[type3.split(";")[0].trim().toLowerCase()] ?? "";
|
|
@@ -23323,8 +23387,8 @@ function fitListings(result) {
|
|
|
23323
23387
|
var MAX_NAME_CHARACTERS = 255;
|
|
23324
23388
|
var CUT_MARK = "\u2026";
|
|
23325
23389
|
var HIDDEN_CHARACTERS = /[\u0000-\u001F\u007F-\u009F\u00AD\u034F\u061C\u115F\u1160\u17B4\u17B5\u180B-\u180F\u200B-\u200F\u2028-\u202E\u2060-\u206F\u3164\uFE00-\uFE0D\uFEFF\uFFA0\uFFF9-\uFFFC\u{1D173}-\u{1D17A}\u{E0000}-\u{E007F}]/gu;
|
|
23326
|
-
function cleanName(
|
|
23327
|
-
const cleaned =
|
|
23390
|
+
function cleanName(text2) {
|
|
23391
|
+
const cleaned = text2.normalize("NFC").replace(HIDDEN_CHARACTERS, "?");
|
|
23328
23392
|
const characters = Array.from(cleaned);
|
|
23329
23393
|
if (characters.length <= MAX_NAME_CHARACTERS) return cleaned;
|
|
23330
23394
|
return characters.slice(0, MAX_NAME_CHARACTERS - CUT_MARK.length).join("") + CUT_MARK;
|
|
@@ -23497,9 +23561,9 @@ function decodeUtf8Lossy(bytes2) {
|
|
|
23497
23561
|
return LOSSY_UTF8.decode(bytes2);
|
|
23498
23562
|
}
|
|
23499
23563
|
function decodeCp437(bytes2) {
|
|
23500
|
-
let
|
|
23501
|
-
for (const byte of bytes2)
|
|
23502
|
-
return
|
|
23564
|
+
let text2 = "";
|
|
23565
|
+
for (const byte of bytes2) text2 += byte < ASCII_END ? String.fromCharCode(byte) : CP437_HIGH[byte - ASCII_END];
|
|
23566
|
+
return text2;
|
|
23503
23567
|
}
|
|
23504
23568
|
|
|
23505
23569
|
// src/core/archive/tar.ts
|
|
@@ -24319,14 +24383,6 @@ function namesOf(file2, id) {
|
|
|
24319
24383
|
const name = safeFileName(file2.name, { kind: file2.kind, id, type: file2.type });
|
|
24320
24384
|
return { name, shown: file2.name === null ? file2.kind : name };
|
|
24321
24385
|
}
|
|
24322
|
-
var FILE_KIND_WORDS = {
|
|
24323
|
-
photo: "Photo",
|
|
24324
|
-
document: "Document",
|
|
24325
|
-
audio: "Audio",
|
|
24326
|
-
voice: "Voice message",
|
|
24327
|
-
video: "Video",
|
|
24328
|
-
sticker: "Sticker"
|
|
24329
|
-
};
|
|
24330
24386
|
function saveHeadline(file2, chat) {
|
|
24331
24387
|
if (file2 !== void 0 && chat !== null) return { text: "About to save {file} from {chat}", values: { file: file2, chat } };
|
|
24332
24388
|
if (chat !== null) return { text: "About to save a file from {chat}", values: { chat } };
|
|
@@ -24334,9 +24390,8 @@ function saveHeadline(file2, chat) {
|
|
|
24334
24390
|
return void 0;
|
|
24335
24391
|
}
|
|
24336
24392
|
function fileFacts(media, unpack) {
|
|
24337
|
-
const kind = media && Object.hasOwn(FILE_KIND_WORDS, media.type) ? FILE_KIND_WORDS[media.type] : void 0;
|
|
24338
24393
|
return [
|
|
24339
|
-
...media ? [{ label: "File", value:
|
|
24394
|
+
...media ? [{ label: "File", value: mediaKindValue(media.type) }] : [],
|
|
24340
24395
|
...unpack ? [{ label: "Unpack", value: { text: "Yes" } }] : [],
|
|
24341
24396
|
...media?.size !== void 0 && Number.isSafeInteger(media.size) && media.size > 0 ? [sizeFact(media.size)] : []
|
|
24342
24397
|
];
|
|
@@ -24567,14 +24622,14 @@ function storedReactions(json2) {
|
|
|
24567
24622
|
function ownReaction(reactions) {
|
|
24568
24623
|
return reactions.find((reaction2) => reaction2.mine)?.emoji;
|
|
24569
24624
|
}
|
|
24570
|
-
function checkEditable({ kind, body, captioned },
|
|
24625
|
+
function checkEditable({ kind, body, captioned }, text2) {
|
|
24571
24626
|
if (kind === "service" || body === null && !captioned) {
|
|
24572
24627
|
throw new ToolError("invalid_argument", "This message has no text or caption to edit; nothing was edited.");
|
|
24573
24628
|
}
|
|
24574
|
-
if (body ===
|
|
24629
|
+
if (body === text2) {
|
|
24575
24630
|
throw new ToolError("invalid_argument", "The text is the same as the message's; nothing to edit.");
|
|
24576
24631
|
}
|
|
24577
|
-
if (captioned &&
|
|
24632
|
+
if (captioned && text2.length > CAPTION_MAX_UNITS) {
|
|
24578
24633
|
throw new ToolError(
|
|
24579
24634
|
"invalid_argument",
|
|
24580
24635
|
`A caption must be at most ${CAPTION_MAX_UNITS} characters; nothing was edited.`
|
|
@@ -24583,8 +24638,8 @@ function checkEditable({ kind, body, captioned }, text) {
|
|
|
24583
24638
|
}
|
|
24584
24639
|
|
|
24585
24640
|
// src/core/message/arguments.ts
|
|
24586
|
-
function checkedText(
|
|
24587
|
-
const trimmed =
|
|
24641
|
+
function checkedText(text2) {
|
|
24642
|
+
const trimmed = text2.trim();
|
|
24588
24643
|
if (trimmed === "") throw new ToolError("invalid_argument", "text is blank; give the text to send.");
|
|
24589
24644
|
if (trimmed.length > TEXT_MAX_UNITS) {
|
|
24590
24645
|
throw new ToolError(
|
|
@@ -24642,8 +24697,8 @@ var Window = class {
|
|
|
24642
24697
|
get tail() {
|
|
24643
24698
|
return this.#tail;
|
|
24644
24699
|
}
|
|
24645
|
-
sees(
|
|
24646
|
-
const all = this.#tail +
|
|
24700
|
+
sees(text2) {
|
|
24701
|
+
const all = this.#tail + text2;
|
|
24647
24702
|
this.#tail = all.slice(-TAIL_LENGTH);
|
|
24648
24703
|
return MARKER.test(all);
|
|
24649
24704
|
}
|
|
@@ -24653,13 +24708,13 @@ var PrivateKeyScan = class {
|
|
|
24653
24708
|
#withoutNuls;
|
|
24654
24709
|
/** Feeds the next chunk; whether a marker starts anywhere in the bytes so far. */
|
|
24655
24710
|
sees(chunk) {
|
|
24656
|
-
const
|
|
24711
|
+
const text2 = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength).toString("latin1");
|
|
24657
24712
|
const before = this.#plain.tail;
|
|
24658
|
-
const plain2 = this.#plain.sees(
|
|
24659
|
-
if (this.#withoutNuls === void 0 &&
|
|
24713
|
+
const plain2 = this.#plain.sees(text2);
|
|
24714
|
+
if (this.#withoutNuls === void 0 && text2.includes(NUL)) {
|
|
24660
24715
|
this.#withoutNuls = new Window(before);
|
|
24661
24716
|
}
|
|
24662
|
-
const stripped = this.#withoutNuls?.sees(
|
|
24717
|
+
const stripped = this.#withoutNuls?.sees(text2.replaceAll(NUL, "")) ?? false;
|
|
24663
24718
|
return plain2 || stripped;
|
|
24664
24719
|
}
|
|
24665
24720
|
};
|
|
@@ -24851,9 +24906,8 @@ async function checkArchive(path, format2, limits, signal) {
|
|
|
24851
24906
|
}
|
|
24852
24907
|
|
|
24853
24908
|
// src/core/outgoing/limits.ts
|
|
24854
|
-
var BYTES_PER_MB2 = 1024 * 1024;
|
|
24855
24909
|
var MAX_FILES = 10;
|
|
24856
|
-
var MAX_TOTAL_BYTES = 100 *
|
|
24910
|
+
var MAX_TOTAL_BYTES = 100 * BYTES_PER_MB;
|
|
24857
24911
|
|
|
24858
24912
|
// src/core/file/send/constants.ts
|
|
24859
24913
|
var SEND_FILES_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
@@ -25286,12 +25340,12 @@ var DUPLICATE_NOTE = "An earlier delivery of this same call had already gone out
|
|
|
25286
25340
|
var DUPLICATE_UNKNOWN_ID_NOTE = `${DUPLICATE_NOTE} Its id is not known yet; \`telegram_chat_read\` shows it once the service receives it.`;
|
|
25287
25341
|
|
|
25288
25342
|
// src/core/message/uncertain.ts
|
|
25289
|
-
function sentLike(paths, chat,
|
|
25343
|
+
function sentLike(paths, chat, text2, startedAt) {
|
|
25290
25344
|
const rows = readMirror(
|
|
25291
25345
|
paths,
|
|
25292
25346
|
(mirror) => mirror.prepare(
|
|
25293
25347
|
"SELECT id, ts FROM messages WHERE chat = ? AND from_me = 1 AND body = ? AND ts >= ? ORDER BY ts DESC, id DESC LIMIT ?"
|
|
25294
|
-
).all(chat,
|
|
25348
|
+
).all(chat, text2, startedAt - SENT_LOOKBACK_MS, MAX_SENT_LIKE)
|
|
25295
25349
|
);
|
|
25296
25350
|
return rows.map(({ id, ts }) => ({ id, time: formatLocalTime(ts) }));
|
|
25297
25351
|
}
|
|
@@ -25311,8 +25365,8 @@ function withFound(error62, find, describe3) {
|
|
|
25311
25365
|
details: { ...error62.details, sent_like_this: found }
|
|
25312
25366
|
});
|
|
25313
25367
|
}
|
|
25314
|
-
function withSentLike(error62, paths, chat,
|
|
25315
|
-
return withFound(error62, () => sentLike(paths, chat,
|
|
25368
|
+
function withSentLike(error62, paths, chat, text2, startedAt) {
|
|
25369
|
+
return withFound(error62, () => sentLike(paths, chat, text2, startedAt), sentence);
|
|
25316
25370
|
}
|
|
25317
25371
|
|
|
25318
25372
|
// src/core/file/send/uncertain.ts
|
|
@@ -25449,17 +25503,17 @@ var MAX_HEADLINE_VALUES = 8;
|
|
|
25449
25503
|
var MAX_HEADLINE_VALUE_LENGTH = 80;
|
|
25450
25504
|
var MAX_PINS = 16;
|
|
25451
25505
|
var HEADLINE_PLACEHOLDER = /\{([A-Za-z_][A-Za-z0-9_]*)\}/;
|
|
25452
|
-
function cut2(
|
|
25453
|
-
const points = Array.from(
|
|
25454
|
-
return points.length > limit ? `${points.slice(0, limit - 1).join("")}\u2026` :
|
|
25506
|
+
function cut2(text2, limit) {
|
|
25507
|
+
const points = Array.from(text2);
|
|
25508
|
+
return points.length > limit ? `${points.slice(0, limit - 1).join("")}\u2026` : text2;
|
|
25455
25509
|
}
|
|
25456
|
-
function omittedBy(
|
|
25457
|
-
const length = Array.from(
|
|
25510
|
+
function omittedBy(text2, limit) {
|
|
25511
|
+
const length = Array.from(text2).length;
|
|
25458
25512
|
return length > limit ? length - (limit - 1) : 0;
|
|
25459
25513
|
}
|
|
25460
|
-
function templatePlaceholders(
|
|
25514
|
+
function templatePlaceholders(text2) {
|
|
25461
25515
|
const names = /* @__PURE__ */ new Set();
|
|
25462
|
-
const parts =
|
|
25516
|
+
const parts = text2.split(HEADLINE_PLACEHOLDER);
|
|
25463
25517
|
for (const [index, part] of parts.entries()) {
|
|
25464
25518
|
if (index % 2 === 1) names.add(part);
|
|
25465
25519
|
else if (/[{}]/.test(part)) return void 0;
|
|
@@ -25477,10 +25531,10 @@ function valueEntries(values) {
|
|
|
25477
25531
|
const entries = Object.entries(values);
|
|
25478
25532
|
return entries.length > MAX_HEADLINE_VALUES ? void 0 : entries;
|
|
25479
25533
|
}
|
|
25480
|
-
function isTemplate(
|
|
25481
|
-
if (
|
|
25534
|
+
function isTemplate(text2, limit, entries) {
|
|
25535
|
+
if (text2.trim() === "" || Array.from(text2).length > limit) return false;
|
|
25482
25536
|
const given = new Set(entries.map(([name]) => name));
|
|
25483
|
-
const placeholders2 = templatePlaceholders(
|
|
25537
|
+
const placeholders2 = templatePlaceholders(text2);
|
|
25484
25538
|
return placeholders2 !== void 0 && [...placeholders2].every((name) => given.has(name));
|
|
25485
25539
|
}
|
|
25486
25540
|
function isTemplateValue(value) {
|
|
@@ -25496,15 +25550,15 @@ function isFact(fact) {
|
|
|
25496
25550
|
}
|
|
25497
25551
|
function cutValue(value) {
|
|
25498
25552
|
if (typeof value === "string") return cut2(value, MAX_VALUE_LENGTH);
|
|
25499
|
-
const { text, values } = value;
|
|
25500
|
-
if (values === void 0) return { text };
|
|
25553
|
+
const { text: text2, values } = value;
|
|
25554
|
+
if (values === void 0) return { text: text2 };
|
|
25501
25555
|
const cutValues = Object.entries(values).map(
|
|
25502
25556
|
([name, entry2]) => [name, typeof entry2 === "string" ? cut2(entry2, MAX_VALUE_LENGTH) : entry2]
|
|
25503
25557
|
);
|
|
25504
|
-
return { text, values: Object.fromEntries(cutValues) };
|
|
25558
|
+
return { text: text2, values: Object.fromEntries(cutValues) };
|
|
25505
25559
|
}
|
|
25506
|
-
function isText2(
|
|
25507
|
-
return isRecord2(
|
|
25560
|
+
function isText2(text2) {
|
|
25561
|
+
return isRecord2(text2) && typeof text2.label === "string" && text2.label.trim() !== "" && typeof text2.body === "string";
|
|
25508
25562
|
}
|
|
25509
25563
|
function pinsOf(pins) {
|
|
25510
25564
|
if (pins === void 0) return {};
|
|
@@ -25518,32 +25572,32 @@ function pinsOf(pins) {
|
|
|
25518
25572
|
}
|
|
25519
25573
|
function copyValue(value) {
|
|
25520
25574
|
if (typeof value === "string") return value;
|
|
25521
|
-
const { text, values } = value;
|
|
25522
|
-
return values === void 0 ? { text } : { text, values: { ...values } };
|
|
25575
|
+
const { text: text2, values } = value;
|
|
25576
|
+
return values === void 0 ? { text: text2 } : { text: text2, values: { ...values } };
|
|
25523
25577
|
}
|
|
25524
25578
|
function headlineOf(headline) {
|
|
25525
25579
|
if (!isRecord2(headline) || typeof headline.text !== "string") return void 0;
|
|
25526
|
-
const { text, values } = headline;
|
|
25580
|
+
const { text: text2, values } = headline;
|
|
25527
25581
|
const entries = valueEntries(values);
|
|
25528
|
-
if (entries === void 0 || !isTemplate(
|
|
25582
|
+
if (entries === void 0 || !isTemplate(text2, MAX_HEADLINE_LENGTH, entries)) return void 0;
|
|
25529
25583
|
if (!entries.every((entry2) => typeof entry2[1] === "string")) return void 0;
|
|
25530
|
-
return values === void 0 ? { text } : { text, values: Object.fromEntries(entries) };
|
|
25584
|
+
return values === void 0 ? { text: text2 } : { text: text2, values: Object.fromEntries(entries) };
|
|
25531
25585
|
}
|
|
25532
|
-
function cutHeadline({ text, values }) {
|
|
25533
|
-
if (values === void 0) return { text };
|
|
25586
|
+
function cutHeadline({ text: text2, values }) {
|
|
25587
|
+
if (values === void 0) return { text: text2 };
|
|
25534
25588
|
const cutValues = Object.entries(values).map(
|
|
25535
25589
|
([name, value]) => [name, cut2(value, MAX_HEADLINE_VALUE_LENGTH)]
|
|
25536
25590
|
);
|
|
25537
|
-
return { text, values: Object.fromEntries(cutValues) };
|
|
25591
|
+
return { text: text2, values: Object.fromEntries(cutValues) };
|
|
25538
25592
|
}
|
|
25539
|
-
function cutDescription({ headline, facts, text, pins }) {
|
|
25593
|
+
function cutDescription({ headline, facts, text: text2, pins }) {
|
|
25540
25594
|
return {
|
|
25541
25595
|
...headline && { headline: cutHeadline(headline) },
|
|
25542
25596
|
facts: facts.slice(0, MAX_FACTS).map(({ label, value }) => ({
|
|
25543
25597
|
label: cut2(label, MAX_LABEL_LENGTH),
|
|
25544
25598
|
value: cutValue(value)
|
|
25545
25599
|
})),
|
|
25546
|
-
...
|
|
25600
|
+
...text2 && { text: { label: cut2(text2.label, MAX_TEXT_LABEL_LENGTH), body: cut2(text2.body, MAX_TEXT_LENGTH) } },
|
|
25547
25601
|
...pins && { pins }
|
|
25548
25602
|
};
|
|
25549
25603
|
}
|
|
@@ -25567,47 +25621,54 @@ async function wholeCallDescription(spec, args, ctx) {
|
|
|
25567
25621
|
if (kept === void 0) return void 0;
|
|
25568
25622
|
const facts = entries.map(({ label, value }) => ({ label, value: copyValue(value) }));
|
|
25569
25623
|
const headline = answer.headline === void 0 ? void 0 : headlineOf(answer.headline);
|
|
25570
|
-
const
|
|
25571
|
-
if (headline === void 0 && facts.length === 0 &&
|
|
25572
|
-
return { ...headline && { headline }, facts, ...
|
|
25624
|
+
const text2 = answer.text === void 0 || answer.text.body === "" ? void 0 : { label: answer.text.label, body: answer.text.body };
|
|
25625
|
+
if (headline === void 0 && facts.length === 0 && text2 === void 0) return void 0;
|
|
25626
|
+
return { ...headline && { headline }, facts, ...text2 && { text: text2 }, ...kept };
|
|
25573
25627
|
}
|
|
25574
25628
|
|
|
25575
25629
|
// src/core/message/action-describe.ts
|
|
25576
25630
|
var EDIT_HEADLINES = {
|
|
25577
25631
|
named: "About to edit message {id} in {chat}",
|
|
25578
|
-
saved: "About to edit message {id} in Saved Messages"
|
|
25632
|
+
saved: "About to edit message {id} in Saved Messages",
|
|
25633
|
+
bare: "About to edit message {id}"
|
|
25579
25634
|
};
|
|
25580
25635
|
var DELETE_HEADLINES = {
|
|
25581
|
-
named: "About to delete message {id} from {chat}",
|
|
25582
|
-
saved: "About to delete message {id} from Saved Messages"
|
|
25636
|
+
named: "About to delete message {id} from {chat} for everyone",
|
|
25637
|
+
saved: "About to delete message {id} from Saved Messages",
|
|
25638
|
+
bare: "About to delete message {id} for everyone"
|
|
25583
25639
|
};
|
|
25584
25640
|
var REACT_HEADLINES = {
|
|
25585
25641
|
named: "About to react {emoji} to message {id} in {chat}",
|
|
25586
|
-
saved: "About to react {emoji} to message {id} in Saved Messages"
|
|
25642
|
+
saved: "About to react {emoji} to message {id} in Saved Messages",
|
|
25643
|
+
bare: "About to react {emoji} to message {id}"
|
|
25587
25644
|
};
|
|
25588
25645
|
var UNREACT_HEADLINES = {
|
|
25589
25646
|
named: "About to remove your reaction from message {id} in {chat}",
|
|
25590
|
-
saved: "About to remove your reaction from message {id} in Saved Messages"
|
|
25647
|
+
saved: "About to remove your reaction from message {id} in Saved Messages",
|
|
25648
|
+
bare: "About to remove your reaction from message {id}"
|
|
25591
25649
|
};
|
|
25592
25650
|
var PIN_HEADLINES = {
|
|
25593
25651
|
named: "About to pin message {id} in {chat}",
|
|
25594
|
-
saved: "About to pin message {id} in Saved Messages"
|
|
25652
|
+
saved: "About to pin message {id} in Saved Messages",
|
|
25653
|
+
bare: "About to pin message {id}"
|
|
25595
25654
|
};
|
|
25596
25655
|
var UNPIN_HEADLINES = {
|
|
25597
25656
|
named: "About to unpin message {id} in {chat}",
|
|
25598
|
-
saved: "About to unpin message {id} in Saved Messages"
|
|
25657
|
+
saved: "About to unpin message {id} in Saved Messages",
|
|
25658
|
+
bare: "About to unpin message {id}"
|
|
25599
25659
|
};
|
|
25600
25660
|
var MARK_READ_HEADLINES = {
|
|
25601
25661
|
named: "About to mark {chat} read up to message {id}",
|
|
25602
|
-
saved: "About to mark Saved Messages read up to message {id}"
|
|
25662
|
+
saved: "About to mark Saved Messages read up to message {id}",
|
|
25663
|
+
bare: "About to mark messages read up to message {id}"
|
|
25603
25664
|
};
|
|
25604
25665
|
function actionHeadline(headlines, { kind, name }, id, values) {
|
|
25605
25666
|
if (kind === "self") return { text: headlines.saved, values: { id: String(id), ...values } };
|
|
25606
|
-
return name === null ?
|
|
25667
|
+
return name === null ? { text: headlines.bare, values: { id: String(id), ...values } } : { text: headlines.named, values: { id: String(id), chat: name, ...values } };
|
|
25607
25668
|
}
|
|
25608
25669
|
function currentFacts({ body, media }) {
|
|
25609
|
-
|
|
25610
|
-
return
|
|
25670
|
+
if (body) return [{ label: "Current", value: cut2(body, MAX_VALUE_LENGTH) }];
|
|
25671
|
+
return media ? [{ label: "Media", value: mediaKindValue(media.type) }] : [];
|
|
25611
25672
|
}
|
|
25612
25673
|
function describeAction(headlines, chat, id, message2, extras = {}) {
|
|
25613
25674
|
const headline = actionHeadline(headlines, chat, id, extras.values ?? {});
|
|
@@ -25843,7 +25904,7 @@ var telegramMessageDelete = defineTool({
|
|
|
25843
25904
|
"A result means Telegram deleted the message for everyone. `already` means it was gone before this call.",
|
|
25844
25905
|
"A failure `uncertain` means the delete may have gone through: check the chat in Telegram and never ask for it again without the user checking."
|
|
25845
25906
|
].join(" "),
|
|
25846
|
-
intent: "About to delete a message",
|
|
25907
|
+
intent: "About to delete a message for everyone",
|
|
25847
25908
|
toolset: "actions",
|
|
25848
25909
|
class: "administrative",
|
|
25849
25910
|
input: deleteInput,
|
|
@@ -25875,10 +25936,10 @@ var telegramMessageDelete = defineTool({
|
|
|
25875
25936
|
});
|
|
25876
25937
|
|
|
25877
25938
|
// src/core/message/edit-prepare.ts
|
|
25878
|
-
function prepareEdit(mirror, chatId, id,
|
|
25939
|
+
function prepareEdit(mirror, chatId, id, text2) {
|
|
25879
25940
|
const { chat, message: message2 } = findOwnMessage(mirror, chatId, id, "edit");
|
|
25880
25941
|
if (!message2) throw deletedMessage();
|
|
25881
|
-
checkEditable({ ...message2, captioned: message2.media !== null && takesCaption(message2.media.type) },
|
|
25942
|
+
checkEditable({ ...message2, captioned: message2.media !== null && takesCaption(message2.media.type) }, text2);
|
|
25882
25943
|
return { chat, message: message2 };
|
|
25883
25944
|
}
|
|
25884
25945
|
|
|
@@ -25901,22 +25962,22 @@ var telegramMessageEdit = defineTool({
|
|
|
25901
25962
|
input: editInput,
|
|
25902
25963
|
output: editOutput,
|
|
25903
25964
|
async describe(args, ctx) {
|
|
25904
|
-
const
|
|
25965
|
+
const text2 = checkedText(args.text);
|
|
25905
25966
|
const chat = requireChatId(args.chat, MESSAGE_EDIT_TOOL_ID);
|
|
25906
25967
|
const paths = await pickPaths(ctx, args.account);
|
|
25907
|
-
const target = readMirror(paths, (mirror) => prepareEdit(mirror, chat, args.id,
|
|
25968
|
+
const target = readMirror(paths, (mirror) => prepareEdit(mirror, chat, args.id, text2));
|
|
25908
25969
|
return {
|
|
25909
25970
|
...describeAction(EDIT_HEADLINES, target.chat, args.id, target.message),
|
|
25910
|
-
text: { label: "New text", body:
|
|
25971
|
+
text: { label: "New text", body: text2 }
|
|
25911
25972
|
};
|
|
25912
25973
|
},
|
|
25913
25974
|
targets: (args, ctx) => actionTargets(MESSAGE_EDIT_TOOL_ID, args, ctx),
|
|
25914
25975
|
async execute(args, ctx) {
|
|
25915
25976
|
const chat = requireChatId(args.chat, MESSAGE_EDIT_TOOL_ID);
|
|
25916
|
-
const
|
|
25977
|
+
const text2 = checkedText(args.text);
|
|
25917
25978
|
const paths = await pickPaths(ctx, args.account);
|
|
25918
|
-
readMirror(paths, (mirror) => prepareEdit(mirror, chat, args.id,
|
|
25919
|
-
const params = { chat, id: args.id, text };
|
|
25979
|
+
readMirror(paths, (mirror) => prepareEdit(mirror, chat, args.id, text2));
|
|
25980
|
+
const params = { chat, id: args.id, text: text2 };
|
|
25920
25981
|
const edited = await callService(paths.socket, SERVICE_REQUESTS.edit, params, {
|
|
25921
25982
|
effect: "write",
|
|
25922
25983
|
signal: ctx.signal,
|
|
@@ -26112,7 +26173,7 @@ var telegramMessageSend = defineTool({
|
|
|
26112
26173
|
input: input5,
|
|
26113
26174
|
output: output5,
|
|
26114
26175
|
async describe(args, ctx) {
|
|
26115
|
-
const
|
|
26176
|
+
const text2 = checkedText(args.text);
|
|
26116
26177
|
const chat = requireChatId(args.chat, MESSAGE_SEND_TOOL_ID);
|
|
26117
26178
|
const paths = await pickPaths(ctx, args.account);
|
|
26118
26179
|
const { row, title } = readMirror(paths, (mirror) => {
|
|
@@ -26124,17 +26185,17 @@ var telegramMessageSend = defineTool({
|
|
|
26124
26185
|
headline: { text: "About to send a message to {chat}", values: { chat: row.name } }
|
|
26125
26186
|
},
|
|
26126
26187
|
facts: [chatFact(row.kind), ...topicFacts(args.topic, title), ...replyFacts(args.reply_to)],
|
|
26127
|
-
text: { label: "Message text", body:
|
|
26188
|
+
text: { label: "Message text", body: text2 }
|
|
26128
26189
|
};
|
|
26129
26190
|
},
|
|
26130
26191
|
targets: (args, ctx) => chatTargets(MESSAGE_SEND_TOOL_ID, args, ctx),
|
|
26131
26192
|
async execute(args, ctx) {
|
|
26132
26193
|
const chat = requireChatId(args.chat, MESSAGE_SEND_TOOL_ID);
|
|
26133
|
-
const
|
|
26194
|
+
const text2 = checkedText(args.text);
|
|
26134
26195
|
const paths = await pickPaths(ctx, args.account);
|
|
26135
26196
|
const params = {
|
|
26136
26197
|
chat,
|
|
26137
|
-
text,
|
|
26198
|
+
text: text2,
|
|
26138
26199
|
...args.topic !== void 0 && { topic: args.topic },
|
|
26139
26200
|
...args.reply_to !== void 0 && { reply_to: args.reply_to }
|
|
26140
26201
|
};
|
|
@@ -26147,7 +26208,7 @@ var telegramMessageSend = defineTool({
|
|
|
26147
26208
|
});
|
|
26148
26209
|
return sendResult(chat, sent);
|
|
26149
26210
|
} catch (error62) {
|
|
26150
|
-
throw isToolError(error62) && error62.code === "uncertain" ? withSentLike(error62, paths, chat,
|
|
26211
|
+
throw isToolError(error62) && error62.code === "uncertain" ? withSentLike(error62, paths, chat, text2, startedAt) : error62;
|
|
26151
26212
|
}
|
|
26152
26213
|
}
|
|
26153
26214
|
});
|
|
@@ -26449,12 +26510,6 @@ var FILE_TRANSLATIONS = {
|
|
|
26449
26510
|
"About to save a file from {chat}": "{chat} \u306E\u30D5\u30A1\u30A4\u30EB\u3092\u4FDD\u5B58\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26450
26511
|
"About to save {file}": "{file} \u3092\u4FDD\u5B58\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26451
26512
|
File: "\u30D5\u30A1\u30A4\u30EB",
|
|
26452
|
-
Photo: "\u5199\u771F",
|
|
26453
|
-
Document: "\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8",
|
|
26454
|
-
Audio: "\u97F3\u58F0",
|
|
26455
|
-
"Voice message": "\u30DC\u30A4\u30B9\u30E1\u30C3\u30BB\u30FC\u30B8",
|
|
26456
|
-
Video: "\u52D5\u753B",
|
|
26457
|
-
Sticker: "\u30B9\u30BF\u30F3\u30D7",
|
|
26458
26513
|
Unpack: "\u5C55\u958B",
|
|
26459
26514
|
Yes: "\u3059\u308B"
|
|
26460
26515
|
}
|
|
@@ -26469,24 +26524,31 @@ var ACTION_TRANSLATIONS = {
|
|
|
26469
26524
|
"Pin or unpin a message": "\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u30D4\u30F3\u7559\u3081\u3059\u308B\u30FB\u89E3\u9664\u3059\u308B",
|
|
26470
26525
|
"Mark a chat read": "\u30C1\u30E3\u30C3\u30C8\u3092\u65E2\u8AAD\u306B\u3059\u308B",
|
|
26471
26526
|
"About to edit a message": "\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u7DE8\u96C6\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26472
|
-
"About to delete a message": "\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u524A\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26527
|
+
"About to delete a message for everyone": "\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u5168\u54E1\u5206\u524A\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26473
26528
|
"About to change a reaction": "\u30EA\u30A2\u30AF\u30B7\u30E7\u30F3\u3092\u5909\u66F4\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26474
26529
|
"About to pin or unpin a message": "\u30E1\u30C3\u30BB\u30FC\u30B8\u306E\u30D4\u30F3\u7559\u3081\u3092\u5909\u66F4\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26475
26530
|
"About to mark messages read": "\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u65E2\u8AAD\u306B\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26476
26531
|
"About to edit message {id} in {chat}": "{chat} \u306E\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u7DE8\u96C6\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26477
|
-
"About to edit message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\
|
|
26478
|
-
"About to
|
|
26479
|
-
"About to delete message {id} from
|
|
26532
|
+
"About to edit message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u3042\u308B\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u7DE8\u96C6\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26533
|
+
"About to edit message {id}": "\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u7DE8\u96C6\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26534
|
+
"About to delete message {id} from {chat} for everyone": "{chat} \u306E\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u5168\u54E1\u5206\u524A\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26535
|
+
"About to delete message {id} from Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u3042\u308B\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u524A\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26536
|
+
"About to delete message {id} for everyone": "\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u5168\u54E1\u5206\u524A\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26480
26537
|
"About to react {emoji} to message {id} in {chat}": "{chat} \u306E\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u306B {emoji} \u306E\u30EA\u30A2\u30AF\u30B7\u30E7\u30F3\u3092\u4ED8\u3051\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26481
|
-
"About to react {emoji} to message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\
|
|
26538
|
+
"About to react {emoji} to message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u3042\u308B\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u306B {emoji} \u306E\u30EA\u30A2\u30AF\u30B7\u30E7\u30F3\u3092\u4ED8\u3051\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26539
|
+
"About to react {emoji} to message {id}": "\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u306B {emoji} \u306E\u30EA\u30A2\u30AF\u30B7\u30E7\u30F3\u3092\u4ED8\u3051\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26482
26540
|
"About to remove your reaction from message {id} in {chat}": "{chat} \u306E\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u304B\u3089\u81EA\u5206\u306E\u30EA\u30A2\u30AF\u30B7\u30E7\u30F3\u3092\u5916\u305D\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26483
|
-
"About to remove your reaction from message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\
|
|
26541
|
+
"About to remove your reaction from message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u3042\u308B\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u304B\u3089\u81EA\u5206\u306E\u30EA\u30A2\u30AF\u30B7\u30E7\u30F3\u3092\u5916\u305D\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26542
|
+
"About to remove your reaction from message {id}": "\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u304B\u3089\u81EA\u5206\u306E\u30EA\u30A2\u30AF\u30B7\u30E7\u30F3\u3092\u5916\u305D\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26484
26543
|
"About to pin message {id} in {chat}": "{chat} \u306E\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u30D4\u30F3\u7559\u3081\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26485
|
-
"About to pin message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\
|
|
26544
|
+
"About to pin message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u3042\u308B\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u30D4\u30F3\u7559\u3081\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26545
|
+
"About to pin message {id}": "\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u3092\u30D4\u30F3\u7559\u3081\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26486
26546
|
"About to unpin message {id} in {chat}": "{chat} \u306E\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u306E\u30D4\u30F3\u7559\u3081\u3092\u89E3\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26487
|
-
"About to unpin message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\
|
|
26547
|
+
"About to unpin message {id} in Saved Messages": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\u306B\u3042\u308B\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u306E\u30D4\u30F3\u7559\u3081\u3092\u89E3\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26548
|
+
"About to unpin message {id}": "\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u306E\u30D4\u30F3\u7559\u3081\u3092\u89E3\u9664\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26488
26549
|
"About to mark {chat} read up to message {id}": "{chat} \u3092\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u307E\u3067\u65E2\u8AAD\u306B\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26489
26550
|
"About to mark Saved Messages read up to message {id}": "\u4FDD\u5B58\u6E08\u307F\u30E1\u30C3\u30BB\u30FC\u30B8\u3092\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u307E\u3067\u65E2\u8AAD\u306B\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26551
|
+
"About to mark messages read up to message {id}": "\u30E1\u30C3\u30BB\u30FC\u30B8 {id} \u307E\u3067\u65E2\u8AAD\u306B\u3057\u3088\u3046\u3068\u3057\u3066\u3044\u307E\u3059",
|
|
26490
26552
|
Message: "\u30E1\u30C3\u30BB\u30FC\u30B8",
|
|
26491
26553
|
Current: "\u73FE\u5728\u306E\u5185\u5BB9",
|
|
26492
26554
|
Replaces: "\u7F6E\u304D\u63DB\u3048\u308B\u30EA\u30A2\u30AF\u30B7\u30E7\u30F3",
|
|
@@ -26530,6 +26592,7 @@ var SYNC_TRANSLATIONS = {
|
|
|
26530
26592
|
var ALL_TRANSLATIONS = mergeTranslations(
|
|
26531
26593
|
FACT_TRANSLATIONS,
|
|
26532
26594
|
CHAT_FACT_TRANSLATIONS,
|
|
26595
|
+
MEDIA_FACT_TRANSLATIONS,
|
|
26533
26596
|
MESSAGE_TRANSLATIONS,
|
|
26534
26597
|
ACTION_TRANSLATIONS,
|
|
26535
26598
|
FILE_TRANSLATIONS,
|
|
@@ -26537,6 +26600,35 @@ var ALL_TRANSLATIONS = mergeTranslations(
|
|
|
26537
26600
|
SYNC_TRANSLATIONS
|
|
26538
26601
|
);
|
|
26539
26602
|
|
|
26603
|
+
// src/entry/directory.ts
|
|
26604
|
+
import { homedir as homedir3 } from "node:os";
|
|
26605
|
+
import { isAbsolute as isAbsolute5, resolve as resolve4 } from "node:path";
|
|
26606
|
+
var DOWNLOADS_DIR = "Downloads";
|
|
26607
|
+
var DEFAULT_DOWNLOAD_MAX_MB = 100;
|
|
26608
|
+
function homeDir(env) {
|
|
26609
|
+
const envHome = env.HOME;
|
|
26610
|
+
if (envHome && isAbsolute5(envHome)) return envHome;
|
|
26611
|
+
return homedir3();
|
|
26612
|
+
}
|
|
26613
|
+
function defaultStateDir(name, env, home) {
|
|
26614
|
+
const xdg = env.XDG_STATE_HOME;
|
|
26615
|
+
return xdg && isAbsolute5(xdg) ? resolve4(xdg, name) : resolve4(home, ".local", "state", name);
|
|
26616
|
+
}
|
|
26617
|
+
function text(value) {
|
|
26618
|
+
return typeof value === "string" ? value : void 0;
|
|
26619
|
+
}
|
|
26620
|
+
function resolveDirectorySettings(options, env, profile) {
|
|
26621
|
+
const home = homeDir(env);
|
|
26622
|
+
const maxMb = options.download_max_mb;
|
|
26623
|
+
const sendDirs = options.send_dirs;
|
|
26624
|
+
return {
|
|
26625
|
+
state_dir: text(options.state_dir) ?? defaultStateDir(profile.name, env, home),
|
|
26626
|
+
download_dir: text(options.download_dir) ?? resolve4(home, DOWNLOADS_DIR, profile.name),
|
|
26627
|
+
download_max_mb: typeof maxMb === "number" ? maxMb : DEFAULT_DOWNLOAD_MAX_MB,
|
|
26628
|
+
send_dirs: Array.isArray(sendDirs) ? [...sendDirs] : []
|
|
26629
|
+
};
|
|
26630
|
+
}
|
|
26631
|
+
|
|
26540
26632
|
// src/entry/errors.ts
|
|
26541
26633
|
function errorBody(code, message2, details) {
|
|
26542
26634
|
return { code, message: message2, ...details !== void 0 && { details } };
|
|
@@ -26556,9 +26648,9 @@ function mark(character) {
|
|
|
26556
26648
|
const hex3 = character.codePointAt(0).toString(16).toUpperCase();
|
|
26557
26649
|
return `<U+${hex3.padStart(MARK_DIGITS, "0")}>`;
|
|
26558
26650
|
}
|
|
26559
|
-
function visible(
|
|
26560
|
-
if (options.keepNewlines) return
|
|
26561
|
-
return
|
|
26651
|
+
function visible(text2, options = {}) {
|
|
26652
|
+
if (options.keepNewlines) return text2.replace(/\r\n/g, "\n").replace(HIDDEN_EXCEPT_NEWLINE, mark);
|
|
26653
|
+
return text2.replace(HIDDEN_ALL, mark);
|
|
26562
26654
|
}
|
|
26563
26655
|
|
|
26564
26656
|
// src/entry/words.ts
|
|
@@ -26597,12 +26689,12 @@ var omittedOf = (count) => count > 0 ? { omitted: count } : {};
|
|
|
26597
26689
|
function quoted(value) {
|
|
26598
26690
|
return `"${visible(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
26599
26691
|
}
|
|
26600
|
-
function filled(
|
|
26601
|
-
return
|
|
26692
|
+
function filled(text2, literal2, slot) {
|
|
26693
|
+
return text2.split(HEADLINE_PLACEHOLDER).map((part, index) => index % 2 === 0 ? literal2(part) : slot(part)).join("");
|
|
26602
26694
|
}
|
|
26603
|
-
function renderedHeadline({ text, values = {} }) {
|
|
26695
|
+
function renderedHeadline({ text: text2, values = {} }) {
|
|
26604
26696
|
return filled(
|
|
26605
|
-
|
|
26697
|
+
text2,
|
|
26606
26698
|
(part) => visible(part),
|
|
26607
26699
|
(name) => quoted(values[name] ?? "")
|
|
26608
26700
|
);
|
|
@@ -26616,7 +26708,7 @@ function renderedValue(value, t) {
|
|
|
26616
26708
|
return { value: visible(cut2(whole, MAX_VALUE_LENGTH)), ...omittedOf(omittedBy(whole, MAX_VALUE_LENGTH)) };
|
|
26617
26709
|
}
|
|
26618
26710
|
function shownDescription(description, t) {
|
|
26619
|
-
const { headline, facts, text } = cutDescription(description);
|
|
26711
|
+
const { headline, facts, text: text2 } = cutDescription(description);
|
|
26620
26712
|
const wholeBody = description.text?.body ?? "";
|
|
26621
26713
|
const dropped = description.facts.length - facts.length;
|
|
26622
26714
|
return {
|
|
@@ -26626,9 +26718,9 @@ function shownDescription(description, t) {
|
|
|
26626
26718
|
...renderedValue(description.facts[index].value, t)
|
|
26627
26719
|
})),
|
|
26628
26720
|
...dropped > 0 && { dropped },
|
|
26629
|
-
...
|
|
26721
|
+
...text2 && {
|
|
26630
26722
|
text: {
|
|
26631
|
-
label: visible(t.word(
|
|
26723
|
+
label: visible(t.word(text2.label, MAX_TEXT_LABEL_LENGTH)),
|
|
26632
26724
|
body: visible(cut2(wholeBody, MAX_TEXT_LENGTH), { keepNewlines: true }),
|
|
26633
26725
|
...omittedOf(omittedBy(wholeBody, MAX_TEXT_LENGTH))
|
|
26634
26726
|
}
|
|
@@ -26642,9 +26734,9 @@ async function timedCallDescription(spec, args, ctx, timeoutMs = DESCRIBE_TIMEOU
|
|
|
26642
26734
|
let timer;
|
|
26643
26735
|
let onAbort2;
|
|
26644
26736
|
try {
|
|
26645
|
-
const timedOut = new Promise((
|
|
26737
|
+
const timedOut = new Promise((resolve6) => {
|
|
26646
26738
|
timer = setTimeout(() => {
|
|
26647
|
-
|
|
26739
|
+
resolve6(void 0);
|
|
26648
26740
|
controller.abort();
|
|
26649
26741
|
}, timeoutMs);
|
|
26650
26742
|
});
|
|
@@ -26694,81 +26786,44 @@ async function checkPin(spec, args, ctx, pin, timeoutMs = DESCRIBE_TIMEOUT_MS) {
|
|
|
26694
26786
|
var PROJECT_PROFILE = {
|
|
26695
26787
|
name: PROJECT.name,
|
|
26696
26788
|
envPrefix: PROJECT.envPrefix,
|
|
26697
|
-
toolsets: { names: PROJECT.toolsets, defaults: PROJECT.defaultToolsets }
|
|
26789
|
+
toolsets: { names: PROJECT.toolsets, defaults: PROJECT.defaultToolsets },
|
|
26790
|
+
options: PROJECT.options
|
|
26698
26791
|
};
|
|
26699
26792
|
|
|
26700
|
-
// src/entry/download-dir.ts
|
|
26701
|
-
import { resolve as resolve5 } from "node:path";
|
|
26702
|
-
|
|
26703
|
-
// src/entry/directory.ts
|
|
26704
|
-
import { homedir as homedir3 } from "node:os";
|
|
26705
|
-
import { isAbsolute as isAbsolute5, join as join11, resolve as resolve4, sep as sep4 } from "node:path";
|
|
26706
|
-
function homeDir(env) {
|
|
26707
|
-
const envHome = env.HOME;
|
|
26708
|
-
if (envHome && isAbsolute5(envHome)) return envHome;
|
|
26709
|
-
return homedir3();
|
|
26710
|
-
}
|
|
26711
|
-
function resolveGivenDirectory(given, home) {
|
|
26712
|
-
const text = given.text.trim();
|
|
26713
|
-
const expanded = text === "~" ? home : text.startsWith("~/") || text.startsWith(`~${sep4}`) ? join11(home, text.slice(2)) : text;
|
|
26714
|
-
if (!text || !isAbsolute5(expanded)) {
|
|
26715
|
-
throw new ToolError("invalid_argument", `${given.source} must be an absolute path.`);
|
|
26716
|
-
}
|
|
26717
|
-
return resolve4(expanded);
|
|
26718
|
-
}
|
|
26719
|
-
|
|
26720
|
-
// src/entry/download-dir.ts
|
|
26721
|
-
var DOWNLOADS_DIR = "Downloads";
|
|
26722
|
-
function resolveDownloadDir(given, env, profile) {
|
|
26723
|
-
const home = homeDir(env);
|
|
26724
|
-
return given !== void 0 ? resolveGivenDirectory(given, home) : resolve5(home, DOWNLOADS_DIR, profile.name);
|
|
26725
|
-
}
|
|
26726
|
-
|
|
26727
|
-
// src/entry/send-dirs.ts
|
|
26728
|
-
function resolveSendDirs(given, env) {
|
|
26729
|
-
const home = homeDir(env);
|
|
26730
|
-
return given.map((directory) => resolveGivenDirectory(directory, home));
|
|
26731
|
-
}
|
|
26732
|
-
|
|
26733
|
-
// src/entry/state-dir.ts
|
|
26734
|
-
import { isAbsolute as isAbsolute6, resolve as resolve6 } from "node:path";
|
|
26735
|
-
function resolveStateDir(given, env, profile) {
|
|
26736
|
-
const home = homeDir(env);
|
|
26737
|
-
if (given !== void 0) return resolveGivenDirectory(given, home);
|
|
26738
|
-
const xdg = env.XDG_STATE_HOME;
|
|
26739
|
-
if (xdg && isAbsolute6(xdg)) {
|
|
26740
|
-
return resolve6(xdg, profile.name);
|
|
26741
|
-
}
|
|
26742
|
-
return resolve6(home, ".local", "state", profile.name);
|
|
26743
|
-
}
|
|
26744
|
-
|
|
26745
26793
|
// src/entry/settings.ts
|
|
26794
|
+
import { homedir as homedir4 } from "node:os";
|
|
26795
|
+
import { isAbsolute as isAbsolute6, join as join11, resolve as resolvePath, sep as sep4 } from "node:path";
|
|
26746
26796
|
var CONFIRM_MODES = ["harness", "elicitation"];
|
|
26747
26797
|
var ALL_TOOLSETS = "all";
|
|
26748
26798
|
var TRUE_VALUES = ["1", "true"];
|
|
26749
26799
|
var FALSE_VALUES = ["0", "false"];
|
|
26750
|
-
var DEFAULT_DOWNLOAD_MAX_MB = 100;
|
|
26751
|
-
var MAX_DOWNLOAD_MB = 2e3;
|
|
26752
26800
|
var OPTIONS = {
|
|
26753
26801
|
toolsets: { flag: "--toolsets", envSuffix: "TOOLSETS" },
|
|
26754
26802
|
read_only: { flag: "--read-only", envSuffix: "READ_ONLY", boolean: true },
|
|
26755
26803
|
tools: { flag: "--tools", envSuffix: "TOOLS" },
|
|
26756
26804
|
exclude_tools: { flag: "--exclude-tools", envSuffix: "EXCLUDE_TOOLS" },
|
|
26757
|
-
confirm: { flag: "--confirm", envSuffix: "CONFIRM" }
|
|
26758
|
-
|
|
26759
|
-
|
|
26760
|
-
|
|
26761
|
-
|
|
26762
|
-
|
|
26763
|
-
|
|
26764
|
-
|
|
26765
|
-
|
|
26805
|
+
confirm: { flag: "--confirm", envSuffix: "CONFIRM" }
|
|
26806
|
+
};
|
|
26807
|
+
function profileOptions(profile) {
|
|
26808
|
+
return profile.options ?? {};
|
|
26809
|
+
}
|
|
26810
|
+
function settingOptions(profile) {
|
|
26811
|
+
const toolOptions = Object.entries(profileOptions(profile)).map(([name, spec]) => [
|
|
26812
|
+
name,
|
|
26813
|
+
{
|
|
26814
|
+
flag: `--${name.replace(/_/g, "-")}`,
|
|
26815
|
+
envSuffix: name.toUpperCase(),
|
|
26816
|
+
...optionType(spec) === "boolean" && { boolean: true }
|
|
26817
|
+
}
|
|
26818
|
+
]);
|
|
26819
|
+
return { ...OPTIONS, ...Object.fromEntries(toolOptions) };
|
|
26820
|
+
}
|
|
26766
26821
|
function envName(name, profile) {
|
|
26767
|
-
return `${profile.envPrefix}_${
|
|
26822
|
+
return `${profile.envPrefix}_${settingOptions(profile)[name].envSuffix}`;
|
|
26768
26823
|
}
|
|
26769
|
-
function readFlags(argv) {
|
|
26824
|
+
function readFlags(argv, profile) {
|
|
26770
26825
|
const byFlag = new Map(
|
|
26771
|
-
Object.
|
|
26826
|
+
Object.entries(settingOptions(profile)).map(([name, option]) => [option.flag, { name, ...option }])
|
|
26772
26827
|
);
|
|
26773
26828
|
const given = {};
|
|
26774
26829
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -26803,9 +26858,9 @@ function checkToolsets(names, source, toolsets) {
|
|
|
26803
26858
|
return names.length ? names : void 0;
|
|
26804
26859
|
}
|
|
26805
26860
|
function parseBoolean(value, source) {
|
|
26806
|
-
const
|
|
26807
|
-
if (TRUE_VALUES.includes(
|
|
26808
|
-
if (FALSE_VALUES.includes(
|
|
26861
|
+
const text2 = value.trim().toLowerCase();
|
|
26862
|
+
if (TRUE_VALUES.includes(text2)) return true;
|
|
26863
|
+
if (FALSE_VALUES.includes(text2)) return false;
|
|
26809
26864
|
throw new ToolError(
|
|
26810
26865
|
"invalid_argument",
|
|
26811
26866
|
`Unknown value "${value}" in ${source}; use one of ${[...TRUE_VALUES, ...FALSE_VALUES].join(", ")}.`
|
|
@@ -26821,44 +26876,115 @@ function parseConfirm(value, source) {
|
|
|
26821
26876
|
}
|
|
26822
26877
|
return mode;
|
|
26823
26878
|
}
|
|
26824
|
-
function
|
|
26825
|
-
|
|
26826
|
-
|
|
26827
|
-
|
|
26828
|
-
|
|
26829
|
-
throw new ToolError("invalid_argument", `${source} must be an integer from 1 to ${MAX_DOWNLOAD_MB}.`);
|
|
26879
|
+
function parseNumber2(value, source) {
|
|
26880
|
+
const trimmed = value.trim();
|
|
26881
|
+
const parsed = trimmed === "" ? Number.NaN : Number(trimmed);
|
|
26882
|
+
if (!Number.isFinite(parsed)) {
|
|
26883
|
+
throw new ToolError("invalid_argument", `Unknown number "${value}" in ${source}; use a finite number.`);
|
|
26830
26884
|
}
|
|
26831
|
-
return
|
|
26885
|
+
return parsed;
|
|
26832
26886
|
}
|
|
26833
|
-
function
|
|
26834
|
-
const
|
|
26835
|
-
|
|
26887
|
+
function absolutePath(text2, source, env) {
|
|
26888
|
+
const home = env.HOME !== void 0 && isAbsolute6(env.HOME) ? env.HOME : homedir4();
|
|
26889
|
+
const expanded = text2 === "~" || text2.startsWith("~/") || text2.startsWith(`~${sep4}`) ? join11(home, text2.slice(1)) : text2;
|
|
26890
|
+
if (!isAbsolute6(expanded)) throw new ToolError("invalid_argument", `${source} must be an absolute path.`);
|
|
26891
|
+
return resolvePath(expanded);
|
|
26836
26892
|
}
|
|
26837
|
-
function
|
|
26838
|
-
|
|
26839
|
-
const max3 = value("download_max_mb");
|
|
26840
|
-
return {
|
|
26841
|
-
download_dir: resolveDownloadDir(value("download_dir"), env, profile),
|
|
26842
|
-
download_max_mb: max3 === void 0 ? DEFAULT_DOWNLOAD_MAX_MB : downloadMaxMbText(max3)
|
|
26843
|
-
};
|
|
26893
|
+
function absolutePaths(items, source, env) {
|
|
26894
|
+
return items.length > 0 ? items.map((item) => absolutePath(item, source, env)) : void 0;
|
|
26844
26895
|
}
|
|
26845
26896
|
function envText(name, env, profile) {
|
|
26846
26897
|
const variable = envName(name, profile);
|
|
26847
|
-
const
|
|
26848
|
-
return
|
|
26898
|
+
const text2 = env[variable];
|
|
26899
|
+
return text2 === void 0 || text2.trim() === "" ? void 0 : { text: text2, source: variable };
|
|
26849
26900
|
}
|
|
26850
26901
|
function flagOrEnvText(flags, name, env, profile) {
|
|
26851
26902
|
const flagged = flags[name];
|
|
26852
26903
|
return flagged !== void 0 ? { text: flagged, source: OPTIONS[name].flag } : envText(name, env, profile);
|
|
26853
26904
|
}
|
|
26905
|
+
function optionType(spec) {
|
|
26906
|
+
return typeof spec === "string" ? spec : spec.type;
|
|
26907
|
+
}
|
|
26908
|
+
function itemCount(count) {
|
|
26909
|
+
return count === 1 ? "1 item" : `${count} items`;
|
|
26910
|
+
}
|
|
26911
|
+
function numberBoundsError({ integer: integer2, min: min3, max: max3 }, source) {
|
|
26912
|
+
const range = min3 !== void 0 && max3 !== void 0 ? ` from ${min3} to ${max3}` : min3 !== void 0 ? ` of at least ${min3}` : max3 !== void 0 ? ` of at most ${max3}` : "";
|
|
26913
|
+
return new ToolError("invalid_argument", `${source} must be ${integer2 ? "a whole number" : "a number"}${range}.`);
|
|
26914
|
+
}
|
|
26915
|
+
function countBoundsError({ min: min3, max: max3 }, source) {
|
|
26916
|
+
const range = min3 !== void 0 && max3 !== void 0 ? `from ${min3} to ${max3} items` : min3 !== void 0 ? `at least ${itemCount(min3)}` : `at most ${itemCount(max3)}`;
|
|
26917
|
+
return new ToolError("invalid_argument", `${source} must list ${range}.`);
|
|
26918
|
+
}
|
|
26919
|
+
function withinBounds(spec, value, source) {
|
|
26920
|
+
if (value === void 0 || typeof spec === "string") return value;
|
|
26921
|
+
const bounds = spec;
|
|
26922
|
+
const { integer: integer2, min: min3, max: max3 } = bounds;
|
|
26923
|
+
if (typeof value === "number") {
|
|
26924
|
+
if (integer2 && !Number.isInteger(value) || min3 !== void 0 && value < min3 || max3 !== void 0 && value > max3) {
|
|
26925
|
+
throw numberBoundsError(bounds, source);
|
|
26926
|
+
}
|
|
26927
|
+
} else if (typeof value === "object" && (min3 !== void 0 && value.length < min3 || max3 !== void 0 && value.length > max3)) {
|
|
26928
|
+
throw countBoundsError(bounds, source);
|
|
26929
|
+
}
|
|
26930
|
+
return value;
|
|
26931
|
+
}
|
|
26932
|
+
function parseOptionText(spec, given, env) {
|
|
26933
|
+
return withinBounds(spec, parseTypedText(optionType(spec), given, env), given.source);
|
|
26934
|
+
}
|
|
26935
|
+
function parseTypedText(kind, given, env) {
|
|
26936
|
+
switch (kind) {
|
|
26937
|
+
case "text":
|
|
26938
|
+
return nonBlank(given.text);
|
|
26939
|
+
case "boolean":
|
|
26940
|
+
return parseBoolean(given.text, given.source);
|
|
26941
|
+
case "number":
|
|
26942
|
+
return parseNumber2(given.text, given.source);
|
|
26943
|
+
case "list": {
|
|
26944
|
+
const items = splitList(given.text);
|
|
26945
|
+
return items.length > 0 ? items : void 0;
|
|
26946
|
+
}
|
|
26947
|
+
case "path": {
|
|
26948
|
+
const text2 = nonBlank(given.text);
|
|
26949
|
+
return text2 === void 0 ? void 0 : absolutePath(text2, given.source, env);
|
|
26950
|
+
}
|
|
26951
|
+
case "paths":
|
|
26952
|
+
return absolutePaths(splitList(given.text), given.source, env);
|
|
26953
|
+
}
|
|
26954
|
+
}
|
|
26955
|
+
function optionsFrom(flags, env, profile) {
|
|
26956
|
+
const options = {};
|
|
26957
|
+
for (const [name, spec] of Object.entries(profileOptions(profile))) {
|
|
26958
|
+
if (flags[name] !== void 0) {
|
|
26959
|
+
const parsed = parseOptionText(spec, { text: flags[name], source: settingOptions(profile)[name].flag }, env);
|
|
26960
|
+
if (parsed !== void 0) options[name] = parsed;
|
|
26961
|
+
continue;
|
|
26962
|
+
}
|
|
26963
|
+
const fromEnv = envText(name, env, profile);
|
|
26964
|
+
if (fromEnv !== void 0) {
|
|
26965
|
+
const parsed = parseOptionText(spec, fromEnv, env);
|
|
26966
|
+
if (parsed !== void 0) options[name] = parsed;
|
|
26967
|
+
}
|
|
26968
|
+
}
|
|
26969
|
+
return options;
|
|
26970
|
+
}
|
|
26971
|
+
function parseToolOptions(argv, env, profile = PROJECT_PROFILE) {
|
|
26972
|
+
const flags = readFlags(argv, profile);
|
|
26973
|
+
const known = profileOptions(profile);
|
|
26974
|
+
const other = Object.keys(flags).find((name) => !(name in known));
|
|
26975
|
+
if (other !== void 0) {
|
|
26976
|
+
throw new ToolError("invalid_argument", `Unknown option "${settingOptions(profile)[other].flag}".`);
|
|
26977
|
+
}
|
|
26978
|
+
return optionsFrom(flags, env, profile);
|
|
26979
|
+
}
|
|
26854
26980
|
function parseSettings(argv, env, profile = PROJECT_PROFILE) {
|
|
26855
|
-
const flags = readFlags(argv);
|
|
26981
|
+
const flags = readFlags(argv, profile);
|
|
26856
26982
|
const value = (name) => flagOrEnvText(flags, name, env, profile);
|
|
26983
|
+
const options = optionsFrom(flags, env, profile);
|
|
26857
26984
|
const settings = {
|
|
26858
26985
|
confirm: "harness",
|
|
26859
|
-
|
|
26860
|
-
...
|
|
26861
|
-
send_dirs: resolveSendDirs(listedDirectories(value("send_dirs")), env)
|
|
26986
|
+
options,
|
|
26987
|
+
...resolveDirectorySettings(options, env, profile)
|
|
26862
26988
|
};
|
|
26863
26989
|
const toolsets = value("toolsets");
|
|
26864
26990
|
if (toolsets) settings.toolsets = checkToolsets(splitList(toolsets.text), toolsets.source, profile.toolsets);
|
|
@@ -26870,10 +26996,6 @@ function parseSettings(argv, env, profile = PROJECT_PROFILE) {
|
|
|
26870
26996
|
if (excluded) settings.exclude_tools = splitList(excluded.text);
|
|
26871
26997
|
const confirm = value("confirm");
|
|
26872
26998
|
if (confirm) settings.confirm = parseConfirm(confirm.text.trim(), confirm.source);
|
|
26873
|
-
for (const name of SERVICE_OPTION_NAMES) {
|
|
26874
|
-
const given = value(name);
|
|
26875
|
-
if (given) settings[name] = parseBoolean(given.text, given.source);
|
|
26876
|
-
}
|
|
26877
26999
|
return settings;
|
|
26878
27000
|
}
|
|
26879
27001
|
function parseToolSettings(argv, env, profile = PROJECT_PROFILE) {
|
|
@@ -26888,48 +27010,11 @@ function parseToolSettings(argv, env, profile = PROJECT_PROFILE) {
|
|
|
26888
27010
|
);
|
|
26889
27011
|
return settings;
|
|
26890
27012
|
}
|
|
26891
|
-
function parseStateDir(argv, env, profile = PROJECT_PROFILE) {
|
|
26892
|
-
const flags = readFlags(argv);
|
|
26893
|
-
const other = Object.keys(flags).find((name) => name !== "state_dir");
|
|
26894
|
-
if (other !== void 0)
|
|
26895
|
-
throw new ToolError("invalid_argument", `Option ${OPTIONS[other].flag} is not available here.`);
|
|
26896
|
-
return resolveStateDir(flagOrEnvText(flags, "state_dir", env, profile), env, profile);
|
|
26897
|
-
}
|
|
26898
|
-
function parseServiceSettings(argv, env, profile = PROJECT_PROFILE) {
|
|
26899
|
-
const flags = readFlags(argv);
|
|
26900
|
-
const allowed = ["state_dir", ...SERVICE_OPTION_NAMES];
|
|
26901
|
-
const other = Object.keys(flags).find((name) => !allowed.includes(name));
|
|
26902
|
-
if (other !== void 0)
|
|
26903
|
-
throw new ToolError("invalid_argument", `Option ${OPTIONS[other].flag} is not available here.`);
|
|
26904
|
-
const value = (name) => flagOrEnvText(flags, name, env, profile);
|
|
26905
|
-
const on = (name) => {
|
|
26906
|
-
const given = value(name);
|
|
26907
|
-
return given !== void 0 && parseBoolean(given.text, given.source);
|
|
26908
|
-
};
|
|
26909
|
-
return {
|
|
26910
|
-
state_dir: resolveStateDir(value("state_dir"), env, profile),
|
|
26911
|
-
keep_disappearing: on("keep_disappearing"),
|
|
26912
|
-
channels: on("channels")
|
|
26913
|
-
};
|
|
26914
|
-
}
|
|
26915
|
-
var TOOL_OPTION_NAMES = [
|
|
26916
|
-
"toolsets",
|
|
26917
|
-
"read_only",
|
|
26918
|
-
"tools",
|
|
26919
|
-
"exclude_tools",
|
|
26920
|
-
"state_dir",
|
|
26921
|
-
"download_dir",
|
|
26922
|
-
"download_max_mb",
|
|
26923
|
-
"send_dirs",
|
|
26924
|
-
...SERVICE_OPTION_NAMES
|
|
26925
|
-
];
|
|
26926
|
-
var LANGUAGE_OPTION = "language";
|
|
26927
|
-
var PLUGIN_OPTION_NAMES = [...TOOL_OPTION_NAMES, LANGUAGE_OPTION];
|
|
26928
27013
|
function languageVariable(profile = PROJECT_PROFILE) {
|
|
26929
27014
|
return `${profile.envPrefix}_LANGUAGE`;
|
|
26930
27015
|
}
|
|
26931
|
-
function nonBlank(
|
|
26932
|
-
const trimmed =
|
|
27016
|
+
function nonBlank(text2) {
|
|
27017
|
+
const trimmed = text2?.trim();
|
|
26933
27018
|
return trimmed === "" ? void 0 : trimmed;
|
|
26934
27019
|
}
|
|
26935
27020
|
function promptLanguage(flag2, env, harness, profile = PROJECT_PROFILE) {
|
|
@@ -26983,20 +27068,20 @@ function checkApiId(apiId) {
|
|
|
26983
27068
|
if (!Number.isSafeInteger(apiId) || apiId <= 0) throw new ToolError("invalid_argument", INVALID_API_ID);
|
|
26984
27069
|
return apiId;
|
|
26985
27070
|
}
|
|
26986
|
-
function parseApiId(
|
|
26987
|
-
const trimmed =
|
|
27071
|
+
function parseApiId(text2) {
|
|
27072
|
+
const trimmed = text2.trim();
|
|
26988
27073
|
if (!API_ID_PATTERN.test(trimmed)) throw new ToolError("invalid_argument", INVALID_API_ID);
|
|
26989
27074
|
return checkApiId(Number(trimmed));
|
|
26990
27075
|
}
|
|
26991
|
-
function parseApiHash(
|
|
26992
|
-
const hash2 =
|
|
27076
|
+
function parseApiHash(text2) {
|
|
27077
|
+
const hash2 = text2.trim().toLowerCase();
|
|
26993
27078
|
if (!API_HASH_PATTERN.test(hash2)) throw new ToolError("invalid_argument", INVALID_API_HASH);
|
|
26994
27079
|
return hash2;
|
|
26995
27080
|
}
|
|
26996
27081
|
function readApp(path) {
|
|
26997
|
-
let
|
|
27082
|
+
let text2;
|
|
26998
27083
|
try {
|
|
26999
|
-
|
|
27084
|
+
text2 = readFileSync3(path, "utf8");
|
|
27000
27085
|
} catch (error62) {
|
|
27001
27086
|
if (error62.code === "ENOENT") {
|
|
27002
27087
|
throw new ToolError("not_found", "This account has no app credentials yet; log in first.");
|
|
@@ -27004,7 +27089,7 @@ function readApp(path) {
|
|
|
27004
27089
|
throw new ToolError("upstream_error", UNREADABLE_APP);
|
|
27005
27090
|
}
|
|
27006
27091
|
try {
|
|
27007
|
-
const parsed = JSON.parse(
|
|
27092
|
+
const parsed = JSON.parse(text2);
|
|
27008
27093
|
if (typeof parsed.api_id !== "number" || typeof parsed.api_hash !== "string") throw new Error("malformed");
|
|
27009
27094
|
return { apiId: checkApiId(parsed.api_id), apiHash: parseApiHash(parsed.api_hash) };
|
|
27010
27095
|
} catch {
|
|
@@ -28792,16 +28877,16 @@ function _isAny2() {
|
|
|
28792
28877
|
}
|
|
28793
28878
|
var LAYER = 232;
|
|
28794
28879
|
var RpcError = class _RpcError extends Error {
|
|
28795
|
-
constructor(code,
|
|
28796
|
-
super("Telegram API error " + code + ": " +
|
|
28880
|
+
constructor(code, text2) {
|
|
28881
|
+
super("Telegram API error " + code + ": " + text2);
|
|
28797
28882
|
this.code = code;
|
|
28798
|
-
this.text =
|
|
28883
|
+
this.text = text2;
|
|
28799
28884
|
}
|
|
28800
|
-
static is(err,
|
|
28801
|
-
return err != null && err.constructor === _RpcError && (!
|
|
28885
|
+
static is(err, text2) {
|
|
28886
|
+
return err != null && err.constructor === _RpcError && (!text2 || err.text === text2);
|
|
28802
28887
|
}
|
|
28803
|
-
is(
|
|
28804
|
-
return this.text ===
|
|
28888
|
+
is(text2) {
|
|
28889
|
+
return this.text === text2;
|
|
28805
28890
|
}
|
|
28806
28891
|
};
|
|
28807
28892
|
RpcError.fromTl = function(obj) {
|
|
@@ -30268,8 +30353,8 @@ var AsyncLock = class {
|
|
|
30268
30353
|
this._locked = true;
|
|
30269
30354
|
return new AsyncLockGuard(this._release);
|
|
30270
30355
|
}
|
|
30271
|
-
return new Promise((
|
|
30272
|
-
this._waiters.pushBack(
|
|
30356
|
+
return new Promise((resolve6) => {
|
|
30357
|
+
this._waiters.pushBack(resolve6);
|
|
30273
30358
|
});
|
|
30274
30359
|
}
|
|
30275
30360
|
async with(func) {
|
|
@@ -30479,8 +30564,8 @@ var ConditionVariable = class {
|
|
|
30479
30564
|
if (this.#promise) {
|
|
30480
30565
|
return this.#promise;
|
|
30481
30566
|
}
|
|
30482
|
-
return this.#promise = new Promise((
|
|
30483
|
-
this.#notify =
|
|
30567
|
+
return this.#promise = new Promise((resolve6) => {
|
|
30568
|
+
this.#notify = resolve6;
|
|
30484
30569
|
});
|
|
30485
30570
|
}
|
|
30486
30571
|
notify() {
|
|
@@ -32111,7 +32196,7 @@ function makeInspectable(obj, props, hide2) {
|
|
|
32111
32196
|
|
|
32112
32197
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/utils/misc-utils.js
|
|
32113
32198
|
function sleepWithAbort(ms, signal) {
|
|
32114
|
-
return new Promise((
|
|
32199
|
+
return new Promise((resolve6, reject) => {
|
|
32115
32200
|
let timeout;
|
|
32116
32201
|
const onAbort2 = () => {
|
|
32117
32202
|
timers_exports.clearTimeout(timeout);
|
|
@@ -32120,7 +32205,7 @@ function sleepWithAbort(ms, signal) {
|
|
|
32120
32205
|
signal.addEventListener("abort", onAbort2);
|
|
32121
32206
|
timeout = timers_exports.setTimeout(() => {
|
|
32122
32207
|
signal.removeEventListener("abort", onAbort2);
|
|
32123
|
-
|
|
32208
|
+
resolve6();
|
|
32124
32209
|
}, ms);
|
|
32125
32210
|
});
|
|
32126
32211
|
}
|
|
@@ -34113,19 +34198,19 @@ var User = class _User {
|
|
|
34113
34198
|
* msg.replyText(html`Hello, ${msg.sender.mention()`)
|
|
34114
34199
|
* ```
|
|
34115
34200
|
*/
|
|
34116
|
-
mention(
|
|
34117
|
-
if (
|
|
34201
|
+
mention(text2) {
|
|
34202
|
+
if (text2 === void 0 && this.username) {
|
|
34118
34203
|
return `@${this.username}`;
|
|
34119
34204
|
}
|
|
34120
|
-
if (!
|
|
34205
|
+
if (!text2) text2 = this.displayName;
|
|
34121
34206
|
return new MessageEntity$2(
|
|
34122
34207
|
{
|
|
34123
34208
|
_: "messageEntityMentionName",
|
|
34124
34209
|
offset: 0,
|
|
34125
|
-
length:
|
|
34210
|
+
length: text2.length,
|
|
34126
34211
|
userId: this.raw.id
|
|
34127
34212
|
},
|
|
34128
|
-
|
|
34213
|
+
text2
|
|
34129
34214
|
);
|
|
34130
34215
|
}
|
|
34131
34216
|
/**
|
|
@@ -34165,19 +34250,19 @@ var User = class _User {
|
|
|
34165
34250
|
*
|
|
34166
34251
|
* @param text Mention text
|
|
34167
34252
|
*/
|
|
34168
|
-
permanentMention(
|
|
34253
|
+
permanentMention(text2) {
|
|
34169
34254
|
if (!this.raw.accessHash) {
|
|
34170
34255
|
throw new MtArgumentError("User's access hash is not available!");
|
|
34171
34256
|
}
|
|
34172
|
-
if (!
|
|
34257
|
+
if (!text2) text2 = this.displayName;
|
|
34173
34258
|
return new MessageEntity$2(
|
|
34174
34259
|
{
|
|
34175
34260
|
_: "messageEntityTextUrl",
|
|
34176
34261
|
offset: 0,
|
|
34177
|
-
length:
|
|
34262
|
+
length: text2.length,
|
|
34178
34263
|
url: `tg://user?id=${this.id}&hash=${this.raw.accessHash.toString(16)}`
|
|
34179
34264
|
},
|
|
34180
|
-
|
|
34265
|
+
text2
|
|
34181
34266
|
);
|
|
34182
34267
|
}
|
|
34183
34268
|
};
|
|
@@ -34238,10 +34323,10 @@ var GameHighScore$1 = /* @__PURE__ */ memoizeGetters(GameHighScore, ["user"]);
|
|
|
34238
34323
|
var GameHighScore$2 = /* @__PURE__ */ makeInspectable(GameHighScore$1);
|
|
34239
34324
|
|
|
34240
34325
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/utils/walk-page-blocks.js
|
|
34241
|
-
function walkRichText(
|
|
34242
|
-
if (!
|
|
34243
|
-
visitor.richText?.(
|
|
34244
|
-
switch (
|
|
34326
|
+
function walkRichText(text2, visitor) {
|
|
34327
|
+
if (!text2) return;
|
|
34328
|
+
visitor.richText?.(text2);
|
|
34329
|
+
switch (text2._) {
|
|
34245
34330
|
case "textEmpty":
|
|
34246
34331
|
case "textPlain":
|
|
34247
34332
|
case "textEmail":
|
|
@@ -34273,14 +34358,14 @@ function walkRichText(text, visitor) {
|
|
|
34273
34358
|
case "textDate":
|
|
34274
34359
|
case "textMentionName":
|
|
34275
34360
|
case "textButton":
|
|
34276
|
-
walkRichText(
|
|
34361
|
+
walkRichText(text2.text, visitor);
|
|
34277
34362
|
break;
|
|
34278
34363
|
case "textConcat":
|
|
34279
|
-
for (const child of
|
|
34364
|
+
for (const child of text2.texts) walkRichText(child, visitor);
|
|
34280
34365
|
break;
|
|
34281
34366
|
case "textDiff":
|
|
34282
|
-
walkRichText(
|
|
34283
|
-
walkRichText(
|
|
34367
|
+
walkRichText(text2.text, visitor);
|
|
34368
|
+
walkRichText(text2.oldText, visitor);
|
|
34284
34369
|
break;
|
|
34285
34370
|
default:
|
|
34286
34371
|
assertNever2();
|
|
@@ -34410,11 +34495,11 @@ function isUploadedFile(obj) {
|
|
|
34410
34495
|
}
|
|
34411
34496
|
|
|
34412
34497
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/types/misc/entities.js
|
|
34413
|
-
function inputTextToTl(
|
|
34498
|
+
function inputTextToTl(text2) {
|
|
34414
34499
|
return {
|
|
34415
34500
|
_: "textWithEntities",
|
|
34416
|
-
text: typeof
|
|
34417
|
-
entities: typeof
|
|
34501
|
+
text: typeof text2 === "string" ? text2 : text2.text,
|
|
34502
|
+
entities: typeof text2 === "string" ? [] : text2.entities ?? []
|
|
34418
34503
|
};
|
|
34419
34504
|
}
|
|
34420
34505
|
|
|
@@ -34708,8 +34793,8 @@ function batchedQuery(params) {
|
|
|
34708
34793
|
arr = [];
|
|
34709
34794
|
waiters.set(key, arr);
|
|
34710
34795
|
}
|
|
34711
|
-
return new Promise((
|
|
34712
|
-
arr.push([item,
|
|
34796
|
+
return new Promise((resolve6, reject) => {
|
|
34797
|
+
arr.push([item, resolve6, reject]);
|
|
34713
34798
|
});
|
|
34714
34799
|
}
|
|
34715
34800
|
function popWaiters(waiters, key) {
|
|
@@ -35131,9 +35216,9 @@ async function _normalizeInputText(client, input8) {
|
|
|
35131
35216
|
if (typeof input8 === "string") {
|
|
35132
35217
|
return [input8, void 0];
|
|
35133
35218
|
}
|
|
35134
|
-
let
|
|
35219
|
+
let text2 = input8.text;
|
|
35135
35220
|
const entities = input8.entities;
|
|
35136
|
-
if (!entities) return [
|
|
35221
|
+
if (!entities) return [text2, void 0];
|
|
35137
35222
|
let canTrimStart = true;
|
|
35138
35223
|
for (const ent of entities) {
|
|
35139
35224
|
if (ent._ === "messageEntityMentionName") {
|
|
@@ -35151,17 +35236,17 @@ async function _normalizeInputText(client, input8) {
|
|
|
35151
35236
|
}
|
|
35152
35237
|
}
|
|
35153
35238
|
if (canTrimStart) {
|
|
35154
|
-
const resultTrimmed =
|
|
35155
|
-
const numCharsTrimmed =
|
|
35156
|
-
|
|
35239
|
+
const resultTrimmed = text2.trimStart();
|
|
35240
|
+
const numCharsTrimmed = text2.length - resultTrimmed.length;
|
|
35241
|
+
text2 = resultTrimmed;
|
|
35157
35242
|
adjustOffsets(entities, 0, -numCharsTrimmed);
|
|
35158
35243
|
}
|
|
35159
|
-
|
|
35244
|
+
text2 = text2.trimEnd();
|
|
35160
35245
|
for (const ent of entities) {
|
|
35161
35246
|
const end = ent.offset + ent.length;
|
|
35162
|
-
if (end >
|
|
35247
|
+
if (end > text2.length) ent.length = text2.length - ent.offset;
|
|
35163
35248
|
}
|
|
35164
|
-
return [
|
|
35249
|
+
return [text2, entities];
|
|
35165
35250
|
}
|
|
35166
35251
|
|
|
35167
35252
|
// node_modules/.pnpm/@fuman+io@0.0.23/node_modules/@fuman/io/read/index.js
|
|
@@ -37094,8 +37179,8 @@ async function _normalizeInputRichMessage(client, peer, input8, params) {
|
|
|
37094
37179
|
const blocks = input8.blocks.map(processBlock);
|
|
37095
37180
|
const mentionIds = /* @__PURE__ */ new Set();
|
|
37096
37181
|
walkPageBlocks(blocks, {
|
|
37097
|
-
richText: (
|
|
37098
|
-
if (
|
|
37182
|
+
richText: (text2) => {
|
|
37183
|
+
if (text2._ === "textMentionName") mentionIds.add(text2.userId);
|
|
37099
37184
|
}
|
|
37100
37185
|
});
|
|
37101
37186
|
const users = mentionIds.size ? await resolvePeerMany(client, [...mentionIds], toInputUser) : void 0;
|
|
@@ -38366,20 +38451,20 @@ var Chat = class {
|
|
|
38366
38451
|
* msg.replyText(html`Hello, ${msg.chat.mention()`)
|
|
38367
38452
|
* ```
|
|
38368
38453
|
*/
|
|
38369
|
-
mention(
|
|
38370
|
-
if (
|
|
38454
|
+
mention(text2) {
|
|
38455
|
+
if (text2 === void 0 && this.username) {
|
|
38371
38456
|
return `@${this.username}`;
|
|
38372
38457
|
}
|
|
38373
|
-
if (!
|
|
38374
|
-
if (!this.username) return
|
|
38458
|
+
if (!text2) text2 = this.displayName;
|
|
38459
|
+
if (!this.username) return text2;
|
|
38375
38460
|
return new MessageEntity$2(
|
|
38376
38461
|
{
|
|
38377
38462
|
_: "messageEntityTextUrl",
|
|
38378
38463
|
offset: 0,
|
|
38379
|
-
length:
|
|
38464
|
+
length: text2.length,
|
|
38380
38465
|
url: `https://t.me/${this.username}`
|
|
38381
38466
|
},
|
|
38382
|
-
|
|
38467
|
+
text2
|
|
38383
38468
|
);
|
|
38384
38469
|
}
|
|
38385
38470
|
};
|
|
@@ -44034,9 +44119,9 @@ function _inputReplyToToHeader(replyTo2, peer) {
|
|
|
44034
44119
|
];
|
|
44035
44120
|
}
|
|
44036
44121
|
}
|
|
44037
|
-
async function sendText(client, chatId,
|
|
44122
|
+
async function sendText(client, chatId, text2, params) {
|
|
44038
44123
|
if (!params) params = {};
|
|
44039
|
-
const [message2, entities] = await _normalizeInputText(client,
|
|
44124
|
+
const [message2, entities] = await _normalizeInputText(client, text2);
|
|
44040
44125
|
const replyMarkup = _convertToTl(params.replyMarkup);
|
|
44041
44126
|
const { peer, replyTo: replyTo2, scheduleDate, chainId, quickReplyShortcut } = await _processCommonSendParameters(
|
|
44042
44127
|
client,
|
|
@@ -49520,8 +49605,8 @@ var UPDATES_TOO_LONG = { _: "updatesTooLong" };
|
|
|
49520
49605
|
function collectRichMessagePeerIds(richMessage, peers) {
|
|
49521
49606
|
if (!richMessage) return;
|
|
49522
49607
|
walkPageBlocks(richMessage.blocks, {
|
|
49523
|
-
richText: (
|
|
49524
|
-
if (
|
|
49608
|
+
richText: (text2) => {
|
|
49609
|
+
if (text2._ === "textMentionName") peers.add(text2.userId);
|
|
49525
49610
|
}
|
|
49526
49611
|
});
|
|
49527
49612
|
}
|
|
@@ -79932,10 +80017,10 @@ var ConnectionFloodController = class {
|
|
|
79932
80017
|
const delay = wakeup - now;
|
|
79933
80018
|
this._log?.debug("connect throttled (waiting %dms)", Math.round(delay));
|
|
79934
80019
|
waited = true;
|
|
79935
|
-
await new Promise((
|
|
80020
|
+
await new Promise((resolve6, reject) => {
|
|
79936
80021
|
const handle = timers_exports.setTimeout(() => {
|
|
79937
80022
|
signal?.removeEventListener("abort", onAbort2);
|
|
79938
|
-
|
|
80023
|
+
resolve6();
|
|
79939
80024
|
}, delay);
|
|
79940
80025
|
const onAbort2 = () => {
|
|
79941
80026
|
timers_exports.clearTimeout(handle);
|
|
@@ -83913,8 +83998,8 @@ function rpcTextOf(error62) {
|
|
|
83913
83998
|
return inner_tl_exports.RpcError.is(error62) ? String(error62.text) : void 0;
|
|
83914
83999
|
}
|
|
83915
84000
|
function isSessionEnded(error62) {
|
|
83916
|
-
const
|
|
83917
|
-
return
|
|
84001
|
+
const text2 = rpcTextOf(error62);
|
|
84002
|
+
return text2 !== void 0 && SESSION_ENDED_ERRORS.includes(text2);
|
|
83918
84003
|
}
|
|
83919
84004
|
function floodWaitSecondsOf(error62) {
|
|
83920
84005
|
if (!inner_tl_exports.RpcError.is(error62)) return void 0;
|
|
@@ -83938,18 +84023,18 @@ var PHONE_REASONS = {
|
|
|
83938
84023
|
function loginError(error62) {
|
|
83939
84024
|
if (error62 instanceof ToolError || isAbortError(error62)) return error62;
|
|
83940
84025
|
if (!inner_tl_exports.RpcError.is(error62)) return error62;
|
|
83941
|
-
const
|
|
84026
|
+
const text2 = String(error62.text);
|
|
83942
84027
|
const seconds = floodWaitSecondsOf(error62);
|
|
83943
84028
|
if (seconds !== void 0 || error62.code === inner_tl_exports.RpcError.FLOOD) {
|
|
83944
84029
|
const wait = seconds === void 0 ? "a while" : `${seconds} seconds`;
|
|
83945
84030
|
return new ToolError("rate_limited", `Telegram asks to wait ${wait} before logging in again.`);
|
|
83946
84031
|
}
|
|
83947
|
-
if (
|
|
84032
|
+
if (text2 === "PHONE_CODE_EXPIRED") {
|
|
83948
84033
|
return new ToolError("invalid_argument", "The code expired; log in again.");
|
|
83949
84034
|
}
|
|
83950
|
-
const reason = PHONE_REASONS[
|
|
84035
|
+
const reason = PHONE_REASONS[text2];
|
|
83951
84036
|
if (reason) return new ToolError("invalid_argument", reason);
|
|
83952
|
-
return new ToolError("upstream_error", `Telegram refused the login (${
|
|
84037
|
+
return new ToolError("upstream_error", `Telegram refused the login (${text2}).`);
|
|
83953
84038
|
}
|
|
83954
84039
|
async function guarded(run) {
|
|
83955
84040
|
try {
|
|
@@ -83966,8 +84051,8 @@ async function isLoggedIn(client) {
|
|
|
83966
84051
|
await client.getMe();
|
|
83967
84052
|
return true;
|
|
83968
84053
|
} catch (error62) {
|
|
83969
|
-
const
|
|
83970
|
-
if (
|
|
84054
|
+
const text2 = rpcTextOf(error62);
|
|
84055
|
+
if (text2 === "AUTH_KEY_UNREGISTERED" || text2 === "SESSION_PASSWORD_NEEDED") return false;
|
|
83971
84056
|
throw loginError(error62);
|
|
83972
84057
|
}
|
|
83973
84058
|
}
|
|
@@ -84007,9 +84092,9 @@ async function signInWithCode(client, io, phone, phoneCodeHash) {
|
|
|
84007
84092
|
try {
|
|
84008
84093
|
return await client.signIn({ phone, phoneCodeHash, phoneCode, abortSignal: io.signal });
|
|
84009
84094
|
} catch (error62) {
|
|
84010
|
-
const
|
|
84011
|
-
if (
|
|
84012
|
-
if (
|
|
84095
|
+
const text2 = rpcTextOf(error62);
|
|
84096
|
+
if (text2 === "SESSION_PASSWORD_NEEDED") return checkTwoStepPassword(client, io);
|
|
84097
|
+
if (text2 !== "PHONE_CODE_INVALID") throw error62;
|
|
84013
84098
|
io.say("That code is not right.");
|
|
84014
84099
|
}
|
|
84015
84100
|
}
|
|
@@ -84081,6 +84166,26 @@ async function logoutLabel(options) {
|
|
|
84081
84166
|
}
|
|
84082
84167
|
}
|
|
84083
84168
|
|
|
84169
|
+
// src/entry/command-settings.ts
|
|
84170
|
+
var SERVICE_BOOLEANS = ["keep_disappearing", "channels"];
|
|
84171
|
+
var STATE_DIR = "state_dir";
|
|
84172
|
+
function onlyOptions(profile, names) {
|
|
84173
|
+
const declared = Object.entries(profile.options ?? {}).filter(([name]) => names.includes(name));
|
|
84174
|
+
return { ...profile, options: Object.fromEntries(declared) };
|
|
84175
|
+
}
|
|
84176
|
+
function parseStateDir(argv, env, profile = PROJECT_PROFILE) {
|
|
84177
|
+
const options = parseToolOptions(argv, env, onlyOptions(profile, [STATE_DIR]));
|
|
84178
|
+
return resolveDirectorySettings(options, env, profile).state_dir;
|
|
84179
|
+
}
|
|
84180
|
+
function parseServiceSettings(argv, env, profile = PROJECT_PROFILE) {
|
|
84181
|
+
const options = parseToolOptions(argv, env, onlyOptions(profile, [STATE_DIR, ...SERVICE_BOOLEANS]));
|
|
84182
|
+
return {
|
|
84183
|
+
state_dir: resolveDirectorySettings(options, env, profile).state_dir,
|
|
84184
|
+
keep_disappearing: options.keep_disappearing === true,
|
|
84185
|
+
channels: options.channels === true
|
|
84186
|
+
};
|
|
84187
|
+
}
|
|
84188
|
+
|
|
84084
84189
|
// src/cli/command-args.ts
|
|
84085
84190
|
function usageError(message2) {
|
|
84086
84191
|
return new ToolError("invalid_argument", message2);
|
|
@@ -84606,35 +84711,35 @@ function makeNumeric(digits) {
|
|
|
84606
84711
|
}
|
|
84607
84712
|
return new QrSegment(MODE_NUMERIC, digits.length, bb);
|
|
84608
84713
|
}
|
|
84609
|
-
function makeAlphanumeric(
|
|
84610
|
-
if (!isAlphanumeric(
|
|
84714
|
+
function makeAlphanumeric(text2) {
|
|
84715
|
+
if (!isAlphanumeric(text2))
|
|
84611
84716
|
throw new RangeError("String contains unencodable characters in alphanumeric mode");
|
|
84612
84717
|
const bb = [];
|
|
84613
84718
|
let i;
|
|
84614
|
-
for (i = 0; i + 2 <=
|
|
84615
|
-
let temp = ALPHANUMERIC_CHARSET.indexOf(
|
|
84616
|
-
temp += ALPHANUMERIC_CHARSET.indexOf(
|
|
84719
|
+
for (i = 0; i + 2 <= text2.length; i += 2) {
|
|
84720
|
+
let temp = ALPHANUMERIC_CHARSET.indexOf(text2.charAt(i)) * 45;
|
|
84721
|
+
temp += ALPHANUMERIC_CHARSET.indexOf(text2.charAt(i + 1));
|
|
84617
84722
|
appendBits(temp, 11, bb);
|
|
84618
84723
|
}
|
|
84619
|
-
if (i <
|
|
84620
|
-
appendBits(ALPHANUMERIC_CHARSET.indexOf(
|
|
84621
|
-
return new QrSegment(MODE_ALPHANUMERIC,
|
|
84724
|
+
if (i < text2.length)
|
|
84725
|
+
appendBits(ALPHANUMERIC_CHARSET.indexOf(text2.charAt(i)), 6, bb);
|
|
84726
|
+
return new QrSegment(MODE_ALPHANUMERIC, text2.length, bb);
|
|
84622
84727
|
}
|
|
84623
|
-
function makeSegments(
|
|
84624
|
-
if (
|
|
84728
|
+
function makeSegments(text2) {
|
|
84729
|
+
if (text2 === "")
|
|
84625
84730
|
return [];
|
|
84626
|
-
else if (isNumeric(
|
|
84627
|
-
return [makeNumeric(
|
|
84628
|
-
else if (isAlphanumeric(
|
|
84629
|
-
return [makeAlphanumeric(
|
|
84731
|
+
else if (isNumeric(text2))
|
|
84732
|
+
return [makeNumeric(text2)];
|
|
84733
|
+
else if (isAlphanumeric(text2))
|
|
84734
|
+
return [makeAlphanumeric(text2)];
|
|
84630
84735
|
else
|
|
84631
|
-
return [makeBytes(toUtf8ByteArray(
|
|
84736
|
+
return [makeBytes(toUtf8ByteArray(text2))];
|
|
84632
84737
|
}
|
|
84633
|
-
function isNumeric(
|
|
84634
|
-
return NUMERIC_REGEX.test(
|
|
84738
|
+
function isNumeric(text2) {
|
|
84739
|
+
return NUMERIC_REGEX.test(text2);
|
|
84635
84740
|
}
|
|
84636
|
-
function isAlphanumeric(
|
|
84637
|
-
return ALPHANUMERIC_REGEX.test(
|
|
84741
|
+
function isAlphanumeric(text2) {
|
|
84742
|
+
return ALPHANUMERIC_REGEX.test(text2);
|
|
84638
84743
|
}
|
|
84639
84744
|
function getTotalBits(segs, version3) {
|
|
84640
84745
|
let result = 0;
|
|
@@ -84820,8 +84925,8 @@ function cell(top, bottom) {
|
|
|
84820
84925
|
const background = bottom === true ? DARK : LIGHT;
|
|
84821
84926
|
return `\x1B[38;5;${foreground}m\x1B[48;5;${background}m${HALF_BLOCK}`;
|
|
84822
84927
|
}
|
|
84823
|
-
function drawQr(
|
|
84824
|
-
const modules = encode5(
|
|
84928
|
+
function drawQr(text2) {
|
|
84929
|
+
const modules = encode5(text2, { border: QR_QUIET_ZONE }).data;
|
|
84825
84930
|
const lines = [];
|
|
84826
84931
|
for (let row = 0; row < modules.length; row += 2) {
|
|
84827
84932
|
const upper = modules[row] ?? [];
|
|
@@ -85707,13 +85812,13 @@ async function answerBotGuestChatQuery(client, queryId, result) {
|
|
|
85707
85812
|
|
|
85708
85813
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/methods/bots/answer-callback-query.js
|
|
85709
85814
|
async function answerCallbackQuery(client, queryId, params) {
|
|
85710
|
-
const { cacheTime = 0, text, alert, url: url2 } = params ?? {};
|
|
85815
|
+
const { cacheTime = 0, text: text2, alert, url: url2 } = params ?? {};
|
|
85711
85816
|
const r = await client.call({
|
|
85712
85817
|
_: "messages.setBotCallbackAnswer",
|
|
85713
85818
|
queryId: long_default.isLong(queryId) ? queryId : queryId.id,
|
|
85714
85819
|
cacheTime,
|
|
85715
85820
|
alert,
|
|
85716
|
-
message:
|
|
85821
|
+
message: text2,
|
|
85717
85822
|
url: url2
|
|
85718
85823
|
});
|
|
85719
85824
|
assertTrue("messages.setBotCallbackAnswer", r);
|
|
@@ -88171,11 +88276,11 @@ function _findEphemeralMessageInUpdate(client, res, isEdit = false, noDispatch =
|
|
|
88171
88276
|
|
|
88172
88277
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/methods/ephemeral/edit-ephemeral-message.js
|
|
88173
88278
|
async function editEphemeralMessage(client, params) {
|
|
88174
|
-
const { chatId, receiverId, messageId, text, media, richMessage, replyMarkup, shouldDispatch, uploadCache } = params;
|
|
88279
|
+
const { chatId, receiverId, messageId, text: text2, media, richMessage, replyMarkup, shouldDispatch, uploadCache } = params;
|
|
88175
88280
|
let message2;
|
|
88176
88281
|
let entities;
|
|
88177
|
-
if (
|
|
88178
|
-
[message2, entities] = await _normalizeInputText(client,
|
|
88282
|
+
if (text2 !== void 0) {
|
|
88283
|
+
[message2, entities] = await _normalizeInputText(client, text2);
|
|
88179
88284
|
}
|
|
88180
88285
|
const peer = chatId !== null ? await resolvePeer(client, chatId) : void 0;
|
|
88181
88286
|
if (richMessage && !peer) {
|
|
@@ -88239,9 +88344,9 @@ async function getWelcomeMessages(client, chatId) {
|
|
|
88239
88344
|
}
|
|
88240
88345
|
|
|
88241
88346
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/methods/ephemeral/send-ephemeral-message.js
|
|
88242
|
-
async function sendEphemeralMessage(client, chatId, receiverId,
|
|
88347
|
+
async function sendEphemeralMessage(client, chatId, receiverId, text2, params) {
|
|
88243
88348
|
const { media, richMessage, replyTo: replyTo2, replyToEphemeral, queryId, shouldDispatch, uploadCache } = params ?? {};
|
|
88244
|
-
const [message2, entities] = await _normalizeInputText(client,
|
|
88349
|
+
const [message2, entities] = await _normalizeInputText(client, text2);
|
|
88245
88350
|
const peer = chatId !== null ? await resolvePeer(client, chatId) : void 0;
|
|
88246
88351
|
if (richMessage && !peer) {
|
|
88247
88352
|
throw new MtArgumentError("richMessage requires chatId to be passed");
|
|
@@ -88287,8 +88392,8 @@ var DownloadDelayGate = class {
|
|
|
88287
88392
|
const ms = at2 - now;
|
|
88288
88393
|
if (ms <= 0) return Promise.resolve();
|
|
88289
88394
|
if (signal) return sleepWithAbort(ms, signal);
|
|
88290
|
-
return new Promise((
|
|
88291
|
-
timers_exports.setTimeout(
|
|
88395
|
+
return new Promise((resolve6) => {
|
|
88396
|
+
timers_exports.setTimeout(resolve6, ms);
|
|
88292
88397
|
});
|
|
88293
88398
|
}
|
|
88294
88399
|
};
|
|
@@ -89740,16 +89845,16 @@ async function createStreamingDraft(client, chatId, params) {
|
|
|
89740
89845
|
const peer = await resolvePeer(client, chatId);
|
|
89741
89846
|
const stopListener = canStop ? _listenForDraftStop(client, randomId) : void 0;
|
|
89742
89847
|
let previousText;
|
|
89743
|
-
const sendDraft = async (
|
|
89848
|
+
const sendDraft = async (text2) => {
|
|
89744
89849
|
if (stopListener?.signal.aborted) return;
|
|
89745
|
-
if (typeof
|
|
89746
|
-
|
|
89850
|
+
if (typeof text2 === "string") {
|
|
89851
|
+
text2 = { text: text2 };
|
|
89747
89852
|
}
|
|
89748
89853
|
if (mode === "append" && previousText) {
|
|
89749
|
-
|
|
89854
|
+
text2 = joinTextWithEntities([previousText, text2]);
|
|
89750
89855
|
}
|
|
89751
|
-
previousText =
|
|
89752
|
-
const [_text, entities = []] = await _normalizeInputText(client,
|
|
89856
|
+
previousText = text2;
|
|
89857
|
+
const [_text, entities = []] = await _normalizeInputText(client, text2);
|
|
89753
89858
|
if (stopListener?.signal.aborted) return;
|
|
89754
89859
|
const r = await client.call({
|
|
89755
89860
|
_: "messages.setTyping",
|
|
@@ -90378,8 +90483,8 @@ async function getUnreadPollVotes(client, chatId, params) {
|
|
|
90378
90483
|
}
|
|
90379
90484
|
|
|
90380
90485
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/methods/messages/get-web-page-preview.js
|
|
90381
|
-
async function getWebPagePreview(client,
|
|
90382
|
-
const [message2, entities] = await _normalizeInputText(client,
|
|
90486
|
+
async function getWebPagePreview(client, text2) {
|
|
90487
|
+
const [message2, entities] = await _normalizeInputText(client, text2);
|
|
90383
90488
|
const res = await client.call({
|
|
90384
90489
|
_: "messages.getWebPagePreview",
|
|
90385
90490
|
message: message2,
|
|
@@ -90766,9 +90871,9 @@ function answerText(client, message2, ...params) {
|
|
|
90766
90871
|
if (!message2.isTopicMessage || !message2.replyToMessage?.threadId) {
|
|
90767
90872
|
return sendText(client, message2.chat.inputPeer, ...params);
|
|
90768
90873
|
}
|
|
90769
|
-
const [
|
|
90874
|
+
const [text2, params_ = {}] = params;
|
|
90770
90875
|
params_.replyTo = message2.replyToMessage.threadId;
|
|
90771
|
-
return sendText(client, message2.chat.inputPeer,
|
|
90876
|
+
return sendText(client, message2.chat.inputPeer, text2, params_);
|
|
90772
90877
|
}
|
|
90773
90878
|
function answerMedia(client, message2, ...params) {
|
|
90774
90879
|
if (!message2.isTopicMessage || !message2.replyToMessage?.threadId) {
|
|
@@ -90789,11 +90894,11 @@ function answerMediaGroup(client, message2, ...params) {
|
|
|
90789
90894
|
|
|
90790
90895
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/methods/messages/send-reply.js
|
|
90791
90896
|
function replyText(client, message2, ...params) {
|
|
90792
|
-
const [
|
|
90897
|
+
const [text2, params_ = {}] = params;
|
|
90793
90898
|
params_.replyTo = message2.id;
|
|
90794
90899
|
const threadId = message2.replyToMessage?.threadId;
|
|
90795
90900
|
if (threadId) params_.threadId = threadId;
|
|
90796
|
-
return sendText(client, message2.chat.inputPeer,
|
|
90901
|
+
return sendText(client, message2.chat.inputPeer, text2, params_);
|
|
90797
90902
|
}
|
|
90798
90903
|
function replyMedia(client, message2, ...params) {
|
|
90799
90904
|
const [media, params_ = {}] = params;
|
|
@@ -90818,9 +90923,9 @@ function commentText(client, message2, ...params) {
|
|
|
90818
90923
|
if (!message2.replies || !message2.replies.hasComments) {
|
|
90819
90924
|
throw new MtArgumentError("This message does not have comments section");
|
|
90820
90925
|
}
|
|
90821
|
-
const [
|
|
90926
|
+
const [text2, params_ = {}] = params;
|
|
90822
90927
|
params_.commentTo = message2.id;
|
|
90823
|
-
return sendText(client, message2.chat.inputPeer,
|
|
90928
|
+
return sendText(client, message2.chat.inputPeer, text2, params_);
|
|
90824
90929
|
}
|
|
90825
90930
|
function commentMedia(client, message2, ...params) {
|
|
90826
90931
|
if (message2.chat.type !== "chat" || message2.chat.chatType !== "channel") {
|
|
@@ -90960,11 +91065,11 @@ function extractQuote(message2, from, to) {
|
|
|
90960
91065
|
const { raw } = message2;
|
|
90961
91066
|
if (raw._ === "messageService") throw new MtArgumentError("Cannot quote service message");
|
|
90962
91067
|
if (!raw.message) throw new MtArgumentError("Cannot quote empty message");
|
|
90963
|
-
const
|
|
91068
|
+
const text2 = raw.message;
|
|
90964
91069
|
if (from < 0) from = 0;
|
|
90965
|
-
if (to >
|
|
91070
|
+
if (to > text2.length) to = text2.length;
|
|
90966
91071
|
if (from >= to) throw new MtArgumentError("Invalid quote range");
|
|
90967
|
-
if (!raw.entities) return { text:
|
|
91072
|
+
if (!raw.entities) return { text: text2.slice(from, to), entities: void 0 };
|
|
90968
91073
|
const entities = [];
|
|
90969
91074
|
for (const ent of raw.entities) {
|
|
90970
91075
|
const start3 = ent.offset;
|
|
@@ -90975,15 +91080,15 @@ function extractQuote(message2, from, to) {
|
|
|
90975
91080
|
const newEnt = { ...ent, offset: newStart, length: newEnd - newStart };
|
|
90976
91081
|
entities.push(newEnt);
|
|
90977
91082
|
}
|
|
90978
|
-
return { text:
|
|
91083
|
+
return { text: text2.slice(from, to), entities };
|
|
90979
91084
|
}
|
|
90980
91085
|
function quoteWithText(client, message2, params) {
|
|
90981
|
-
const { toChatId = message2.chat, start: start3, end, text, ...params__ } = params;
|
|
91086
|
+
const { toChatId = message2.chat, start: start3, end, text: text2, ...params__ } = params;
|
|
90982
91087
|
const params_ = params__;
|
|
90983
91088
|
params_.replyTo = message2;
|
|
90984
91089
|
params_.quote = extractQuote(message2, params.start, params.end);
|
|
90985
91090
|
params_.quoteOffset = params.start;
|
|
90986
|
-
return sendText(client, toChatId,
|
|
91091
|
+
return sendText(client, toChatId, text2, params_);
|
|
90987
91092
|
}
|
|
90988
91093
|
function quoteWithMedia(client, message2, params) {
|
|
90989
91094
|
const { toChatId = message2.chat, start: start3, end, media, ...params__ } = params;
|
|
@@ -91176,8 +91281,8 @@ async function translateMessage(client, params) {
|
|
|
91176
91281
|
}
|
|
91177
91282
|
|
|
91178
91283
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/methods/messages/translate-text.js
|
|
91179
|
-
async function translateText(client,
|
|
91180
|
-
const [message2, entities] = await _normalizeInputText(client,
|
|
91284
|
+
async function translateText(client, text2, toLanguage, params) {
|
|
91285
|
+
const [message2, entities] = await _normalizeInputText(client, text2);
|
|
91181
91286
|
const res = await client.call({
|
|
91182
91287
|
_: "messages.translateText",
|
|
91183
91288
|
text: [
|
|
@@ -91431,8 +91536,8 @@ async function canApplyBoost(client) {
|
|
|
91431
91536
|
}
|
|
91432
91537
|
|
|
91433
91538
|
// node_modules/.pnpm/@mtcute+core@0.32.7/node_modules/@mtcute/core/highlevel/methods/premium/create-business-chat-link.js
|
|
91434
|
-
async function createBusinessChatLink(client,
|
|
91435
|
-
const [message2, entities] = await _normalizeInputText(client,
|
|
91539
|
+
async function createBusinessChatLink(client, text2, params) {
|
|
91540
|
+
const [message2, entities] = await _normalizeInputText(client, text2);
|
|
91436
91541
|
const res = await client.call({
|
|
91437
91542
|
_: "account.createBusinessChatLink",
|
|
91438
91543
|
link: {
|
|
@@ -94089,10 +94194,10 @@ var NodeSocketConnection = class {
|
|
|
94089
94194
|
}
|
|
94090
94195
|
async write(bytes2) {
|
|
94091
94196
|
if (this.#error) throw this.#error;
|
|
94092
|
-
return new Promise((
|
|
94197
|
+
return new Promise((resolve6, reject) => {
|
|
94093
94198
|
this.socket.write(bytes2, (error62) => {
|
|
94094
94199
|
if (error62) reject(error62);
|
|
94095
|
-
else
|
|
94200
|
+
else resolve6();
|
|
94096
94201
|
});
|
|
94097
94202
|
});
|
|
94098
94203
|
}
|
|
@@ -94121,14 +94226,14 @@ var TcpConnection = class extends NodeSocketConnection {
|
|
|
94121
94226
|
// node_modules/.pnpm/@fuman+node@0.0.23/node_modules/@fuman/node/net/functions.js
|
|
94122
94227
|
import { Socket as Socket2, Server } from "node:net";
|
|
94123
94228
|
function awaitConnect(socket, signal) {
|
|
94124
|
-
return new Promise((
|
|
94229
|
+
return new Promise((resolve6, reject) => {
|
|
94125
94230
|
function onError(error62) {
|
|
94126
94231
|
cleanup();
|
|
94127
94232
|
reject(error62);
|
|
94128
94233
|
}
|
|
94129
94234
|
function onConnect() {
|
|
94130
94235
|
cleanup();
|
|
94131
|
-
|
|
94236
|
+
resolve6();
|
|
94132
94237
|
}
|
|
94133
94238
|
function onAbort2() {
|
|
94134
94239
|
cleanup();
|
|
@@ -94281,7 +94386,7 @@ var NodeCryptoProvider = class extends BaseCryptoProvider {
|
|
|
94281
94386
|
}
|
|
94282
94387
|
pbkdf2(password, salt, iterations, keylen = 64, algo = "sha512") {
|
|
94283
94388
|
return new Promise(
|
|
94284
|
-
(
|
|
94389
|
+
(resolve6, reject) => pbkdf2(password, salt, iterations, keylen, algo, (err, buf) => err !== null ? reject(err) : resolve6(buf))
|
|
94285
94390
|
);
|
|
94286
94391
|
}
|
|
94287
94392
|
sha1(data) {
|
|
@@ -94531,7 +94636,7 @@ function createTelegramClient(settings) {
|
|
|
94531
94636
|
function deviceInfo() {
|
|
94532
94637
|
return {
|
|
94533
94638
|
model: `${PROJECT.name} (unofficial)`,
|
|
94534
|
-
appVersion: true ? "0.
|
|
94639
|
+
appVersion: true ? "0.3.0" : DEV_VERSION,
|
|
94535
94640
|
systemVersion: `${type2()} ${release()}`
|
|
94536
94641
|
};
|
|
94537
94642
|
}
|
|
@@ -94591,9 +94696,9 @@ async function appCredentials(paths, io) {
|
|
|
94591
94696
|
return app;
|
|
94592
94697
|
}
|
|
94593
94698
|
async function telethonSession(io) {
|
|
94594
|
-
const
|
|
94595
|
-
if (
|
|
94596
|
-
return
|
|
94699
|
+
const text2 = isTerminal(io) ? await askHidden(io, TELETHON_PROMPT) : await io.readStdin?.() ?? "";
|
|
94700
|
+
if (text2.trim() === "") throw usageError("No Telethon string session was given.");
|
|
94701
|
+
return text2;
|
|
94597
94702
|
}
|
|
94598
94703
|
function qrPrinter(io) {
|
|
94599
94704
|
const inPlace = io.isTTY ?? Boolean(process.stdout.isTTY);
|
|
@@ -94721,7 +94826,7 @@ async function removeLabel(options) {
|
|
|
94721
94826
|
if (Date.now() - start3 >= timeoutMs) {
|
|
94722
94827
|
throw new ToolError("invalid_argument", "The sync service for this label is still running; stop it first.");
|
|
94723
94828
|
}
|
|
94724
|
-
await new Promise((
|
|
94829
|
+
await new Promise((resolve6) => setTimeout(resolve6, Math.min(intervalMs, timeoutMs - (Date.now() - start3))));
|
|
94725
94830
|
}
|
|
94726
94831
|
const finalStat = await lstat8(paths.dir).catch(() => void 0);
|
|
94727
94832
|
if (!finalStat || finalStat.isSymbolicLink() || !finalStat.isDirectory()) {
|
|
@@ -94746,8 +94851,8 @@ import { chmod as chmod3, lstat as lstat9, mkdir as mkdir5, rename as rename3, r
|
|
|
94746
94851
|
import { basename as basename3, dirname as dirname6, join as join13 } from "node:path";
|
|
94747
94852
|
import { setTimeout as setTimeout3 } from "node:timers/promises";
|
|
94748
94853
|
var LAUNCHER_SCRIPT = '#!/bin/sh\nexec "$@"\n';
|
|
94749
|
-
function xmlEscape(
|
|
94750
|
-
return
|
|
94854
|
+
function xmlEscape(text2) {
|
|
94855
|
+
return text2.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
94751
94856
|
}
|
|
94752
94857
|
function buildLaunchdPlist(spec, logPath, launcherPath) {
|
|
94753
94858
|
checkServiceSpecControlChars(spec);
|
|
@@ -94803,8 +94908,8 @@ function launcherPaths(id, label, launcher, home) {
|
|
|
94803
94908
|
}
|
|
94804
94909
|
function isLaunchdNotLoaded(result) {
|
|
94805
94910
|
if (result.code === 0) return true;
|
|
94806
|
-
const
|
|
94807
|
-
return
|
|
94911
|
+
const text2 = `${result.stderr} ${result.stdout}`.toLowerCase();
|
|
94912
|
+
return text2.includes("not loaded") || text2.includes("no such process") || text2.includes("input/output error") || text2.includes("could not find") || result.code === 3 || result.code === 5;
|
|
94808
94913
|
}
|
|
94809
94914
|
var STOP_POLL_INTERVAL_MS = 200;
|
|
94810
94915
|
var STOP_TIMEOUT_MS = 3e4;
|
|
@@ -94947,8 +95052,8 @@ function systemdPaths(id, label, host) {
|
|
|
94947
95052
|
}
|
|
94948
95053
|
function isSystemdNotLoaded(result) {
|
|
94949
95054
|
if (result.code === 0) return true;
|
|
94950
|
-
const
|
|
94951
|
-
return
|
|
95055
|
+
const text2 = `${result.stderr} ${result.stdout}`.toLowerCase();
|
|
95056
|
+
return text2.includes("not loaded") || text2.includes("does not exist") || text2.includes("not found") || text2.includes("no such") || text2.includes("not active");
|
|
94952
95057
|
}
|
|
94953
95058
|
async function isSystemdActive(unitName, host) {
|
|
94954
95059
|
const result = await host.run(["systemctl", "--user", "is-active", unitName]);
|
|
@@ -95080,7 +95185,7 @@ import { existsSync as existsSync3, realpathSync } from "node:fs";
|
|
|
95080
95185
|
|
|
95081
95186
|
// src/cli/service-program.ts
|
|
95082
95187
|
import { access as access2, constants as constants4, realpath as realpath7, stat as stat3 } from "node:fs/promises";
|
|
95083
|
-
import { isAbsolute as isAbsolute7, join as join15, resolve as
|
|
95188
|
+
import { isAbsolute as isAbsolute7, join as join15, resolve as resolve5, sep as sep5 } from "node:path";
|
|
95084
95189
|
var PROBE_TIMEOUT_MS = 1e4;
|
|
95085
95190
|
var PROGRAM_NAME = "node";
|
|
95086
95191
|
var PROBE_ARGS = ["-p", "process.execPath"];
|
|
@@ -95113,7 +95218,7 @@ async function resolveRoots(roots) {
|
|
|
95113
95218
|
const resolved = /* @__PURE__ */ new Set();
|
|
95114
95219
|
for (const root of roots) {
|
|
95115
95220
|
if (root === "" || !isAbsolute7(root)) continue;
|
|
95116
|
-
resolved.add(
|
|
95221
|
+
resolved.add(resolve5(root));
|
|
95117
95222
|
try {
|
|
95118
95223
|
resolved.add(await realpath7(root));
|
|
95119
95224
|
} catch {
|
|
@@ -95144,7 +95249,7 @@ async function pickStableProgram(options) {
|
|
|
95144
95249
|
if (dir !== "" && isAbsolute7(dir)) candidates.add(join15(dir, PROGRAM_NAME));
|
|
95145
95250
|
}
|
|
95146
95251
|
for (const candidate of candidates) {
|
|
95147
|
-
if (pathHoldsVersion(candidate, version3) || isUnder(
|
|
95252
|
+
if (pathHoldsVersion(candidate, version3) || isUnder(resolve5(candidate), volatileRoots)) continue;
|
|
95148
95253
|
if (!await isExecutableFile(candidate)) continue;
|
|
95149
95254
|
let started;
|
|
95150
95255
|
try {
|
|
@@ -95479,12 +95584,12 @@ function parseRequest(message2) {
|
|
|
95479
95584
|
return { id: message2.id, method: message2.method, params };
|
|
95480
95585
|
}
|
|
95481
95586
|
function probe(socketPath) {
|
|
95482
|
-
return new Promise((
|
|
95587
|
+
return new Promise((resolve6) => {
|
|
95483
95588
|
const socket = new Socket3();
|
|
95484
95589
|
const settle3 = (outcome) => {
|
|
95485
95590
|
clearTimeout(timer);
|
|
95486
95591
|
socket.destroy();
|
|
95487
|
-
|
|
95592
|
+
resolve6(outcome);
|
|
95488
95593
|
};
|
|
95489
95594
|
const timer = setTimeout(() => settle3("unknown"), PROBE_TIMEOUT_MS2);
|
|
95490
95595
|
socket.once("connect", () => settle3("answering"));
|
|
@@ -95505,16 +95610,16 @@ async function claimSocketPath(socketPath) {
|
|
|
95505
95610
|
if (outcome === "stale") await rm5(socketPath, { force: true });
|
|
95506
95611
|
}
|
|
95507
95612
|
function listen(server, socketPath) {
|
|
95508
|
-
return new Promise((
|
|
95613
|
+
return new Promise((resolve6, reject) => {
|
|
95509
95614
|
server.once("error", reject);
|
|
95510
95615
|
server.listen(socketPath, () => {
|
|
95511
95616
|
server.off("error", reject);
|
|
95512
|
-
|
|
95617
|
+
resolve6();
|
|
95513
95618
|
});
|
|
95514
95619
|
});
|
|
95515
95620
|
}
|
|
95516
95621
|
function closeServer(server) {
|
|
95517
|
-
return new Promise((
|
|
95622
|
+
return new Promise((resolve6) => server.close(() => resolve6()));
|
|
95518
95623
|
}
|
|
95519
95624
|
function frame(reply) {
|
|
95520
95625
|
return `${JSON.stringify({ jsonrpc: "2.0", ...reply })}
|
|
@@ -95582,14 +95687,14 @@ var Connection = class {
|
|
|
95582
95687
|
signal: this.calls.signal,
|
|
95583
95688
|
afterAnswered: (effect) => answered ? runEffect(effect) : void effects.push(effect)
|
|
95584
95689
|
};
|
|
95585
|
-
let
|
|
95690
|
+
let text2;
|
|
95586
95691
|
try {
|
|
95587
95692
|
const result = await handler(params, call);
|
|
95588
|
-
|
|
95693
|
+
text2 = frame({ id, result: result ?? null });
|
|
95589
95694
|
} catch (error62) {
|
|
95590
|
-
|
|
95695
|
+
text2 = frame({ id, error: this.failure(error62, method) });
|
|
95591
95696
|
}
|
|
95592
|
-
this.write(
|
|
95697
|
+
this.write(text2, () => {
|
|
95593
95698
|
answered = true;
|
|
95594
95699
|
for (const effect of effects.splice(0)) runEffect(effect);
|
|
95595
95700
|
});
|
|
@@ -95612,13 +95717,13 @@ var Connection = class {
|
|
|
95612
95717
|
* way is the client's loss. `onWritten` runs once the line is flushed, or
|
|
95613
95718
|
* when it cannot be.
|
|
95614
95719
|
*/
|
|
95615
|
-
write(
|
|
95720
|
+
write(text2, onWritten) {
|
|
95616
95721
|
if (!this.socket.writable) {
|
|
95617
95722
|
onWritten?.();
|
|
95618
95723
|
return;
|
|
95619
95724
|
}
|
|
95620
95725
|
try {
|
|
95621
|
-
this.socket.write(
|
|
95726
|
+
this.socket.write(text2, onWritten);
|
|
95622
95727
|
} catch {
|
|
95623
95728
|
this.socket.destroy();
|
|
95624
95729
|
onWritten?.();
|
|
@@ -95654,7 +95759,7 @@ async function serveService(socketPath, handlers, options = {}) {
|
|
|
95654
95759
|
});
|
|
95655
95760
|
let closing;
|
|
95656
95761
|
const shutDown2 = async () => {
|
|
95657
|
-
const closed = [...connections].map((socket) => new Promise((
|
|
95762
|
+
const closed = [...connections].map((socket) => new Promise((resolve6) => socket.once("close", resolve6)));
|
|
95658
95763
|
for (const socket of connections) socket.destroy();
|
|
95659
95764
|
await Promise.all(closed);
|
|
95660
95765
|
await closeServer(server);
|
|
@@ -95676,8 +95781,8 @@ var STORAGE_FAILURE_REASON = "the mirror cannot be written; receiving stopped";
|
|
|
95676
95781
|
var CONNECTION_LOST_REASON = "the connection to Telegram could not be kept";
|
|
95677
95782
|
var OTHER_ACCOUNT_REASON = "this mirror belongs to another account";
|
|
95678
95783
|
function errorLabel(error62) {
|
|
95679
|
-
const
|
|
95680
|
-
if (
|
|
95784
|
+
const text2 = rpcTextOf(error62);
|
|
95785
|
+
if (text2 !== void 0) return text2;
|
|
95681
95786
|
if (error62 instanceof ToolError) return error62.message;
|
|
95682
95787
|
return error62 instanceof Error ? error62.name : "unexpected error";
|
|
95683
95788
|
}
|
|
@@ -95753,7 +95858,7 @@ var Ending = class {
|
|
|
95753
95858
|
};
|
|
95754
95859
|
result;
|
|
95755
95860
|
constructor() {
|
|
95756
|
-
this.promise = new Promise((
|
|
95861
|
+
this.promise = new Promise((resolve6) => this.resolve = resolve6);
|
|
95757
95862
|
}
|
|
95758
95863
|
/** Aborts once the run has ended, so everything waiting on it gives up. */
|
|
95759
95864
|
get signal() {
|
|
@@ -95782,26 +95887,26 @@ function onAbort(signal, fn) {
|
|
|
95782
95887
|
signal.addEventListener("abort", fn, { once: true });
|
|
95783
95888
|
return () => signal.removeEventListener("abort", fn);
|
|
95784
95889
|
}
|
|
95785
|
-
var realPause = (ms, signal) => new Promise((
|
|
95890
|
+
var realPause = (ms, signal) => new Promise((resolve6) => {
|
|
95786
95891
|
let stopListening = () => {
|
|
95787
95892
|
};
|
|
95788
95893
|
const timer = setTimeout(() => {
|
|
95789
95894
|
stopListening();
|
|
95790
|
-
|
|
95895
|
+
resolve6();
|
|
95791
95896
|
}, ms);
|
|
95792
95897
|
stopListening = onAbort(signal, () => {
|
|
95793
95898
|
clearTimeout(timer);
|
|
95794
|
-
|
|
95899
|
+
resolve6();
|
|
95795
95900
|
});
|
|
95796
95901
|
});
|
|
95797
95902
|
function waitThrough(pause, ms, signal) {
|
|
95798
95903
|
if (signal.aborted) return Promise.resolve();
|
|
95799
|
-
return new Promise((
|
|
95800
|
-
const stopListening = onAbort(signal,
|
|
95904
|
+
return new Promise((resolve6) => {
|
|
95905
|
+
const stopListening = onAbort(signal, resolve6);
|
|
95801
95906
|
pause(ms, signal).catch(() => {
|
|
95802
95907
|
}).finally(() => {
|
|
95803
95908
|
stopListening();
|
|
95804
|
-
|
|
95909
|
+
resolve6();
|
|
95805
95910
|
});
|
|
95806
95911
|
});
|
|
95807
95912
|
}
|
|
@@ -95826,9 +95931,9 @@ function cancelled() {
|
|
|
95826
95931
|
return new ToolError("upstream_error", "The request was cancelled before Telegram answered.");
|
|
95827
95932
|
}
|
|
95828
95933
|
function abortable(promise2, signal) {
|
|
95829
|
-
return new Promise((
|
|
95934
|
+
return new Promise((resolve6, reject) => {
|
|
95830
95935
|
const stopListening = onAbort(signal, () => reject(cancelled()));
|
|
95831
|
-
promise2.then(
|
|
95936
|
+
promise2.then(resolve6, reject).then(stopListening);
|
|
95832
95937
|
});
|
|
95833
95938
|
}
|
|
95834
95939
|
function requestFailure(error62, what, env) {
|
|
@@ -96219,9 +96324,8 @@ function applyRead(mirror, read) {
|
|
|
96219
96324
|
}
|
|
96220
96325
|
|
|
96221
96326
|
// src/core/telegram/ingest-messages.ts
|
|
96222
|
-
var MS_PER_S2 = 1e3;
|
|
96223
96327
|
function expiryOf(msg) {
|
|
96224
|
-
return isCount(msg.ttl) && msg.ttl > 0 ? msg.ts + msg.ttl *
|
|
96328
|
+
return isCount(msg.ttl) && msg.ttl > 0 ? msg.ts + msg.ttl * MS_PER_S : null;
|
|
96225
96329
|
}
|
|
96226
96330
|
function findVersion(mirror, chat, id) {
|
|
96227
96331
|
const row = mirror.prepare("SELECT ts, body, entities, media, edited, expires FROM messages WHERE chat = ? AND id = ?").get(chat, id);
|
|
@@ -96578,8 +96682,8 @@ var ChatListRefresh = class {
|
|
|
96578
96682
|
}
|
|
96579
96683
|
begin() {
|
|
96580
96684
|
let listener;
|
|
96581
|
-
const listed = new Promise((
|
|
96582
|
-
listener = { listed:
|
|
96685
|
+
const listed = new Promise((resolve6, reject) => {
|
|
96686
|
+
listener = { listed: resolve6, failed: reject };
|
|
96583
96687
|
});
|
|
96584
96688
|
listed.catch(() => {
|
|
96585
96689
|
});
|
|
@@ -96759,7 +96863,6 @@ import { Buffer as Buffer8 } from "node:buffer";
|
|
|
96759
96863
|
import { open as open6 } from "node:fs/promises";
|
|
96760
96864
|
|
|
96761
96865
|
// src/core/telegram/sync-download-file.ts
|
|
96762
|
-
var MS_PER_S3 = 1e3;
|
|
96763
96866
|
var FILE_KINDS = ["photo", "document", "audio", "voice", "video", "sticker"];
|
|
96764
96867
|
function isFileMedia(media) {
|
|
96765
96868
|
return media !== null && FILE_KINDS.includes(media.type);
|
|
@@ -96773,7 +96876,7 @@ function messageFile(message2) {
|
|
|
96773
96876
|
}
|
|
96774
96877
|
function disappearsAtOf(message2) {
|
|
96775
96878
|
const ttl = message2.ttlPeriod;
|
|
96776
|
-
return ttl ? message2.date.getTime() + ttl *
|
|
96879
|
+
return ttl ? message2.date.getTime() + ttl * MS_PER_S : void 0;
|
|
96777
96880
|
}
|
|
96778
96881
|
|
|
96779
96882
|
// src/core/telegram/sync-download-refusal.ts
|
|
@@ -96801,11 +96904,10 @@ function tooLargeReason(size, maxBytes) {
|
|
|
96801
96904
|
// src/core/telegram/sync-download-stream.ts
|
|
96802
96905
|
import { open as open4 } from "node:fs/promises";
|
|
96803
96906
|
var FILE_MODE3 = 384;
|
|
96804
|
-
var MS_PER_S4 = 1e3;
|
|
96805
96907
|
function stalled(stallMs) {
|
|
96806
96908
|
return new ToolError(
|
|
96807
96909
|
"upstream_error",
|
|
96808
|
-
`The download received nothing for ${stallMs /
|
|
96910
|
+
`The download received nothing for ${stallMs / MS_PER_S} seconds; try again later.`
|
|
96809
96911
|
);
|
|
96810
96912
|
}
|
|
96811
96913
|
async function writeAll2(handle, chunk) {
|
|
@@ -96814,7 +96916,7 @@ async function writeAll2(handle, chunk) {
|
|
|
96814
96916
|
}
|
|
96815
96917
|
async function writeDownload(ctx, signal, media, file2, max3) {
|
|
96816
96918
|
const env = { endSession: ctx.endSession, log: ctx.settings.log };
|
|
96817
|
-
const stallMs = ctx.settings.
|
|
96919
|
+
const stallMs = ctx.settings.transferStallMs;
|
|
96818
96920
|
const failure2 = (error62) => {
|
|
96819
96921
|
if (signal.aborted) return cancelled();
|
|
96820
96922
|
if (error62 instanceof MtTimeoutError && error62.timeout === stallMs) return stalled(stallMs);
|
|
@@ -97144,6 +97246,202 @@ var FileKeeper = class {
|
|
|
97144
97246
|
}
|
|
97145
97247
|
};
|
|
97146
97248
|
|
|
97249
|
+
// src/core/telegram/sync-options.ts
|
|
97250
|
+
var SECOND_MS2 = 1e3;
|
|
97251
|
+
var MINUTE_MS = 60 * SECOND_MS2;
|
|
97252
|
+
var HOUR_MS = 60 * MINUTE_MS;
|
|
97253
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
97254
|
+
var TRANSFER_STALL_MS = 6e4;
|
|
97255
|
+
var DEFAULT_HEARTBEAT_EVERY_MS = 5 * SECOND_MS2;
|
|
97256
|
+
var DEFAULT_GAP_AFTER_MS = 30 * SECOND_MS2;
|
|
97257
|
+
var DEFAULT_OFFLINE_LIMIT_MS = 10 * MINUTE_MS;
|
|
97258
|
+
var DEFAULT_PURGE_EVERY_MS = HOUR_MS;
|
|
97259
|
+
var DEFAULT_REFRESH_EVERY_MS = 30 * MINUTE_MS;
|
|
97260
|
+
var DEFAULT_REFRESH_RETRY_MS = MINUTE_MS;
|
|
97261
|
+
var DEFAULT_ROUND_EVERY_MS = 5 * SECOND_MS2;
|
|
97262
|
+
var DEFAULT_STOP_WAIT_MS = 10 * SECOND_MS2;
|
|
97263
|
+
var DEFAULT_SEED_WITHIN_MS = 30 * DAY_MS;
|
|
97264
|
+
var DEFAULT_SEED_COUNT = 50;
|
|
97265
|
+
var DEFAULT_SEED_CHATS_PER_ROUND = 20;
|
|
97266
|
+
var DEFAULT_SEED_ATTEMPTS = 3;
|
|
97267
|
+
var DEFAULT_FILL_LIMIT = 200;
|
|
97268
|
+
var DEFAULT_PACE_MS = [500, 1500];
|
|
97269
|
+
function resolveOptions(options) {
|
|
97270
|
+
return {
|
|
97271
|
+
...options,
|
|
97272
|
+
now: options.now ?? Date.now,
|
|
97273
|
+
pause: options.pause ?? realPause,
|
|
97274
|
+
heartbeatEveryMs: options.heartbeatEveryMs ?? DEFAULT_HEARTBEAT_EVERY_MS,
|
|
97275
|
+
gapAfterMs: options.gapAfterMs ?? DEFAULT_GAP_AFTER_MS,
|
|
97276
|
+
offlineLimitMs: options.offlineLimitMs ?? DEFAULT_OFFLINE_LIMIT_MS,
|
|
97277
|
+
purgeEveryMs: options.purgeEveryMs ?? DEFAULT_PURGE_EVERY_MS,
|
|
97278
|
+
refreshEveryMs: options.refreshEveryMs ?? DEFAULT_REFRESH_EVERY_MS,
|
|
97279
|
+
refreshRetryMs: options.refreshRetryMs ?? DEFAULT_REFRESH_RETRY_MS,
|
|
97280
|
+
roundEveryMs: options.roundEveryMs ?? DEFAULT_ROUND_EVERY_MS,
|
|
97281
|
+
stopWaitMs: options.stopWaitMs ?? DEFAULT_STOP_WAIT_MS,
|
|
97282
|
+
seedWithinMs: options.seedWithinMs ?? DEFAULT_SEED_WITHIN_MS,
|
|
97283
|
+
seedCount: options.seedCount ?? DEFAULT_SEED_COUNT,
|
|
97284
|
+
seedChatsPerRound: options.seedChatsPerRound ?? DEFAULT_SEED_CHATS_PER_ROUND,
|
|
97285
|
+
seedAttempts: options.seedAttempts ?? DEFAULT_SEED_ATTEMPTS,
|
|
97286
|
+
fillLimit: options.fillLimit ?? DEFAULT_FILL_LIMIT,
|
|
97287
|
+
paceMs: options.paceMs ?? DEFAULT_PACE_MS,
|
|
97288
|
+
transferStallMs: options.transferStallMs ?? TRANSFER_STALL_MS
|
|
97289
|
+
};
|
|
97290
|
+
}
|
|
97291
|
+
|
|
97292
|
+
// src/core/telegram/sync-message.ts
|
|
97293
|
+
function readMessage(message2, channels) {
|
|
97294
|
+
const input8 = messageInputOf(message2);
|
|
97295
|
+
if (!input8) return null;
|
|
97296
|
+
const peer = readOrNull(() => message2.chat);
|
|
97297
|
+
const chat = peer ? chatInputOf(peer) : null;
|
|
97298
|
+
if (chat && !keepsKind(chat.kind, channels)) return null;
|
|
97299
|
+
return { chat, message: input8, topic: topicInputOfAction(message2) };
|
|
97300
|
+
}
|
|
97301
|
+
function writeMessage(mirror, ctx, read, channels) {
|
|
97302
|
+
if (read.chat) rememberChats(mirror, [read.chat], ctx.now, channels);
|
|
97303
|
+
if (read.topic) upsertTopics(mirror, [read.topic], ctx.now);
|
|
97304
|
+
return storeMessage(mirror, ctx, read.message);
|
|
97305
|
+
}
|
|
97306
|
+
|
|
97307
|
+
// src/core/telegram/sync-receive.ts
|
|
97308
|
+
var SKIPPED = "skipped";
|
|
97309
|
+
function countsOf(outcomes) {
|
|
97310
|
+
const counts = /* @__PURE__ */ new Map();
|
|
97311
|
+
for (const outcome of outcomes) counts.set(outcome, (counts.get(outcome) ?? 0) + 1);
|
|
97312
|
+
return [...counts].map(([outcome, count]) => `${outcome}=${count}`).join(" ") || "none";
|
|
97313
|
+
}
|
|
97314
|
+
var Receiver = class {
|
|
97315
|
+
deps;
|
|
97316
|
+
keeper;
|
|
97317
|
+
halted = false;
|
|
97318
|
+
constructor(deps) {
|
|
97319
|
+
this.deps = deps;
|
|
97320
|
+
}
|
|
97321
|
+
/**
|
|
97322
|
+
* Registers the handlers on the client's emitters; call it before the client
|
|
97323
|
+
* connects. `keeper` keeps the files of the disappearing messages that
|
|
97324
|
+
* arrive, when `keepDisappearing` is on.
|
|
97325
|
+
*/
|
|
97326
|
+
attach(client, keeper) {
|
|
97327
|
+
this.keeper = keeper;
|
|
97328
|
+
client.onNewMessage.add((message2) => this.onMessage("message", message2));
|
|
97329
|
+
client.onEditMessage.add((message2) => this.onMessage("edit", message2));
|
|
97330
|
+
client.onDeleteMessage.add((update) => this.onDelete(update));
|
|
97331
|
+
client.onHistoryRead.add((update) => this.onRead(update));
|
|
97332
|
+
}
|
|
97333
|
+
/** Stops storing: whatever arrives from here on is ignored. */
|
|
97334
|
+
halt() {
|
|
97335
|
+
this.halted = true;
|
|
97336
|
+
}
|
|
97337
|
+
onMessage(label, message2) {
|
|
97338
|
+
const { channels, keepDisappearing } = this.deps;
|
|
97339
|
+
const done = this.process(
|
|
97340
|
+
label,
|
|
97341
|
+
() => readMessage(message2, channels),
|
|
97342
|
+
(read, ctx) => writeMessage(this.deps.mirror, ctx, read, channels)
|
|
97343
|
+
);
|
|
97344
|
+
if (keepDisappearing && label === "message" && done?.outcome === "stored") {
|
|
97345
|
+
this.keeper?.keep(message2, done.prepared.message);
|
|
97346
|
+
}
|
|
97347
|
+
}
|
|
97348
|
+
onDelete(update) {
|
|
97349
|
+
const { mirror, coverage, keepDisappearing } = this.deps;
|
|
97350
|
+
const done = this.process(
|
|
97351
|
+
"delete",
|
|
97352
|
+
() => deleteInputOf(update),
|
|
97353
|
+
(input8, ctx) => {
|
|
97354
|
+
if (input8.chat !== null && !findChat(mirror, input8.chat)?.followed) return SKIPPED;
|
|
97355
|
+
coverage.note(ctx.now);
|
|
97356
|
+
return countsOf(deleteMessages2(mirror, ctx, input8));
|
|
97357
|
+
}
|
|
97358
|
+
);
|
|
97359
|
+
if (keepDisappearing && done && done.outcome !== SKIPPED) {
|
|
97360
|
+
this.keeper?.forgetMessages(done.prepared.chat, done.prepared.ids);
|
|
97361
|
+
}
|
|
97362
|
+
}
|
|
97363
|
+
onRead(update) {
|
|
97364
|
+
this.process(
|
|
97365
|
+
"read",
|
|
97366
|
+
() => readInputOf(update),
|
|
97367
|
+
(input8) => {
|
|
97368
|
+
applyRead(this.deps.mirror, input8);
|
|
97369
|
+
return "applied";
|
|
97370
|
+
}
|
|
97371
|
+
);
|
|
97372
|
+
}
|
|
97373
|
+
/**
|
|
97374
|
+
* Turns the update into `prepared` outside the transaction, so that what
|
|
97375
|
+
* fails there is only mtcute's data, then writes it. `store` names the
|
|
97376
|
+
* outcome for the log. Resolves with `prepared` and the outcome once it is
|
|
97377
|
+
* written, and with null when the update was not (unreadable, not for the
|
|
97378
|
+
* mirror, or a storage failure).
|
|
97379
|
+
*/
|
|
97380
|
+
process(label, prepare2, store) {
|
|
97381
|
+
if (this.halted) return null;
|
|
97382
|
+
const { mirror, now, keepDisappearing, log } = this.deps;
|
|
97383
|
+
let prepared;
|
|
97384
|
+
try {
|
|
97385
|
+
prepared = prepare2();
|
|
97386
|
+
} catch (error62) {
|
|
97387
|
+
log(`event: ${label} unreadable (${errorLabel(error62)})`);
|
|
97388
|
+
return null;
|
|
97389
|
+
}
|
|
97390
|
+
if (prepared === null) {
|
|
97391
|
+
log(`event: ${label} ${SKIPPED}`);
|
|
97392
|
+
return null;
|
|
97393
|
+
}
|
|
97394
|
+
let outcome;
|
|
97395
|
+
try {
|
|
97396
|
+
const received = now();
|
|
97397
|
+
outcome = inTransaction(mirror, () => {
|
|
97398
|
+
const result = store(prepared, { now: received, keepDisappearing });
|
|
97399
|
+
if (result !== SKIPPED) setMeta(mirror, { [META.lastReceivedAt]: received });
|
|
97400
|
+
return result;
|
|
97401
|
+
});
|
|
97402
|
+
} catch {
|
|
97403
|
+
this.failStorage();
|
|
97404
|
+
return null;
|
|
97405
|
+
}
|
|
97406
|
+
log(`event: ${label} ${outcome}`);
|
|
97407
|
+
return { prepared, outcome };
|
|
97408
|
+
}
|
|
97409
|
+
failStorage() {
|
|
97410
|
+
if (this.halted) return;
|
|
97411
|
+
this.halted = true;
|
|
97412
|
+
this.deps.onStorageFailure();
|
|
97413
|
+
this.deps.log(STORAGE_FAILURE_REASON);
|
|
97414
|
+
}
|
|
97415
|
+
};
|
|
97416
|
+
|
|
97417
|
+
// src/core/telegram/sync-request-queue.ts
|
|
97418
|
+
var RequestQueue = class {
|
|
97419
|
+
/** Settles when the last job in line is done. It never rejects. */
|
|
97420
|
+
tail = Promise.resolve();
|
|
97421
|
+
/**
|
|
97422
|
+
* Runs `work` once the jobs ahead are done. Rejects as `cancelled()`, without
|
|
97423
|
+
* running `work`, when `signal` aborts first; the jobs behind it then wait
|
|
97424
|
+
* for the ones ahead of it, as they would have.
|
|
97425
|
+
*/
|
|
97426
|
+
async run(signal, work) {
|
|
97427
|
+
const ahead = this.tail;
|
|
97428
|
+
let done = () => {
|
|
97429
|
+
};
|
|
97430
|
+
this.tail = new Promise((resolve6) => done = resolve6);
|
|
97431
|
+
try {
|
|
97432
|
+
await abortable(ahead, signal);
|
|
97433
|
+
} catch (error62) {
|
|
97434
|
+
void ahead.then(done);
|
|
97435
|
+
throw error62;
|
|
97436
|
+
}
|
|
97437
|
+
try {
|
|
97438
|
+
return await work();
|
|
97439
|
+
} finally {
|
|
97440
|
+
done();
|
|
97441
|
+
}
|
|
97442
|
+
}
|
|
97443
|
+
};
|
|
97444
|
+
|
|
97147
97445
|
// src/core/telegram/sync-request-calls.ts
|
|
97148
97446
|
async function viaTelegram(ctx, call, what, work) {
|
|
97149
97447
|
const signal = AbortSignal.any([call.signal, ctx.signal]);
|
|
@@ -97276,12 +97574,12 @@ function parseDownloadParams(params) {
|
|
|
97276
97574
|
};
|
|
97277
97575
|
}
|
|
97278
97576
|
function sendTextAt(fields) {
|
|
97279
|
-
const { text } = fields;
|
|
97280
|
-
if (typeof
|
|
97281
|
-
if (
|
|
97282
|
-
if (
|
|
97283
|
-
if (
|
|
97284
|
-
return
|
|
97577
|
+
const { text: text2 } = fields;
|
|
97578
|
+
if (typeof text2 !== "string") throw invalid("text must be a string.");
|
|
97579
|
+
if (text2.trim() === "") throw invalid("text must not be blank.");
|
|
97580
|
+
if (text2 !== text2.trim()) throw invalid("text must not start or end with blank space.");
|
|
97581
|
+
if (text2.length > TEXT_MAX_UNITS) throw invalid(`text must be at most ${TEXT_MAX_UNITS} characters.`);
|
|
97582
|
+
return text2;
|
|
97285
97583
|
}
|
|
97286
97584
|
function parseSendParams(params) {
|
|
97287
97585
|
const fields = recordOf(params, SEND_KEYS, "The send parameters");
|
|
@@ -97404,7 +97702,6 @@ function expectNoParams(params, what) {
|
|
|
97404
97702
|
}
|
|
97405
97703
|
|
|
97406
97704
|
// src/core/telegram/sync-download.ts
|
|
97407
|
-
var DOWNLOAD_STALL_MS = 6e4;
|
|
97408
97705
|
function fileOf(message2, id) {
|
|
97409
97706
|
const file2 = messageFile(message2);
|
|
97410
97707
|
if (!file2) {
|
|
@@ -97478,201 +97775,6 @@ function downloadRequest(ctx, queue, raw, call) {
|
|
|
97478
97775
|
return keptCopy(ctx, params).then((kept) => kept ?? queue.run(signal, () => downloadFile(ctx, call, signal, params)));
|
|
97479
97776
|
}
|
|
97480
97777
|
|
|
97481
|
-
// src/core/telegram/sync-options.ts
|
|
97482
|
-
var SECOND_MS2 = 1e3;
|
|
97483
|
-
var MINUTE_MS = 60 * SECOND_MS2;
|
|
97484
|
-
var HOUR_MS = 60 * MINUTE_MS;
|
|
97485
|
-
var DAY_MS = 24 * HOUR_MS;
|
|
97486
|
-
var DEFAULT_HEARTBEAT_EVERY_MS = 5 * SECOND_MS2;
|
|
97487
|
-
var DEFAULT_GAP_AFTER_MS = 30 * SECOND_MS2;
|
|
97488
|
-
var DEFAULT_OFFLINE_LIMIT_MS = 10 * MINUTE_MS;
|
|
97489
|
-
var DEFAULT_PURGE_EVERY_MS = HOUR_MS;
|
|
97490
|
-
var DEFAULT_REFRESH_EVERY_MS = 30 * MINUTE_MS;
|
|
97491
|
-
var DEFAULT_REFRESH_RETRY_MS = MINUTE_MS;
|
|
97492
|
-
var DEFAULT_ROUND_EVERY_MS = 5 * SECOND_MS2;
|
|
97493
|
-
var DEFAULT_STOP_WAIT_MS = 10 * SECOND_MS2;
|
|
97494
|
-
var DEFAULT_SEED_WITHIN_MS = 30 * DAY_MS;
|
|
97495
|
-
var DEFAULT_SEED_COUNT = 50;
|
|
97496
|
-
var DEFAULT_SEED_CHATS_PER_ROUND = 20;
|
|
97497
|
-
var DEFAULT_SEED_ATTEMPTS = 3;
|
|
97498
|
-
var DEFAULT_FILL_LIMIT = 200;
|
|
97499
|
-
var DEFAULT_PACE_MS = [500, 1500];
|
|
97500
|
-
function resolveOptions(options) {
|
|
97501
|
-
return {
|
|
97502
|
-
...options,
|
|
97503
|
-
now: options.now ?? Date.now,
|
|
97504
|
-
pause: options.pause ?? realPause,
|
|
97505
|
-
heartbeatEveryMs: options.heartbeatEveryMs ?? DEFAULT_HEARTBEAT_EVERY_MS,
|
|
97506
|
-
gapAfterMs: options.gapAfterMs ?? DEFAULT_GAP_AFTER_MS,
|
|
97507
|
-
offlineLimitMs: options.offlineLimitMs ?? DEFAULT_OFFLINE_LIMIT_MS,
|
|
97508
|
-
purgeEveryMs: options.purgeEveryMs ?? DEFAULT_PURGE_EVERY_MS,
|
|
97509
|
-
refreshEveryMs: options.refreshEveryMs ?? DEFAULT_REFRESH_EVERY_MS,
|
|
97510
|
-
refreshRetryMs: options.refreshRetryMs ?? DEFAULT_REFRESH_RETRY_MS,
|
|
97511
|
-
roundEveryMs: options.roundEveryMs ?? DEFAULT_ROUND_EVERY_MS,
|
|
97512
|
-
stopWaitMs: options.stopWaitMs ?? DEFAULT_STOP_WAIT_MS,
|
|
97513
|
-
seedWithinMs: options.seedWithinMs ?? DEFAULT_SEED_WITHIN_MS,
|
|
97514
|
-
seedCount: options.seedCount ?? DEFAULT_SEED_COUNT,
|
|
97515
|
-
seedChatsPerRound: options.seedChatsPerRound ?? DEFAULT_SEED_CHATS_PER_ROUND,
|
|
97516
|
-
seedAttempts: options.seedAttempts ?? DEFAULT_SEED_ATTEMPTS,
|
|
97517
|
-
fillLimit: options.fillLimit ?? DEFAULT_FILL_LIMIT,
|
|
97518
|
-
paceMs: options.paceMs ?? DEFAULT_PACE_MS,
|
|
97519
|
-
downloadStallMs: options.downloadStallMs ?? DOWNLOAD_STALL_MS
|
|
97520
|
-
};
|
|
97521
|
-
}
|
|
97522
|
-
|
|
97523
|
-
// src/core/telegram/sync-message.ts
|
|
97524
|
-
function readMessage(message2, channels) {
|
|
97525
|
-
const input8 = messageInputOf(message2);
|
|
97526
|
-
if (!input8) return null;
|
|
97527
|
-
const peer = readOrNull(() => message2.chat);
|
|
97528
|
-
const chat = peer ? chatInputOf(peer) : null;
|
|
97529
|
-
if (chat && !keepsKind(chat.kind, channels)) return null;
|
|
97530
|
-
return { chat, message: input8, topic: topicInputOfAction(message2) };
|
|
97531
|
-
}
|
|
97532
|
-
function writeMessage(mirror, ctx, read, channels) {
|
|
97533
|
-
if (read.chat) rememberChats(mirror, [read.chat], ctx.now, channels);
|
|
97534
|
-
if (read.topic) upsertTopics(mirror, [read.topic], ctx.now);
|
|
97535
|
-
return storeMessage(mirror, ctx, read.message);
|
|
97536
|
-
}
|
|
97537
|
-
|
|
97538
|
-
// src/core/telegram/sync-receive.ts
|
|
97539
|
-
var SKIPPED = "skipped";
|
|
97540
|
-
function countsOf(outcomes) {
|
|
97541
|
-
const counts = /* @__PURE__ */ new Map();
|
|
97542
|
-
for (const outcome of outcomes) counts.set(outcome, (counts.get(outcome) ?? 0) + 1);
|
|
97543
|
-
return [...counts].map(([outcome, count]) => `${outcome}=${count}`).join(" ") || "none";
|
|
97544
|
-
}
|
|
97545
|
-
var Receiver = class {
|
|
97546
|
-
deps;
|
|
97547
|
-
keeper;
|
|
97548
|
-
halted = false;
|
|
97549
|
-
constructor(deps) {
|
|
97550
|
-
this.deps = deps;
|
|
97551
|
-
}
|
|
97552
|
-
/**
|
|
97553
|
-
* Registers the handlers on the client's emitters; call it before the client
|
|
97554
|
-
* connects. `keeper` keeps the files of the disappearing messages that
|
|
97555
|
-
* arrive, when `keepDisappearing` is on.
|
|
97556
|
-
*/
|
|
97557
|
-
attach(client, keeper) {
|
|
97558
|
-
this.keeper = keeper;
|
|
97559
|
-
client.onNewMessage.add((message2) => this.onMessage("message", message2));
|
|
97560
|
-
client.onEditMessage.add((message2) => this.onMessage("edit", message2));
|
|
97561
|
-
client.onDeleteMessage.add((update) => this.onDelete(update));
|
|
97562
|
-
client.onHistoryRead.add((update) => this.onRead(update));
|
|
97563
|
-
}
|
|
97564
|
-
/** Stops storing: whatever arrives from here on is ignored. */
|
|
97565
|
-
halt() {
|
|
97566
|
-
this.halted = true;
|
|
97567
|
-
}
|
|
97568
|
-
onMessage(label, message2) {
|
|
97569
|
-
const { channels, keepDisappearing } = this.deps;
|
|
97570
|
-
const done = this.process(
|
|
97571
|
-
label,
|
|
97572
|
-
() => readMessage(message2, channels),
|
|
97573
|
-
(read, ctx) => writeMessage(this.deps.mirror, ctx, read, channels)
|
|
97574
|
-
);
|
|
97575
|
-
if (keepDisappearing && label === "message" && done?.outcome === "stored") {
|
|
97576
|
-
this.keeper?.keep(message2, done.prepared.message);
|
|
97577
|
-
}
|
|
97578
|
-
}
|
|
97579
|
-
onDelete(update) {
|
|
97580
|
-
const { mirror, coverage, keepDisappearing } = this.deps;
|
|
97581
|
-
const done = this.process(
|
|
97582
|
-
"delete",
|
|
97583
|
-
() => deleteInputOf(update),
|
|
97584
|
-
(input8, ctx) => {
|
|
97585
|
-
if (input8.chat !== null && !findChat(mirror, input8.chat)?.followed) return SKIPPED;
|
|
97586
|
-
coverage.note(ctx.now);
|
|
97587
|
-
return countsOf(deleteMessages2(mirror, ctx, input8));
|
|
97588
|
-
}
|
|
97589
|
-
);
|
|
97590
|
-
if (keepDisappearing && done && done.outcome !== SKIPPED) {
|
|
97591
|
-
this.keeper?.forgetMessages(done.prepared.chat, done.prepared.ids);
|
|
97592
|
-
}
|
|
97593
|
-
}
|
|
97594
|
-
onRead(update) {
|
|
97595
|
-
this.process(
|
|
97596
|
-
"read",
|
|
97597
|
-
() => readInputOf(update),
|
|
97598
|
-
(input8) => {
|
|
97599
|
-
applyRead(this.deps.mirror, input8);
|
|
97600
|
-
return "applied";
|
|
97601
|
-
}
|
|
97602
|
-
);
|
|
97603
|
-
}
|
|
97604
|
-
/**
|
|
97605
|
-
* Turns the update into `prepared` outside the transaction, so that what
|
|
97606
|
-
* fails there is only mtcute's data, then writes it. `store` names the
|
|
97607
|
-
* outcome for the log. Resolves with `prepared` and the outcome once it is
|
|
97608
|
-
* written, and with null when the update was not (unreadable, not for the
|
|
97609
|
-
* mirror, or a storage failure).
|
|
97610
|
-
*/
|
|
97611
|
-
process(label, prepare2, store) {
|
|
97612
|
-
if (this.halted) return null;
|
|
97613
|
-
const { mirror, now, keepDisappearing, log } = this.deps;
|
|
97614
|
-
let prepared;
|
|
97615
|
-
try {
|
|
97616
|
-
prepared = prepare2();
|
|
97617
|
-
} catch (error62) {
|
|
97618
|
-
log(`event: ${label} unreadable (${errorLabel(error62)})`);
|
|
97619
|
-
return null;
|
|
97620
|
-
}
|
|
97621
|
-
if (prepared === null) {
|
|
97622
|
-
log(`event: ${label} ${SKIPPED}`);
|
|
97623
|
-
return null;
|
|
97624
|
-
}
|
|
97625
|
-
let outcome;
|
|
97626
|
-
try {
|
|
97627
|
-
const received = now();
|
|
97628
|
-
outcome = inTransaction(mirror, () => {
|
|
97629
|
-
const result = store(prepared, { now: received, keepDisappearing });
|
|
97630
|
-
if (result !== SKIPPED) setMeta(mirror, { [META.lastReceivedAt]: received });
|
|
97631
|
-
return result;
|
|
97632
|
-
});
|
|
97633
|
-
} catch {
|
|
97634
|
-
this.failStorage();
|
|
97635
|
-
return null;
|
|
97636
|
-
}
|
|
97637
|
-
log(`event: ${label} ${outcome}`);
|
|
97638
|
-
return { prepared, outcome };
|
|
97639
|
-
}
|
|
97640
|
-
failStorage() {
|
|
97641
|
-
if (this.halted) return;
|
|
97642
|
-
this.halted = true;
|
|
97643
|
-
this.deps.onStorageFailure();
|
|
97644
|
-
this.deps.log(STORAGE_FAILURE_REASON);
|
|
97645
|
-
}
|
|
97646
|
-
};
|
|
97647
|
-
|
|
97648
|
-
// src/core/telegram/sync-request-queue.ts
|
|
97649
|
-
var RequestQueue = class {
|
|
97650
|
-
/** Settles when the last job in line is done. It never rejects. */
|
|
97651
|
-
tail = Promise.resolve();
|
|
97652
|
-
/**
|
|
97653
|
-
* Runs `work` once the jobs ahead are done. Rejects as `cancelled()`, without
|
|
97654
|
-
* running `work`, when `signal` aborts first; the jobs behind it then wait
|
|
97655
|
-
* for the ones ahead of it, as they would have.
|
|
97656
|
-
*/
|
|
97657
|
-
async run(signal, work) {
|
|
97658
|
-
const ahead = this.tail;
|
|
97659
|
-
let done = () => {
|
|
97660
|
-
};
|
|
97661
|
-
this.tail = new Promise((resolve8) => done = resolve8);
|
|
97662
|
-
try {
|
|
97663
|
-
await abortable(ahead, signal);
|
|
97664
|
-
} catch (error62) {
|
|
97665
|
-
void ahead.then(done);
|
|
97666
|
-
throw error62;
|
|
97667
|
-
}
|
|
97668
|
-
try {
|
|
97669
|
-
return await work();
|
|
97670
|
-
} finally {
|
|
97671
|
-
done();
|
|
97672
|
-
}
|
|
97673
|
-
}
|
|
97674
|
-
};
|
|
97675
|
-
|
|
97676
97778
|
// src/core/telegram/sync-list-requests.ts
|
|
97677
97779
|
function expectListable({ mirror, settings }, chats) {
|
|
97678
97780
|
for (const id of chats) {
|
|
@@ -97724,7 +97826,6 @@ async function syncRemove(ctx, raw) {
|
|
|
97724
97826
|
}
|
|
97725
97827
|
|
|
97726
97828
|
// src/core/telegram/sync-send-outcome.ts
|
|
97727
|
-
var MS_PER_S5 = 1e3;
|
|
97728
97829
|
var RANDOM_ID_DUPLICATE = "RANDOM_ID_DUPLICATE";
|
|
97729
97830
|
var CALL_TIMEOUT = "TIMEOUT";
|
|
97730
97831
|
var REFUSAL_CODES = [400, 403, 406];
|
|
@@ -97764,9 +97865,9 @@ function refusedSend(code, what, name) {
|
|
|
97764
97865
|
return new ToolError(code, `${what} (${name}); nothing was sent.`);
|
|
97765
97866
|
}
|
|
97766
97867
|
function rateLimitSecondsOf(error62) {
|
|
97767
|
-
const
|
|
97768
|
-
if (!RATE_LIMIT_ERRORS.includes(
|
|
97769
|
-
const digits = /\d+$/.exec(
|
|
97868
|
+
const text2 = String(error62.text);
|
|
97869
|
+
if (!RATE_LIMIT_ERRORS.includes(text2.replace(/\d+$/, "%d"))) return void 0;
|
|
97870
|
+
const digits = /\d+$/.exec(text2);
|
|
97770
97871
|
return floodWaitSecondsOf(error62) ?? (digits ? Number(digits[0]) : void 0);
|
|
97771
97872
|
}
|
|
97772
97873
|
function refusalOf(error62) {
|
|
@@ -97807,7 +97908,7 @@ function sentMessageOf(response, randomId) {
|
|
|
97807
97908
|
return {
|
|
97808
97909
|
form: "short",
|
|
97809
97910
|
id: response.id,
|
|
97810
|
-
date: response.date *
|
|
97911
|
+
date: response.date * MS_PER_S,
|
|
97811
97912
|
ttl: response.ttlPeriod ?? null,
|
|
97812
97913
|
entities: response.entities ?? []
|
|
97813
97914
|
};
|
|
@@ -97898,8 +97999,8 @@ function checkSendable(mirror, { chat, topic, reply_to }) {
|
|
|
97898
97999
|
throw new ToolError("not_found", `No message ${reply_to} in this chat to reply to; nothing was sent.`);
|
|
97899
98000
|
}
|
|
97900
98001
|
}
|
|
97901
|
-
function deliveredId(mirror, chat,
|
|
97902
|
-
const rows = mirror.prepare("SELECT id FROM messages WHERE chat = ? AND from_me = 1 AND body = ? AND ts >= ? LIMIT 2").all(chat,
|
|
98002
|
+
function deliveredId(mirror, chat, text2, startedAt) {
|
|
98003
|
+
const rows = mirror.prepare("SELECT id FROM messages WHERE chat = ? AND from_me = 1 AND body = ? AND ts >= ? LIMIT 2").all(chat, text2, startedAt - DUPLICATE_LOOKBACK_MS);
|
|
97903
98004
|
return rows.length === 1 ? rows[0].id : void 0;
|
|
97904
98005
|
}
|
|
97905
98006
|
function deliveredFileIds(mirror, chat, files, startedAt) {
|
|
@@ -97973,9 +98074,9 @@ function replyToOf({
|
|
|
97973
98074
|
return { _: "inputReplyToMessage", replyToMsgId, ...inTopic2 === void 0 ? {} : { topMsgId: inTopic2 } };
|
|
97974
98075
|
}
|
|
97975
98076
|
function untilAborted(promise2, signal) {
|
|
97976
|
-
return new Promise((
|
|
98077
|
+
return new Promise((resolve6, reject) => {
|
|
97977
98078
|
const stopListening = onAbort(signal, () => reject(signal.reason));
|
|
97978
|
-
promise2.then(
|
|
98079
|
+
promise2.then(resolve6, reject).then(stopListening);
|
|
97979
98080
|
});
|
|
97980
98081
|
}
|
|
97981
98082
|
async function callOnce(ctx, signal, what, call, settle3) {
|
|
@@ -98075,12 +98176,27 @@ function sendRequest(ctx, queue, raw, call) {
|
|
|
98075
98176
|
}
|
|
98076
98177
|
|
|
98077
98178
|
// src/core/telegram/sync-action.ts
|
|
98078
|
-
function
|
|
98179
|
+
function runAction(ctx, queue, raw, call, parse6, act) {
|
|
98180
|
+
const params = parse6(raw);
|
|
98181
|
+
const signal = AbortSignal.any([call.signal, ctx.signal]);
|
|
98182
|
+
return queue.run(signal, () => act(params, signal));
|
|
98183
|
+
}
|
|
98184
|
+
async function resolveChatPeer(ctx, call, signal, what, chat) {
|
|
98185
|
+
const peer = await viaTelegram(ctx, call, what, () => ctx.client.resolvePeer(Number(chat)));
|
|
98186
|
+
if (signal.aborted) throw cancelled();
|
|
98187
|
+
return peer;
|
|
98188
|
+
}
|
|
98189
|
+
function inputChannelOf(peer) {
|
|
98190
|
+
if (peer._ !== "inputPeerChannel") return void 0;
|
|
98191
|
+
const { channelId, accessHash } = peer;
|
|
98192
|
+
return { _: "inputChannel", channelId, accessHash };
|
|
98193
|
+
}
|
|
98194
|
+
function performAction(ctx, signal, refusals, request) {
|
|
98079
98195
|
return callOnce(
|
|
98080
98196
|
ctx,
|
|
98081
98197
|
signal,
|
|
98082
98198
|
refusals.words.name,
|
|
98083
|
-
call,
|
|
98199
|
+
(options) => ctx.client.call(request, options),
|
|
98084
98200
|
(error62, trouble) => actionFailureOf(error62, trouble, refusals)
|
|
98085
98201
|
);
|
|
98086
98202
|
}
|
|
@@ -98161,10 +98277,9 @@ var DELETE_REFUSALS = {
|
|
|
98161
98277
|
}
|
|
98162
98278
|
]
|
|
98163
98279
|
};
|
|
98164
|
-
function requestOf(
|
|
98165
|
-
if (
|
|
98166
|
-
|
|
98167
|
-
return { _: "channels.deleteMessages", channel: { _: "inputChannel", channelId, accessHash }, id: [id] };
|
|
98280
|
+
function requestOf(channel, id) {
|
|
98281
|
+
if (!channel) return { _: "messages.deleteMessages", revoke: true, id: [id] };
|
|
98282
|
+
return { _: "channels.deleteMessages", channel, id: [id] };
|
|
98168
98283
|
}
|
|
98169
98284
|
function recordDelete(ctx, { id: chat, kind }, id) {
|
|
98170
98285
|
recordAction(ctx, "delete", () => {
|
|
@@ -98180,22 +98295,17 @@ function recordDelete(ctx, { id: chat, kind }, id) {
|
|
|
98180
98295
|
async function deleteOwn(ctx, call, signal, params) {
|
|
98181
98296
|
const { chat, message: message2 } = targetOf(ctx.mirror, params.chat, params.id, DELETE_WORDS);
|
|
98182
98297
|
if (!message2) return { id: params.id, deleted: true, already: true };
|
|
98183
|
-
const
|
|
98184
|
-
|
|
98185
|
-
|
|
98186
|
-
const affected = await performAction(ctx, signal, DELETE_REFUSALS, (options) => ctx.client.call(request, options));
|
|
98187
|
-
if (affected) handOverAffected(ctx, "delete", affected, peer._ === "inputPeerChannel" ? peer.channelId : void 0);
|
|
98298
|
+
const channel = inputChannelOf(await resolveChatPeer(ctx, call, signal, "delete", params.chat));
|
|
98299
|
+
const affected = await performAction(ctx, signal, DELETE_REFUSALS, requestOf(channel, params.id));
|
|
98300
|
+
if (affected) handOverAffected(ctx, "delete", affected, channel?.channelId);
|
|
98188
98301
|
recordDelete(ctx, chat, params.id);
|
|
98189
98302
|
return { id: params.id, deleted: true, ...!affected || affected.ptsCount === 0 ? { already: true } : {} };
|
|
98190
98303
|
}
|
|
98191
98304
|
function deleteRequest(ctx, queue, raw, call) {
|
|
98192
|
-
|
|
98193
|
-
const signal = AbortSignal.any([call.signal, ctx.signal]);
|
|
98194
|
-
return queue.run(signal, () => deleteOwn(ctx, call, signal, params));
|
|
98305
|
+
return runAction(ctx, queue, raw, call, parseDeleteParams, (params, signal) => deleteOwn(ctx, call, signal, params));
|
|
98195
98306
|
}
|
|
98196
98307
|
|
|
98197
98308
|
// src/core/telegram/sync-edit.ts
|
|
98198
|
-
var MS_PER_S6 = 1e3;
|
|
98199
98309
|
var EDIT_WORDS = {
|
|
98200
98310
|
name: "edit",
|
|
98201
98311
|
gerund: "editing",
|
|
@@ -98218,10 +98328,10 @@ var EDIT_REFUSALS = {
|
|
|
98218
98328
|
{ names: ["MEDIA_CAPTION_TOO_LONG"], code: "invalid_argument", what: "Telegram refused the caption" }
|
|
98219
98329
|
]
|
|
98220
98330
|
};
|
|
98221
|
-
function refuseUneditable({ message: message2 },
|
|
98331
|
+
function refuseUneditable({ message: message2 }, text2) {
|
|
98222
98332
|
if (!message2) throw deletedMessage();
|
|
98223
98333
|
const captioned = message2.media !== null && takesCaption(JSON.parse(message2.media).type);
|
|
98224
|
-
checkEditable({ ...message2, captioned },
|
|
98334
|
+
checkEditable({ ...message2, captioned }, text2);
|
|
98225
98335
|
}
|
|
98226
98336
|
function editedOf(group, id) {
|
|
98227
98337
|
for (const update of group.updates) {
|
|
@@ -98238,10 +98348,10 @@ function recordEdit(ctx, { chat }, raw, group) {
|
|
|
98238
98348
|
recordSent(ctx.mirror, { now: now(), keepDisappearing }, read, channels);
|
|
98239
98349
|
});
|
|
98240
98350
|
}
|
|
98241
|
-
function alreadyResult(ctx, { chat, id, text }) {
|
|
98351
|
+
function alreadyResult(ctx, { chat, id, text: text2 }) {
|
|
98242
98352
|
try {
|
|
98243
98353
|
const stored = storedMessageOf(ctx.mirror, chat, id);
|
|
98244
|
-
if (stored?.body ===
|
|
98354
|
+
if (stored?.body === text2 && stored.edited !== null) return { id, edited: stored.edited, already: true };
|
|
98245
98355
|
} catch (error62) {
|
|
98246
98356
|
ctx.settings.log(`edit: the mirror could not be read (${errorLabel(error62)})`);
|
|
98247
98357
|
}
|
|
@@ -98255,25 +98365,22 @@ function acceptedResult2(ctx, params, response) {
|
|
|
98255
98365
|
throw uncertainAction(EDIT_WORDS, "Telegram's answer did not name the edited message");
|
|
98256
98366
|
}
|
|
98257
98367
|
recordEdit(ctx, params, raw, group);
|
|
98258
|
-
return { id: params.id, edited: raw.editDate *
|
|
98368
|
+
return { id: params.id, edited: raw.editDate * MS_PER_S };
|
|
98259
98369
|
}
|
|
98260
98370
|
async function editText(ctx, call, signal, params) {
|
|
98261
98371
|
refuseUneditable(targetOf(ctx.mirror, params.chat, params.id, EDIT_WORDS), params.text);
|
|
98262
|
-
const peer = await
|
|
98263
|
-
if (signal.aborted) throw cancelled();
|
|
98372
|
+
const peer = await resolveChatPeer(ctx, call, signal, "edit", params.chat);
|
|
98264
98373
|
const request = {
|
|
98265
98374
|
_: "messages.editMessage",
|
|
98266
98375
|
peer,
|
|
98267
98376
|
id: params.id,
|
|
98268
98377
|
message: params.text
|
|
98269
98378
|
};
|
|
98270
|
-
const response = await performAction(ctx, signal, EDIT_REFUSALS,
|
|
98379
|
+
const response = await performAction(ctx, signal, EDIT_REFUSALS, request);
|
|
98271
98380
|
return response === void 0 ? alreadyResult(ctx, params) : acceptedResult2(ctx, params, response);
|
|
98272
98381
|
}
|
|
98273
98382
|
function editRequest(ctx, queue, raw, call) {
|
|
98274
|
-
|
|
98275
|
-
const signal = AbortSignal.any([call.signal, ctx.signal]);
|
|
98276
|
-
return queue.run(signal, () => editText(ctx, call, signal, params));
|
|
98383
|
+
return runAction(ctx, queue, raw, call, parseEditParams, (params, signal) => editText(ctx, call, signal, params));
|
|
98277
98384
|
}
|
|
98278
98385
|
|
|
98279
98386
|
// src/core/telegram/sync-mark-read.ts
|
|
@@ -98290,9 +98397,9 @@ var MARK_READ_REFUSALS = {
|
|
|
98290
98397
|
};
|
|
98291
98398
|
function requestOf2(peer, { up_to, topic }) {
|
|
98292
98399
|
if (topic !== void 0) return { _: "messages.readDiscussion", peer, msgId: topic, readMaxId: up_to };
|
|
98293
|
-
|
|
98294
|
-
|
|
98295
|
-
return { _: "channels.readHistory", channel
|
|
98400
|
+
const channel = inputChannelOf(peer);
|
|
98401
|
+
if (!channel) return { _: "messages.readHistory", peer, maxId: up_to };
|
|
98402
|
+
return { _: "channels.readHistory", channel, maxId: up_to };
|
|
98296
98403
|
}
|
|
98297
98404
|
function unreadPast(mirror, chat, readMax) {
|
|
98298
98405
|
const row = mirror.prepare("SELECT COUNT(*) AS unread FROM messages WHERE chat = ? AND from_me = 0 AND id > ?").get(chat, readMax);
|
|
@@ -98318,23 +98425,19 @@ async function markRead(ctx, call, signal, params) {
|
|
|
98318
98425
|
checkInTopic(message2.topic, topic, MARK_READ_WORDS.past);
|
|
98319
98426
|
const done = { chat, up_to, ...topic === void 0 ? {} : { topic } };
|
|
98320
98427
|
if (topic === void 0 && row.read_max !== null && row.read_max >= up_to) return { ...done, already: true };
|
|
98321
|
-
const peer = await
|
|
98322
|
-
if (signal.aborted) throw cancelled();
|
|
98323
|
-
const request = requestOf2(peer, params);
|
|
98428
|
+
const peer = await resolveChatPeer(ctx, call, signal, "mark read", chat);
|
|
98324
98429
|
const answer = await performAction(
|
|
98325
98430
|
ctx,
|
|
98326
98431
|
signal,
|
|
98327
98432
|
MARK_READ_REFUSALS,
|
|
98328
|
-
(
|
|
98433
|
+
requestOf2(peer, params)
|
|
98329
98434
|
);
|
|
98330
98435
|
if (typeof answer === "object") handOverAffected(ctx, "mark read", answer);
|
|
98331
98436
|
if (topic === void 0) recordRead(ctx, params);
|
|
98332
98437
|
return done;
|
|
98333
98438
|
}
|
|
98334
98439
|
function markReadRequest(ctx, queue, raw, call) {
|
|
98335
|
-
|
|
98336
|
-
const signal = AbortSignal.any([call.signal, ctx.signal]);
|
|
98337
|
-
return queue.run(signal, () => markRead(ctx, call, signal, params));
|
|
98440
|
+
return runAction(ctx, queue, raw, call, parseMarkReadParams, (params, signal) => markRead(ctx, call, signal, params));
|
|
98338
98441
|
}
|
|
98339
98442
|
|
|
98340
98443
|
// src/core/telegram/sync-pin.ts
|
|
@@ -98384,8 +98487,7 @@ async function pinMessage2(ctx, call, signal, params) {
|
|
|
98384
98487
|
const unpin = params.unpin === true;
|
|
98385
98488
|
const { chat } = anyMessageOf(ctx.mirror, params.chat, params.id, unpin ? UNPIN_WORDS : PIN_WORDS);
|
|
98386
98489
|
checkBothSides(chat.kind, params.both_sides);
|
|
98387
|
-
const peer = await
|
|
98388
|
-
if (signal.aborted) throw cancelled();
|
|
98490
|
+
const peer = await resolveChatPeer(ctx, call, signal, "pin", params.chat);
|
|
98389
98491
|
const request = {
|
|
98390
98492
|
_: "messages.updatePinnedMessage",
|
|
98391
98493
|
peer,
|
|
@@ -98394,21 +98496,14 @@ async function pinMessage2(ctx, call, signal, params) {
|
|
|
98394
98496
|
...unpin ? { unpin } : {},
|
|
98395
98497
|
...isPrivateChat(chat.kind) && !params.both_sides ? { pmOneside: true } : {}
|
|
98396
98498
|
};
|
|
98397
|
-
const response = await performAction(
|
|
98398
|
-
ctx,
|
|
98399
|
-
signal,
|
|
98400
|
-
unpin ? UNPIN_REFUSALS : PIN_REFUSALS,
|
|
98401
|
-
(options) => ctx.client.call(request, options)
|
|
98402
|
-
);
|
|
98499
|
+
const response = await performAction(ctx, signal, unpin ? UNPIN_REFUSALS : PIN_REFUSALS, request);
|
|
98403
98500
|
if (response === void 0) return { id: params.id, pinned: !unpin, already: true };
|
|
98404
98501
|
handOver(ctx, response, "pin");
|
|
98405
98502
|
recordServiceMessages(ctx, params.chat, response);
|
|
98406
98503
|
return { id: params.id, pinned: !unpin };
|
|
98407
98504
|
}
|
|
98408
98505
|
function pinRequest(ctx, queue, raw, call) {
|
|
98409
|
-
|
|
98410
|
-
const signal = AbortSignal.any([call.signal, ctx.signal]);
|
|
98411
|
-
return queue.run(signal, () => pinMessage2(ctx, call, signal, params));
|
|
98506
|
+
return runAction(ctx, queue, raw, call, parsePinParams, (params, signal) => pinMessage2(ctx, call, signal, params));
|
|
98412
98507
|
}
|
|
98413
98508
|
|
|
98414
98509
|
// src/core/telegram/sync-react.ts
|
|
@@ -98474,24 +98569,21 @@ async function reactTo(ctx, call, signal, params) {
|
|
|
98474
98569
|
if (params.emoji !== void 0 && ownReaction(storedReactions(message2.reactions)) === params.emoji) {
|
|
98475
98570
|
return { ...doneOf(params), already: true };
|
|
98476
98571
|
}
|
|
98477
|
-
const peer = await
|
|
98478
|
-
if (signal.aborted) throw cancelled();
|
|
98572
|
+
const peer = await resolveChatPeer(ctx, call, signal, "react", params.chat);
|
|
98479
98573
|
const request = {
|
|
98480
98574
|
_: "messages.sendReaction",
|
|
98481
98575
|
peer,
|
|
98482
98576
|
msgId: params.id,
|
|
98483
98577
|
reaction: params.emoji === void 0 ? [] : [{ _: "reactionEmoji", emoticon: params.emoji }]
|
|
98484
98578
|
};
|
|
98485
|
-
const response = await performAction(ctx, signal, REACT_REFUSALS,
|
|
98579
|
+
const response = await performAction(ctx, signal, REACT_REFUSALS, request);
|
|
98486
98580
|
if (response === void 0) return { ...doneOf(params), already: true };
|
|
98487
98581
|
handOver(ctx, response, "react");
|
|
98488
98582
|
recordReaction(ctx, params, response);
|
|
98489
98583
|
return doneOf(params);
|
|
98490
98584
|
}
|
|
98491
98585
|
function reactRequest(ctx, queue, raw, call) {
|
|
98492
|
-
|
|
98493
|
-
const signal = AbortSignal.any([call.signal, ctx.signal]);
|
|
98494
|
-
return queue.run(signal, () => reactTo(ctx, call, signal, params));
|
|
98586
|
+
return runAction(ctx, queue, raw, call, parseReactParams, (params, signal) => reactTo(ctx, call, signal, params));
|
|
98495
98587
|
}
|
|
98496
98588
|
|
|
98497
98589
|
// src/core/telegram/sync-send-outbox.ts
|
|
@@ -98567,7 +98659,7 @@ function uploadFailure(ctx, signal, error62, name) {
|
|
|
98567
98659
|
return refusal ?? new ToolError("upstream_error", `The upload of ${name} failed (${errorLabel(error62)}); nothing was sent.`);
|
|
98568
98660
|
}
|
|
98569
98661
|
async function uploadOne(ctx, signal, file2) {
|
|
98570
|
-
const stallMs = ctx.settings.
|
|
98662
|
+
const stallMs = ctx.settings.transferStallMs;
|
|
98571
98663
|
const stall = new AbortController();
|
|
98572
98664
|
const uploadSignal = AbortSignal.any([signal, stall.signal]);
|
|
98573
98665
|
let stalled2 = false;
|
|
@@ -99158,6 +99250,7 @@ function toolContext(command, io) {
|
|
|
99158
99250
|
downloadMaxMb: command.downloadMaxMb,
|
|
99159
99251
|
sendDirs: command.sendDirs,
|
|
99160
99252
|
programName: PROJECT.name,
|
|
99253
|
+
options: command.options,
|
|
99161
99254
|
signal: io.signal
|
|
99162
99255
|
};
|
|
99163
99256
|
}
|
|
@@ -99199,16 +99292,18 @@ function parseCommand(argv, io) {
|
|
|
99199
99292
|
if (cwd === void 0) throw usageError2(`Command ${name} needs ${CWD_FLAG} <dir>.`);
|
|
99200
99293
|
if (name === "target") {
|
|
99201
99294
|
const { value: language, rest: afterLanguage } = takeFlag(rest, LANGUAGE_FLAG);
|
|
99202
|
-
const { value: harnessLanguage, rest:
|
|
99203
|
-
const
|
|
99295
|
+
const { value: harnessLanguage, rest: optionFlags } = takeFlag(afterLanguage, HARNESS_LANGUAGE_FLAG);
|
|
99296
|
+
const parsedOptions = parseToolOptions(optionFlags, io.env, profile);
|
|
99297
|
+
const directories = resolveDirectorySettings(parsedOptions, io.env, profile);
|
|
99204
99298
|
return {
|
|
99205
99299
|
name,
|
|
99206
99300
|
toolId,
|
|
99207
99301
|
cwd,
|
|
99208
|
-
stateDir:
|
|
99209
|
-
downloadDir:
|
|
99210
|
-
downloadMaxMb:
|
|
99211
|
-
sendDirs:
|
|
99302
|
+
stateDir: directories.state_dir,
|
|
99303
|
+
downloadDir: directories.download_dir,
|
|
99304
|
+
downloadMaxMb: directories.download_max_mb,
|
|
99305
|
+
sendDirs: directories.send_dirs,
|
|
99306
|
+
options: parsedOptions,
|
|
99212
99307
|
language: promptLanguage(language, io.env, harnessLanguage, profile)
|
|
99213
99308
|
};
|
|
99214
99309
|
}
|
|
@@ -99226,7 +99321,8 @@ function parseCommand(argv, io) {
|
|
|
99226
99321
|
stateDir: settings.state_dir,
|
|
99227
99322
|
downloadDir: settings.download_dir,
|
|
99228
99323
|
downloadMaxMb: settings.download_max_mb,
|
|
99229
|
-
sendDirs: settings.send_dirs
|
|
99324
|
+
sendDirs: settings.send_dirs,
|
|
99325
|
+
options: settings.options
|
|
99230
99326
|
};
|
|
99231
99327
|
}
|
|
99232
99328
|
function describeSpec(spec) {
|
|
@@ -99251,10 +99347,10 @@ function writeError(io, code, message2, details) {
|
|
|
99251
99347
|
return EXIT_FAILED;
|
|
99252
99348
|
}
|
|
99253
99349
|
async function readArguments(io) {
|
|
99254
|
-
const
|
|
99255
|
-
if (
|
|
99350
|
+
const text2 = await io.readStdin();
|
|
99351
|
+
if (text2.trim() === "") return {};
|
|
99256
99352
|
try {
|
|
99257
|
-
return JSON.parse(
|
|
99353
|
+
return JSON.parse(text2);
|
|
99258
99354
|
} catch (error62) {
|
|
99259
99355
|
throw new ToolError("invalid_argument", "The arguments on standard input are not valid JSON.", { cause: error62 });
|
|
99260
99356
|
}
|
|
@@ -99354,8 +99450,8 @@ async function main() {
|
|
|
99354
99450
|
env: process.env,
|
|
99355
99451
|
ownDir: packageRoot(import.meta.url),
|
|
99356
99452
|
readStdin,
|
|
99357
|
-
stdout: (
|
|
99358
|
-
stderr: (
|
|
99453
|
+
stdout: (text2) => process.stdout.write(text2),
|
|
99454
|
+
stderr: (text2) => process.stderr.write(text2),
|
|
99359
99455
|
signal: controller.signal
|
|
99360
99456
|
});
|
|
99361
99457
|
if (argv[0] === "target") process.stdout.write("", () => process.stderr.write("", () => process.exit()));
|