@craftsamo/telegram-tools 0.2.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 +524 -463
- package/dist/mcp.js +307 -217
- package/dist/opencode.js +335 -250
- 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/opencode.js
CHANGED
|
@@ -25,6 +25,21 @@ var PROJECT = {
|
|
|
25
25
|
toolsets: ["account", "chats", "sync", "files", "sends", "actions"],
|
|
26
26
|
/** The toolsets on when a setting names none. */
|
|
27
27
|
defaultToolsets: ["account", "chats", "sync", "sends"],
|
|
28
|
+
/** The package's own settings, which the tools themselves read: each snake_case name and its type, with bounds when it needs them. */
|
|
29
|
+
options: {
|
|
30
|
+
/** Where every account's state lives. */
|
|
31
|
+
state_dir: "path",
|
|
32
|
+
/** Where received files are saved. */
|
|
33
|
+
download_dir: "path",
|
|
34
|
+
/** The largest received file a call may download, in megabytes. */
|
|
35
|
+
download_max_mb: { type: "number", integer: true, min: 1, max: 2e3 },
|
|
36
|
+
/** The directories files may be sent from, besides the working directory. */
|
|
37
|
+
send_dirs: "paths",
|
|
38
|
+
/** Whether messages that disappear are kept; read by the sync service's commands. */
|
|
39
|
+
keep_disappearing: "boolean",
|
|
40
|
+
/** Whether channels are listed and their messages received; read by the sync service's commands. */
|
|
41
|
+
channels: "boolean"
|
|
42
|
+
},
|
|
28
43
|
/** The environment variables the tools read besides the settings, which Codex forwards to the server after them. */
|
|
29
44
|
toolVariables: []
|
|
30
45
|
};
|
|
@@ -5099,7 +5114,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
|
|
|
5099
5114
|
var NONE = 0;
|
|
5100
5115
|
var ASSUMED = 1;
|
|
5101
5116
|
var PROVEN = 2;
|
|
5102
|
-
function isRecursive(inst, stack,
|
|
5117
|
+
function isRecursive(inst, stack, resolve6) {
|
|
5103
5118
|
const cached2 = recursive.get(inst);
|
|
5104
5119
|
if (cached2 !== void 0)
|
|
5105
5120
|
return cached2 ? PROVEN : NONE;
|
|
@@ -5109,7 +5124,7 @@ function isRecursive(inst, stack, resolve8) {
|
|
|
5109
5124
|
let result = NONE;
|
|
5110
5125
|
const check2 = (child) => {
|
|
5111
5126
|
if (result !== PROVEN && child?._zod) {
|
|
5112
|
-
const answer = isRecursive(child, stack,
|
|
5127
|
+
const answer = isRecursive(child, stack, resolve6);
|
|
5113
5128
|
if (answer > result)
|
|
5114
5129
|
result = answer;
|
|
5115
5130
|
}
|
|
@@ -5120,7 +5135,7 @@ function isRecursive(inst, stack, resolve8) {
|
|
|
5120
5135
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
5121
5136
|
if (spread && !desc.enumerable)
|
|
5122
5137
|
continue;
|
|
5123
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
5138
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve6) : NONE;
|
|
5124
5139
|
if (child > answer)
|
|
5125
5140
|
answer = child;
|
|
5126
5141
|
}
|
|
@@ -5184,7 +5199,7 @@ function isRecursive(inst, stack, resolve8) {
|
|
|
5184
5199
|
break;
|
|
5185
5200
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
5186
5201
|
case "lazy": {
|
|
5187
|
-
const inner = def._cachedInner ?? (
|
|
5202
|
+
const inner = def._cachedInner ?? (resolve6 ? inst._zod.innerType : void 0);
|
|
5188
5203
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
5189
5204
|
break;
|
|
5190
5205
|
}
|
|
@@ -9382,8 +9397,8 @@ function ko_default() {
|
|
|
9382
9397
|
}
|
|
9383
9398
|
|
|
9384
9399
|
// node_modules/.pnpm/zod@4.6.7/node_modules/zod/v4/locales/lt.js
|
|
9385
|
-
var capitalizeFirstCharacter = (
|
|
9386
|
-
return
|
|
9400
|
+
var capitalizeFirstCharacter = (text2) => {
|
|
9401
|
+
return text2.charAt(0).toUpperCase() + text2.slice(1);
|
|
9387
9402
|
};
|
|
9388
9403
|
function getUnitTypeFromNumber(number4) {
|
|
9389
9404
|
const abs = Math.abs(number4);
|
|
@@ -19788,8 +19803,8 @@ function quoteBadLabel(value) {
|
|
|
19788
19803
|
const truncated = value.length > MAX_BAD_LABEL_PREVIEW ? `${value.slice(0, MAX_BAD_LABEL_PREVIEW)}\u2026` : value;
|
|
19789
19804
|
return JSON.stringify(truncated);
|
|
19790
19805
|
}
|
|
19791
|
-
function isLabel(
|
|
19792
|
-
return typeof
|
|
19806
|
+
function isLabel(text2) {
|
|
19807
|
+
return typeof text2 === "string" && LABEL_PATTERN.test(text2);
|
|
19793
19808
|
}
|
|
19794
19809
|
function checkLabel(label) {
|
|
19795
19810
|
if (!isLabel(label)) {
|
|
@@ -20028,10 +20043,10 @@ var MILLISECOND_DIGITS = 3;
|
|
|
20028
20043
|
var MIN_YEAR = 1e3;
|
|
20029
20044
|
var MAX_HOUR = 23;
|
|
20030
20045
|
var MAX_MINUTE = 59;
|
|
20031
|
-
function badTime(
|
|
20046
|
+
function badTime(text2, name) {
|
|
20032
20047
|
return new ToolError(
|
|
20033
20048
|
"invalid_argument",
|
|
20034
|
-
`${name} is not a time: ${JSON.stringify(
|
|
20049
|
+
`${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.`
|
|
20035
20050
|
);
|
|
20036
20051
|
}
|
|
20037
20052
|
function isCalendarDay(year, month, day) {
|
|
@@ -20039,21 +20054,21 @@ function isCalendarDay(year, month, day) {
|
|
|
20039
20054
|
date5.setUTCFullYear(year, month - 1, day);
|
|
20040
20055
|
return date5.getUTCFullYear() === year && date5.getUTCMonth() === month - 1 && date5.getUTCDate() === day;
|
|
20041
20056
|
}
|
|
20042
|
-
function parseTimeArgument(
|
|
20043
|
-
const match = TIME_PATTERN.exec(
|
|
20044
|
-
if (!match) throw badTime(
|
|
20057
|
+
function parseTimeArgument(text2, name) {
|
|
20058
|
+
const match = TIME_PATTERN.exec(text2.trim());
|
|
20059
|
+
if (!match) throw badTime(text2, name);
|
|
20045
20060
|
const [, year, month, day, hour = "0", minute = "0", second = "0", fraction = "", zulu, sign, offsetHour, offsetMin] = match;
|
|
20046
20061
|
const [y, mon, d, h, mi, s] = [year, month, day, hour, minute, second].map(Number);
|
|
20047
20062
|
const ms = Number(fraction.padEnd(MILLISECOND_DIGITS, "0").slice(0, MILLISECOND_DIGITS));
|
|
20048
20063
|
if (y < MIN_YEAR || !isCalendarDay(y, mon, d) || h > MAX_HOUR || mi > MAX_MINUTE || s > MAX_MINUTE) {
|
|
20049
|
-
throw badTime(
|
|
20064
|
+
throw badTime(text2, name);
|
|
20050
20065
|
}
|
|
20051
20066
|
if (sign === void 0 && zulu === void 0) return new Date(y, mon - 1, d, h, mi, s, ms).getTime();
|
|
20052
20067
|
const wall = Date.UTC(y, mon - 1, d, h, mi, s, ms);
|
|
20053
20068
|
if (zulu) return wall;
|
|
20054
20069
|
const offsetH = Number(offsetHour);
|
|
20055
20070
|
const offsetM = Number(offsetMin);
|
|
20056
|
-
if (offsetH > MAX_HOUR || offsetM > MAX_MINUTE) throw badTime(
|
|
20071
|
+
if (offsetH > MAX_HOUR || offsetM > MAX_MINUTE) throw badTime(text2, name);
|
|
20057
20072
|
const offset = (offsetH * MINUTES_PER_HOUR + offsetM) * MS_PER_MINUTE;
|
|
20058
20073
|
return sign === "-" ? wall + offset : wall - offset;
|
|
20059
20074
|
}
|
|
@@ -20388,23 +20403,23 @@ function encodeCursor(value) {
|
|
|
20388
20403
|
function notACursor(name) {
|
|
20389
20404
|
return new ToolError("invalid_argument", `${name} is not a cursor this tool returned.`);
|
|
20390
20405
|
}
|
|
20391
|
-
function decodeCursor(
|
|
20392
|
-
const bytes = Buffer3.from(
|
|
20393
|
-
if (bytes.toString("base64url") !==
|
|
20406
|
+
function decodeCursor(text2, name) {
|
|
20407
|
+
const bytes = Buffer3.from(text2, "base64url");
|
|
20408
|
+
if (bytes.toString("base64url") !== text2) throw notACursor(name);
|
|
20394
20409
|
try {
|
|
20395
20410
|
return JSON.parse(bytes.toString("utf8"));
|
|
20396
20411
|
} catch {
|
|
20397
20412
|
throw notACursor(name);
|
|
20398
20413
|
}
|
|
20399
20414
|
}
|
|
20400
|
-
function readCursor(
|
|
20401
|
-
const parsed = schema.safeParse(decodeCursor(
|
|
20415
|
+
function readCursor(text2, name, schema) {
|
|
20416
|
+
const parsed = schema.safeParse(decodeCursor(text2, name));
|
|
20402
20417
|
if (!parsed.success) throw notACursor(name);
|
|
20403
20418
|
return parsed.data;
|
|
20404
20419
|
}
|
|
20405
20420
|
var HIGH_SURROGATE = /[\uD800-\uDBFF]$/;
|
|
20406
|
-
function cutText(
|
|
20407
|
-
return
|
|
20421
|
+
function cutText(text2, keep) {
|
|
20422
|
+
return text2.length <= keep ? text2 : text2.slice(0, keep).replace(HIGH_SURROGATE, "");
|
|
20408
20423
|
}
|
|
20409
20424
|
function jsonLength(value) {
|
|
20410
20425
|
return JSON.stringify(value).length;
|
|
@@ -20494,15 +20509,15 @@ var ERROR_CODES = {
|
|
|
20494
20509
|
function isErrorCode(value) {
|
|
20495
20510
|
return typeof value === "string" && Object.hasOwn(ERROR_CODES, value);
|
|
20496
20511
|
}
|
|
20497
|
-
function maskPhoneNumbers(
|
|
20498
|
-
return
|
|
20512
|
+
function maskPhoneNumbers(text2) {
|
|
20513
|
+
return text2.replace(PHONE_NUMBER, "[number]");
|
|
20499
20514
|
}
|
|
20500
20515
|
function cut(message) {
|
|
20501
20516
|
return maskPhoneNumbers(message).trim().slice(0, MAX_DETAIL_LENGTH);
|
|
20502
20517
|
}
|
|
20503
20518
|
function detail(message) {
|
|
20504
|
-
const
|
|
20505
|
-
return
|
|
20519
|
+
const text2 = cut(message);
|
|
20520
|
+
return text2 ? `: ${text2}` : "";
|
|
20506
20521
|
}
|
|
20507
20522
|
function afterWriteError(method, effect, reason) {
|
|
20508
20523
|
return effect === "write" ? new ToolError("uncertain", `${method} may have taken effect (${reason}). ${UNCERTAIN_ADVICE}`) : new ToolError("upstream_error", `${method} failed (${reason}).`);
|
|
@@ -20623,7 +20638,7 @@ function abortError(signal) {
|
|
|
20623
20638
|
}
|
|
20624
20639
|
function exec(argv, options) {
|
|
20625
20640
|
const { signal } = options;
|
|
20626
|
-
return new Promise((
|
|
20641
|
+
return new Promise((resolve6, reject) => {
|
|
20627
20642
|
if (signal?.aborted) {
|
|
20628
20643
|
reject(abortError(signal));
|
|
20629
20644
|
return;
|
|
@@ -20682,7 +20697,7 @@ function exec(argv, options) {
|
|
|
20682
20697
|
}
|
|
20683
20698
|
const finish = () => settle2(() => {
|
|
20684
20699
|
const { code, killedBy } = exitedWith ?? { code: null, killedBy: null };
|
|
20685
|
-
|
|
20700
|
+
resolve6({
|
|
20686
20701
|
code: code ?? -1,
|
|
20687
20702
|
stdout,
|
|
20688
20703
|
stderr,
|
|
@@ -20776,19 +20791,19 @@ var ServiceConnection = class _ServiceConnection {
|
|
|
20776
20791
|
socket.on("error", (error62) => {
|
|
20777
20792
|
this.endReason ??= `the connection to the service broke${error62.code ? ` (${error62.code})` : ""}`;
|
|
20778
20793
|
});
|
|
20779
|
-
this.closed = new Promise((
|
|
20794
|
+
this.closed = new Promise((resolve6) => {
|
|
20780
20795
|
socket.once("close", () => {
|
|
20781
20796
|
this.endReason ??= "the service closed the connection";
|
|
20782
20797
|
const lost = { lost: this.endReason };
|
|
20783
20798
|
for (const settle2 of [...this.pending.values()]) settle2(lost);
|
|
20784
|
-
|
|
20799
|
+
resolve6();
|
|
20785
20800
|
});
|
|
20786
20801
|
});
|
|
20787
20802
|
}
|
|
20788
20803
|
/** Connects to the service's socket; rejects as `upstream_error` when nothing is listening there. */
|
|
20789
20804
|
static connect(socketPath, options = {}) {
|
|
20790
20805
|
const { timeoutMs = DEFAULT_CONNECT_TIMEOUT_MS, signal, maxLineLength = DEFAULT_MAX_LINE_LENGTH } = options;
|
|
20791
|
-
return new Promise((
|
|
20806
|
+
return new Promise((resolve6, reject) => {
|
|
20792
20807
|
if (signal?.aborted) {
|
|
20793
20808
|
reject(abortError(signal));
|
|
20794
20809
|
return;
|
|
@@ -20810,7 +20825,7 @@ var ServiceConnection = class _ServiceConnection {
|
|
|
20810
20825
|
};
|
|
20811
20826
|
const onConnect = () => {
|
|
20812
20827
|
detach();
|
|
20813
|
-
|
|
20828
|
+
resolve6(new _ServiceConnection(socket, maxLineLength));
|
|
20814
20829
|
};
|
|
20815
20830
|
const onFailure = () => stop(new ToolError("upstream_error", NOT_RUNNING_MESSAGE));
|
|
20816
20831
|
const onAbort = () => stop(abortError(signal));
|
|
@@ -20833,7 +20848,7 @@ var ServiceConnection = class _ServiceConnection {
|
|
|
20833
20848
|
*/
|
|
20834
20849
|
call(method, params, options) {
|
|
20835
20850
|
const { effect, timeoutMs = DEFAULT_CALL_TIMEOUT_MS, signal } = options;
|
|
20836
|
-
return new Promise((
|
|
20851
|
+
return new Promise((resolve6, reject) => {
|
|
20837
20852
|
if (signal?.aborted) {
|
|
20838
20853
|
reject(abortError(signal));
|
|
20839
20854
|
return;
|
|
@@ -20862,7 +20877,7 @@ var ServiceConnection = class _ServiceConnection {
|
|
|
20862
20877
|
clearTimeout(timer);
|
|
20863
20878
|
signal?.removeEventListener("abort", onAbort);
|
|
20864
20879
|
try {
|
|
20865
|
-
|
|
20880
|
+
resolve6(produce());
|
|
20866
20881
|
} catch (error62) {
|
|
20867
20882
|
reject(error62);
|
|
20868
20883
|
}
|
|
@@ -21182,10 +21197,10 @@ function replyTo(parsed, related) {
|
|
|
21182
21197
|
if (reply.chat !== void 0) entry2.chat = reply.chat;
|
|
21183
21198
|
if (reply.topic !== void 0) entry2.topic = reply.topic;
|
|
21184
21199
|
if (reply.quote !== void 0) entry2.quote = reply.quote;
|
|
21185
|
-
const
|
|
21186
|
-
if (
|
|
21187
|
-
entry2.text = cutText(
|
|
21188
|
-
if (entry2.text.length <
|
|
21200
|
+
const text2 = repliedText(parsed, related)?.text;
|
|
21201
|
+
if (text2 !== void 0) {
|
|
21202
|
+
entry2.text = cutText(text2, REPLY_TEXT_LENGTH);
|
|
21203
|
+
if (entry2.text.length < text2.length) entry2.text_cut = true;
|
|
21189
21204
|
}
|
|
21190
21205
|
return entry2;
|
|
21191
21206
|
}
|
|
@@ -21254,25 +21269,25 @@ function texts(entry2) {
|
|
|
21254
21269
|
];
|
|
21255
21270
|
}
|
|
21256
21271
|
function messageTextLength(entry2) {
|
|
21257
|
-
return texts(entry2).reduce((total,
|
|
21272
|
+
return texts(entry2).reduce((total, text2) => total + text2.length, 0);
|
|
21258
21273
|
}
|
|
21259
21274
|
function cutMessage(entry2, keep) {
|
|
21260
21275
|
let room = keep;
|
|
21261
21276
|
let cut3 = false;
|
|
21262
|
-
const take = (
|
|
21263
|
-
const kept = cutText(
|
|
21264
|
-
room = Math.max(0, room -
|
|
21265
|
-
if (kept.length <
|
|
21277
|
+
const take = (text2) => {
|
|
21278
|
+
const kept = cutText(text2, room);
|
|
21279
|
+
room = Math.max(0, room - text2.length);
|
|
21280
|
+
if (kept.length < text2.length) cut3 = true;
|
|
21266
21281
|
return kept;
|
|
21267
21282
|
};
|
|
21268
21283
|
const cutEntry = { ...entry2 };
|
|
21269
21284
|
if (entry2.text !== void 0) cutEntry.text = take(entry2.text);
|
|
21270
21285
|
if (entry2.reply_to) {
|
|
21271
|
-
const { quote, text } = entry2.reply_to;
|
|
21286
|
+
const { quote, text: text2 } = entry2.reply_to;
|
|
21272
21287
|
cutEntry.reply_to = {
|
|
21273
21288
|
...entry2.reply_to,
|
|
21274
21289
|
...quote === void 0 ? {} : { quote: take(quote) },
|
|
21275
|
-
...
|
|
21290
|
+
...text2 === void 0 ? {} : { text: take(text2) }
|
|
21276
21291
|
};
|
|
21277
21292
|
}
|
|
21278
21293
|
if (entry2.earlier_versions)
|
|
@@ -21521,8 +21536,8 @@ function fetchResult(read, stored) {
|
|
|
21521
21536
|
}
|
|
21522
21537
|
|
|
21523
21538
|
// src/core/fold.ts
|
|
21524
|
-
function foldCase(
|
|
21525
|
-
return
|
|
21539
|
+
function foldCase(text2) {
|
|
21540
|
+
return text2.normalize("NFKC").toUpperCase().toLowerCase().replace(/ς/g, "\u03C3");
|
|
21526
21541
|
}
|
|
21527
21542
|
|
|
21528
21543
|
// src/core/chat/filter.ts
|
|
@@ -21661,8 +21676,8 @@ function foldedFileName(media) {
|
|
|
21661
21676
|
return isRecord(info) && typeof info.name === "string" ? foldCase(info.name) : void 0;
|
|
21662
21677
|
}
|
|
21663
21678
|
function matchesAllWords(row, words2) {
|
|
21664
|
-
const
|
|
21665
|
-
const unmatched = words2.filter((word) => !
|
|
21679
|
+
const text2 = foldCase(row.body ?? "");
|
|
21680
|
+
const unmatched = words2.filter((word) => !text2.includes(word));
|
|
21666
21681
|
if (unmatched.length === 0) return true;
|
|
21667
21682
|
const name = row.media === null ? void 0 : foldedFileName(row.media);
|
|
21668
21683
|
return name !== void 0 && unmatched.every((word) => name.includes(word));
|
|
@@ -22306,11 +22321,11 @@ var ANIMATED_STICKER = "an animated sticker (.tgs), which cannot be inspected";
|
|
|
22306
22321
|
function unreadableArchive(label) {
|
|
22307
22322
|
return `an archive that cannot be inspected (${label})`;
|
|
22308
22323
|
}
|
|
22309
|
-
function words(
|
|
22310
|
-
return
|
|
22324
|
+
function words(text2) {
|
|
22325
|
+
return text2.split(/\s+/).filter((word) => word !== "");
|
|
22311
22326
|
}
|
|
22312
|
-
function ascii(
|
|
22313
|
-
return Array.from(
|
|
22327
|
+
function ascii(text2) {
|
|
22328
|
+
return Array.from(text2, (character) => character.charCodeAt(0));
|
|
22314
22329
|
}
|
|
22315
22330
|
function at(offset, bytes) {
|
|
22316
22331
|
return { offset, bytes };
|
|
@@ -22568,9 +22583,9 @@ function parseHeader(block) {
|
|
|
22568
22583
|
}
|
|
22569
22584
|
return { path, size: parseNumber(block.subarray(SIZE_START, SIZE_END)), type: block[TYPE_OFFSET] };
|
|
22570
22585
|
}
|
|
22571
|
-
function parseDecimal(
|
|
22572
|
-
if (!/^[0-9]{1,15}$/.test(
|
|
22573
|
-
return Number(
|
|
22586
|
+
function parseDecimal(text2) {
|
|
22587
|
+
if (!/^[0-9]{1,15}$/.test(text2)) return void 0;
|
|
22588
|
+
return Number(text2);
|
|
22574
22589
|
}
|
|
22575
22590
|
function parsePaxRecords(data, maxRecords = Infinity) {
|
|
22576
22591
|
const records = [];
|
|
@@ -22760,8 +22775,8 @@ var EXTENSIONS = {
|
|
|
22760
22775
|
};
|
|
22761
22776
|
var KIND_PATTERN = /^[a-z]{1,16}$/;
|
|
22762
22777
|
var UNKNOWN_KIND = "file";
|
|
22763
|
-
function byteLength(
|
|
22764
|
-
return Buffer5.byteLength(
|
|
22778
|
+
function byteLength(text2) {
|
|
22779
|
+
return Buffer5.byteLength(text2);
|
|
22765
22780
|
}
|
|
22766
22781
|
function extensionOf2(type) {
|
|
22767
22782
|
return type == null ? "" : EXTENSIONS[type.split(";")[0].trim().toLowerCase()] ?? "";
|
|
@@ -23030,8 +23045,8 @@ function fitListings(result) {
|
|
|
23030
23045
|
var MAX_NAME_CHARACTERS = 255;
|
|
23031
23046
|
var CUT_MARK = "\u2026";
|
|
23032
23047
|
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;
|
|
23033
|
-
function cleanName(
|
|
23034
|
-
const cleaned =
|
|
23048
|
+
function cleanName(text2) {
|
|
23049
|
+
const cleaned = text2.normalize("NFC").replace(HIDDEN_CHARACTERS, "?");
|
|
23035
23050
|
const characters = Array.from(cleaned);
|
|
23036
23051
|
if (characters.length <= MAX_NAME_CHARACTERS) return cleaned;
|
|
23037
23052
|
return characters.slice(0, MAX_NAME_CHARACTERS - CUT_MARK.length).join("") + CUT_MARK;
|
|
@@ -23204,9 +23219,9 @@ function decodeUtf8Lossy(bytes) {
|
|
|
23204
23219
|
return LOSSY_UTF8.decode(bytes);
|
|
23205
23220
|
}
|
|
23206
23221
|
function decodeCp437(bytes) {
|
|
23207
|
-
let
|
|
23208
|
-
for (const byte of bytes)
|
|
23209
|
-
return
|
|
23222
|
+
let text2 = "";
|
|
23223
|
+
for (const byte of bytes) text2 += byte < ASCII_END ? String.fromCharCode(byte) : CP437_HIGH[byte - ASCII_END];
|
|
23224
|
+
return text2;
|
|
23210
23225
|
}
|
|
23211
23226
|
|
|
23212
23227
|
// src/core/archive/tar.ts
|
|
@@ -24265,14 +24280,14 @@ function storedReactions(json2) {
|
|
|
24265
24280
|
function ownReaction(reactions) {
|
|
24266
24281
|
return reactions.find((reaction2) => reaction2.mine)?.emoji;
|
|
24267
24282
|
}
|
|
24268
|
-
function checkEditable({ kind, body, captioned },
|
|
24283
|
+
function checkEditable({ kind, body, captioned }, text2) {
|
|
24269
24284
|
if (kind === "service" || body === null && !captioned) {
|
|
24270
24285
|
throw new ToolError("invalid_argument", "This message has no text or caption to edit; nothing was edited.");
|
|
24271
24286
|
}
|
|
24272
|
-
if (body ===
|
|
24287
|
+
if (body === text2) {
|
|
24273
24288
|
throw new ToolError("invalid_argument", "The text is the same as the message's; nothing to edit.");
|
|
24274
24289
|
}
|
|
24275
|
-
if (captioned &&
|
|
24290
|
+
if (captioned && text2.length > CAPTION_MAX_UNITS) {
|
|
24276
24291
|
throw new ToolError(
|
|
24277
24292
|
"invalid_argument",
|
|
24278
24293
|
`A caption must be at most ${CAPTION_MAX_UNITS} characters; nothing was edited.`
|
|
@@ -24281,8 +24296,8 @@ function checkEditable({ kind, body, captioned }, text) {
|
|
|
24281
24296
|
}
|
|
24282
24297
|
|
|
24283
24298
|
// src/core/message/arguments.ts
|
|
24284
|
-
function checkedText(
|
|
24285
|
-
const trimmed =
|
|
24299
|
+
function checkedText(text2) {
|
|
24300
|
+
const trimmed = text2.trim();
|
|
24286
24301
|
if (trimmed === "") throw new ToolError("invalid_argument", "text is blank; give the text to send.");
|
|
24287
24302
|
if (trimmed.length > TEXT_MAX_UNITS) {
|
|
24288
24303
|
throw new ToolError(
|
|
@@ -24340,8 +24355,8 @@ var Window = class {
|
|
|
24340
24355
|
get tail() {
|
|
24341
24356
|
return this.#tail;
|
|
24342
24357
|
}
|
|
24343
|
-
sees(
|
|
24344
|
-
const all = this.#tail +
|
|
24358
|
+
sees(text2) {
|
|
24359
|
+
const all = this.#tail + text2;
|
|
24345
24360
|
this.#tail = all.slice(-TAIL_LENGTH);
|
|
24346
24361
|
return MARKER.test(all);
|
|
24347
24362
|
}
|
|
@@ -24351,13 +24366,13 @@ var PrivateKeyScan = class {
|
|
|
24351
24366
|
#withoutNuls;
|
|
24352
24367
|
/** Feeds the next chunk; whether a marker starts anywhere in the bytes so far. */
|
|
24353
24368
|
sees(chunk) {
|
|
24354
|
-
const
|
|
24369
|
+
const text2 = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength).toString("latin1");
|
|
24355
24370
|
const before = this.#plain.tail;
|
|
24356
|
-
const plain2 = this.#plain.sees(
|
|
24357
|
-
if (this.#withoutNuls === void 0 &&
|
|
24371
|
+
const plain2 = this.#plain.sees(text2);
|
|
24372
|
+
if (this.#withoutNuls === void 0 && text2.includes(NUL)) {
|
|
24358
24373
|
this.#withoutNuls = new Window(before);
|
|
24359
24374
|
}
|
|
24360
|
-
const stripped = this.#withoutNuls?.sees(
|
|
24375
|
+
const stripped = this.#withoutNuls?.sees(text2.replaceAll(NUL, "")) ?? false;
|
|
24361
24376
|
return plain2 || stripped;
|
|
24362
24377
|
}
|
|
24363
24378
|
};
|
|
@@ -24983,12 +24998,12 @@ var DUPLICATE_NOTE = "An earlier delivery of this same call had already gone out
|
|
|
24983
24998
|
var DUPLICATE_UNKNOWN_ID_NOTE = `${DUPLICATE_NOTE} Its id is not known yet; \`telegram_chat_read\` shows it once the service receives it.`;
|
|
24984
24999
|
|
|
24985
25000
|
// src/core/message/uncertain.ts
|
|
24986
|
-
function sentLike(paths, chat,
|
|
25001
|
+
function sentLike(paths, chat, text2, startedAt) {
|
|
24987
25002
|
const rows = readMirror(
|
|
24988
25003
|
paths,
|
|
24989
25004
|
(mirror) => mirror.prepare(
|
|
24990
25005
|
"SELECT id, ts FROM messages WHERE chat = ? AND from_me = 1 AND body = ? AND ts >= ? ORDER BY ts DESC, id DESC LIMIT ?"
|
|
24991
|
-
).all(chat,
|
|
25006
|
+
).all(chat, text2, startedAt - SENT_LOOKBACK_MS, MAX_SENT_LIKE)
|
|
24992
25007
|
);
|
|
24993
25008
|
return rows.map(({ id, ts }) => ({ id, time: formatLocalTime(ts) }));
|
|
24994
25009
|
}
|
|
@@ -25008,8 +25023,8 @@ function withFound(error62, find, describe3) {
|
|
|
25008
25023
|
details: { ...error62.details, sent_like_this: found }
|
|
25009
25024
|
});
|
|
25010
25025
|
}
|
|
25011
|
-
function withSentLike(error62, paths, chat,
|
|
25012
|
-
return withFound(error62, () => sentLike(paths, chat,
|
|
25026
|
+
function withSentLike(error62, paths, chat, text2, startedAt) {
|
|
25027
|
+
return withFound(error62, () => sentLike(paths, chat, text2, startedAt), sentence);
|
|
25013
25028
|
}
|
|
25014
25029
|
|
|
25015
25030
|
// src/core/file/send/uncertain.ts
|
|
@@ -25146,17 +25161,17 @@ var MAX_HEADLINE_VALUES = 8;
|
|
|
25146
25161
|
var MAX_HEADLINE_VALUE_LENGTH = 80;
|
|
25147
25162
|
var MAX_PINS = 16;
|
|
25148
25163
|
var HEADLINE_PLACEHOLDER = /\{([A-Za-z_][A-Za-z0-9_]*)\}/;
|
|
25149
|
-
function cut2(
|
|
25150
|
-
const points = Array.from(
|
|
25151
|
-
return points.length > limit ? `${points.slice(0, limit - 1).join("")}\u2026` :
|
|
25164
|
+
function cut2(text2, limit) {
|
|
25165
|
+
const points = Array.from(text2);
|
|
25166
|
+
return points.length > limit ? `${points.slice(0, limit - 1).join("")}\u2026` : text2;
|
|
25152
25167
|
}
|
|
25153
|
-
function omittedBy(
|
|
25154
|
-
const length = Array.from(
|
|
25168
|
+
function omittedBy(text2, limit) {
|
|
25169
|
+
const length = Array.from(text2).length;
|
|
25155
25170
|
return length > limit ? length - (limit - 1) : 0;
|
|
25156
25171
|
}
|
|
25157
|
-
function templatePlaceholders(
|
|
25172
|
+
function templatePlaceholders(text2) {
|
|
25158
25173
|
const names = /* @__PURE__ */ new Set();
|
|
25159
|
-
const parts =
|
|
25174
|
+
const parts = text2.split(HEADLINE_PLACEHOLDER);
|
|
25160
25175
|
for (const [index, part] of parts.entries()) {
|
|
25161
25176
|
if (index % 2 === 1) names.add(part);
|
|
25162
25177
|
else if (/[{}]/.test(part)) return void 0;
|
|
@@ -25174,10 +25189,10 @@ function valueEntries(values) {
|
|
|
25174
25189
|
const entries = Object.entries(values);
|
|
25175
25190
|
return entries.length > MAX_HEADLINE_VALUES ? void 0 : entries;
|
|
25176
25191
|
}
|
|
25177
|
-
function isTemplate(
|
|
25178
|
-
if (
|
|
25192
|
+
function isTemplate(text2, limit, entries) {
|
|
25193
|
+
if (text2.trim() === "" || Array.from(text2).length > limit) return false;
|
|
25179
25194
|
const given = new Set(entries.map(([name]) => name));
|
|
25180
|
-
const placeholders2 = templatePlaceholders(
|
|
25195
|
+
const placeholders2 = templatePlaceholders(text2);
|
|
25181
25196
|
return placeholders2 !== void 0 && [...placeholders2].every((name) => given.has(name));
|
|
25182
25197
|
}
|
|
25183
25198
|
function isTemplateValue(value) {
|
|
@@ -25193,15 +25208,15 @@ function isFact(fact) {
|
|
|
25193
25208
|
}
|
|
25194
25209
|
function cutValue(value) {
|
|
25195
25210
|
if (typeof value === "string") return cut2(value, MAX_VALUE_LENGTH);
|
|
25196
|
-
const { text, values } = value;
|
|
25197
|
-
if (values === void 0) return { text };
|
|
25211
|
+
const { text: text2, values } = value;
|
|
25212
|
+
if (values === void 0) return { text: text2 };
|
|
25198
25213
|
const cutValues = Object.entries(values).map(
|
|
25199
25214
|
([name, entry2]) => [name, typeof entry2 === "string" ? cut2(entry2, MAX_VALUE_LENGTH) : entry2]
|
|
25200
25215
|
);
|
|
25201
|
-
return { text, values: Object.fromEntries(cutValues) };
|
|
25216
|
+
return { text: text2, values: Object.fromEntries(cutValues) };
|
|
25202
25217
|
}
|
|
25203
|
-
function isText2(
|
|
25204
|
-
return isRecord2(
|
|
25218
|
+
function isText2(text2) {
|
|
25219
|
+
return isRecord2(text2) && typeof text2.label === "string" && text2.label.trim() !== "" && typeof text2.body === "string";
|
|
25205
25220
|
}
|
|
25206
25221
|
function pinsOf(pins) {
|
|
25207
25222
|
if (pins === void 0) return {};
|
|
@@ -25215,32 +25230,32 @@ function pinsOf(pins) {
|
|
|
25215
25230
|
}
|
|
25216
25231
|
function copyValue(value) {
|
|
25217
25232
|
if (typeof value === "string") return value;
|
|
25218
|
-
const { text, values } = value;
|
|
25219
|
-
return values === void 0 ? { text } : { text, values: { ...values } };
|
|
25233
|
+
const { text: text2, values } = value;
|
|
25234
|
+
return values === void 0 ? { text: text2 } : { text: text2, values: { ...values } };
|
|
25220
25235
|
}
|
|
25221
25236
|
function headlineOf(headline) {
|
|
25222
25237
|
if (!isRecord2(headline) || typeof headline.text !== "string") return void 0;
|
|
25223
|
-
const { text, values } = headline;
|
|
25238
|
+
const { text: text2, values } = headline;
|
|
25224
25239
|
const entries = valueEntries(values);
|
|
25225
|
-
if (entries === void 0 || !isTemplate(
|
|
25240
|
+
if (entries === void 0 || !isTemplate(text2, MAX_HEADLINE_LENGTH, entries)) return void 0;
|
|
25226
25241
|
if (!entries.every((entry2) => typeof entry2[1] === "string")) return void 0;
|
|
25227
|
-
return values === void 0 ? { text } : { text, values: Object.fromEntries(entries) };
|
|
25242
|
+
return values === void 0 ? { text: text2 } : { text: text2, values: Object.fromEntries(entries) };
|
|
25228
25243
|
}
|
|
25229
|
-
function cutHeadline({ text, values }) {
|
|
25230
|
-
if (values === void 0) return { text };
|
|
25244
|
+
function cutHeadline({ text: text2, values }) {
|
|
25245
|
+
if (values === void 0) return { text: text2 };
|
|
25231
25246
|
const cutValues = Object.entries(values).map(
|
|
25232
25247
|
([name, value]) => [name, cut2(value, MAX_HEADLINE_VALUE_LENGTH)]
|
|
25233
25248
|
);
|
|
25234
|
-
return { text, values: Object.fromEntries(cutValues) };
|
|
25249
|
+
return { text: text2, values: Object.fromEntries(cutValues) };
|
|
25235
25250
|
}
|
|
25236
|
-
function cutDescription({ headline, facts, text, pins }) {
|
|
25251
|
+
function cutDescription({ headline, facts, text: text2, pins }) {
|
|
25237
25252
|
return {
|
|
25238
25253
|
...headline && { headline: cutHeadline(headline) },
|
|
25239
25254
|
facts: facts.slice(0, MAX_FACTS).map(({ label, value }) => ({
|
|
25240
25255
|
label: cut2(label, MAX_LABEL_LENGTH),
|
|
25241
25256
|
value: cutValue(value)
|
|
25242
25257
|
})),
|
|
25243
|
-
...
|
|
25258
|
+
...text2 && { text: { label: cut2(text2.label, MAX_TEXT_LABEL_LENGTH), body: cut2(text2.body, MAX_TEXT_LENGTH) } },
|
|
25244
25259
|
...pins && { pins }
|
|
25245
25260
|
};
|
|
25246
25261
|
}
|
|
@@ -25264,9 +25279,9 @@ async function wholeCallDescription(spec, args, ctx) {
|
|
|
25264
25279
|
if (kept === void 0) return void 0;
|
|
25265
25280
|
const facts = entries.map(({ label, value }) => ({ label, value: copyValue(value) }));
|
|
25266
25281
|
const headline = answer.headline === void 0 ? void 0 : headlineOf(answer.headline);
|
|
25267
|
-
const
|
|
25268
|
-
if (headline === void 0 && facts.length === 0 &&
|
|
25269
|
-
return { ...headline && { headline }, facts, ...
|
|
25282
|
+
const text2 = answer.text === void 0 || answer.text.body === "" ? void 0 : { label: answer.text.label, body: answer.text.body };
|
|
25283
|
+
if (headline === void 0 && facts.length === 0 && text2 === void 0) return void 0;
|
|
25284
|
+
return { ...headline && { headline }, facts, ...text2 && { text: text2 }, ...kept };
|
|
25270
25285
|
}
|
|
25271
25286
|
|
|
25272
25287
|
// src/core/message/action-describe.ts
|
|
@@ -25579,10 +25594,10 @@ var telegramMessageDelete = defineTool({
|
|
|
25579
25594
|
});
|
|
25580
25595
|
|
|
25581
25596
|
// src/core/message/edit-prepare.ts
|
|
25582
|
-
function prepareEdit(mirror, chatId, id,
|
|
25597
|
+
function prepareEdit(mirror, chatId, id, text2) {
|
|
25583
25598
|
const { chat, message } = findOwnMessage(mirror, chatId, id, "edit");
|
|
25584
25599
|
if (!message) throw deletedMessage();
|
|
25585
|
-
checkEditable({ ...message, captioned: message.media !== null && takesCaption(message.media.type) },
|
|
25600
|
+
checkEditable({ ...message, captioned: message.media !== null && takesCaption(message.media.type) }, text2);
|
|
25586
25601
|
return { chat, message };
|
|
25587
25602
|
}
|
|
25588
25603
|
|
|
@@ -25605,22 +25620,22 @@ var telegramMessageEdit = defineTool({
|
|
|
25605
25620
|
input: editInput,
|
|
25606
25621
|
output: editOutput,
|
|
25607
25622
|
async describe(args, ctx) {
|
|
25608
|
-
const
|
|
25623
|
+
const text2 = checkedText(args.text);
|
|
25609
25624
|
const chat = requireChatId(args.chat, MESSAGE_EDIT_TOOL_ID);
|
|
25610
25625
|
const paths = await pickPaths(ctx, args.account);
|
|
25611
|
-
const target = readMirror(paths, (mirror) => prepareEdit(mirror, chat, args.id,
|
|
25626
|
+
const target = readMirror(paths, (mirror) => prepareEdit(mirror, chat, args.id, text2));
|
|
25612
25627
|
return {
|
|
25613
25628
|
...describeAction(EDIT_HEADLINES, target.chat, args.id, target.message),
|
|
25614
|
-
text: { label: "New text", body:
|
|
25629
|
+
text: { label: "New text", body: text2 }
|
|
25615
25630
|
};
|
|
25616
25631
|
},
|
|
25617
25632
|
targets: (args, ctx) => actionTargets(MESSAGE_EDIT_TOOL_ID, args, ctx),
|
|
25618
25633
|
async execute(args, ctx) {
|
|
25619
25634
|
const chat = requireChatId(args.chat, MESSAGE_EDIT_TOOL_ID);
|
|
25620
|
-
const
|
|
25635
|
+
const text2 = checkedText(args.text);
|
|
25621
25636
|
const paths = await pickPaths(ctx, args.account);
|
|
25622
|
-
readMirror(paths, (mirror) => prepareEdit(mirror, chat, args.id,
|
|
25623
|
-
const params = { chat, id: args.id, text };
|
|
25637
|
+
readMirror(paths, (mirror) => prepareEdit(mirror, chat, args.id, text2));
|
|
25638
|
+
const params = { chat, id: args.id, text: text2 };
|
|
25624
25639
|
const edited = await callService(paths.socket, SERVICE_REQUESTS.edit, params, {
|
|
25625
25640
|
effect: "write",
|
|
25626
25641
|
signal: ctx.signal,
|
|
@@ -25816,7 +25831,7 @@ var telegramMessageSend = defineTool({
|
|
|
25816
25831
|
input: input5,
|
|
25817
25832
|
output: output5,
|
|
25818
25833
|
async describe(args, ctx) {
|
|
25819
|
-
const
|
|
25834
|
+
const text2 = checkedText(args.text);
|
|
25820
25835
|
const chat = requireChatId(args.chat, MESSAGE_SEND_TOOL_ID);
|
|
25821
25836
|
const paths = await pickPaths(ctx, args.account);
|
|
25822
25837
|
const { row, title } = readMirror(paths, (mirror) => {
|
|
@@ -25828,17 +25843,17 @@ var telegramMessageSend = defineTool({
|
|
|
25828
25843
|
headline: { text: "About to send a message to {chat}", values: { chat: row.name } }
|
|
25829
25844
|
},
|
|
25830
25845
|
facts: [chatFact(row.kind), ...topicFacts(args.topic, title), ...replyFacts(args.reply_to)],
|
|
25831
|
-
text: { label: "Message text", body:
|
|
25846
|
+
text: { label: "Message text", body: text2 }
|
|
25832
25847
|
};
|
|
25833
25848
|
},
|
|
25834
25849
|
targets: (args, ctx) => chatTargets(MESSAGE_SEND_TOOL_ID, args, ctx),
|
|
25835
25850
|
async execute(args, ctx) {
|
|
25836
25851
|
const chat = requireChatId(args.chat, MESSAGE_SEND_TOOL_ID);
|
|
25837
|
-
const
|
|
25852
|
+
const text2 = checkedText(args.text);
|
|
25838
25853
|
const paths = await pickPaths(ctx, args.account);
|
|
25839
25854
|
const params = {
|
|
25840
25855
|
chat,
|
|
25841
|
-
text,
|
|
25856
|
+
text: text2,
|
|
25842
25857
|
...args.topic !== void 0 && { topic: args.topic },
|
|
25843
25858
|
...args.reply_to !== void 0 && { reply_to: args.reply_to }
|
|
25844
25859
|
};
|
|
@@ -25851,7 +25866,7 @@ var telegramMessageSend = defineTool({
|
|
|
25851
25866
|
});
|
|
25852
25867
|
return sendResult(chat, sent);
|
|
25853
25868
|
} catch (error62) {
|
|
25854
|
-
throw isToolError(error62) && error62.code === "uncertain" ? withSentLike(error62, paths, chat,
|
|
25869
|
+
throw isToolError(error62) && error62.code === "uncertain" ? withSentLike(error62, paths, chat, text2, startedAt) : error62;
|
|
25855
25870
|
}
|
|
25856
25871
|
}
|
|
25857
25872
|
});
|
|
@@ -26257,9 +26272,9 @@ function mark(character) {
|
|
|
26257
26272
|
const hex3 = character.codePointAt(0).toString(16).toUpperCase();
|
|
26258
26273
|
return `<U+${hex3.padStart(MARK_DIGITS, "0")}>`;
|
|
26259
26274
|
}
|
|
26260
|
-
function visible(
|
|
26261
|
-
if (options.keepNewlines) return
|
|
26262
|
-
return
|
|
26275
|
+
function visible(text2, options = {}) {
|
|
26276
|
+
if (options.keepNewlines) return text2.replace(/\r\n/g, "\n").replace(HIDDEN_EXCEPT_NEWLINE, mark);
|
|
26277
|
+
return text2.replace(HIDDEN_ALL, mark);
|
|
26263
26278
|
}
|
|
26264
26279
|
|
|
26265
26280
|
// src/entry/words.ts
|
|
@@ -26305,12 +26320,12 @@ var omittedOf = (count) => count > 0 ? { omitted: count } : {};
|
|
|
26305
26320
|
function quoted(value) {
|
|
26306
26321
|
return `"${visible(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
26307
26322
|
}
|
|
26308
|
-
function filled(
|
|
26309
|
-
return
|
|
26323
|
+
function filled(text2, literal2, slot) {
|
|
26324
|
+
return text2.split(HEADLINE_PLACEHOLDER).map((part, index) => index % 2 === 0 ? literal2(part) : slot(part)).join("");
|
|
26310
26325
|
}
|
|
26311
|
-
function renderedHeadline({ text, values = {} }) {
|
|
26326
|
+
function renderedHeadline({ text: text2, values = {} }) {
|
|
26312
26327
|
return filled(
|
|
26313
|
-
|
|
26328
|
+
text2,
|
|
26314
26329
|
(part) => visible(part),
|
|
26315
26330
|
(name) => quoted(values[name] ?? "")
|
|
26316
26331
|
);
|
|
@@ -26324,7 +26339,7 @@ function renderedValue(value, t) {
|
|
|
26324
26339
|
return { value: visible(cut2(whole, MAX_VALUE_LENGTH)), ...omittedOf(omittedBy(whole, MAX_VALUE_LENGTH)) };
|
|
26325
26340
|
}
|
|
26326
26341
|
function shownDescription(description, t) {
|
|
26327
|
-
const { headline, facts, text } = cutDescription(description);
|
|
26342
|
+
const { headline, facts, text: text2 } = cutDescription(description);
|
|
26328
26343
|
const wholeBody = description.text?.body ?? "";
|
|
26329
26344
|
const dropped = description.facts.length - facts.length;
|
|
26330
26345
|
return {
|
|
@@ -26334,9 +26349,9 @@ function shownDescription(description, t) {
|
|
|
26334
26349
|
...renderedValue(description.facts[index].value, t)
|
|
26335
26350
|
})),
|
|
26336
26351
|
...dropped > 0 && { dropped },
|
|
26337
|
-
...
|
|
26352
|
+
...text2 && {
|
|
26338
26353
|
text: {
|
|
26339
|
-
label: visible(t.word(
|
|
26354
|
+
label: visible(t.word(text2.label, MAX_TEXT_LABEL_LENGTH)),
|
|
26340
26355
|
body: visible(cut2(wholeBody, MAX_TEXT_LENGTH), { keepNewlines: true }),
|
|
26341
26356
|
...omittedOf(omittedBy(wholeBody, MAX_TEXT_LENGTH))
|
|
26342
26357
|
}
|
|
@@ -26350,9 +26365,9 @@ async function timedCallDescription(spec, args, ctx, timeoutMs = DESCRIBE_TIMEOU
|
|
|
26350
26365
|
let timer;
|
|
26351
26366
|
let onAbort;
|
|
26352
26367
|
try {
|
|
26353
|
-
const timedOut = new Promise((
|
|
26368
|
+
const timedOut = new Promise((resolve6) => {
|
|
26354
26369
|
timer = setTimeout(() => {
|
|
26355
|
-
|
|
26370
|
+
resolve6(void 0);
|
|
26356
26371
|
controller.abort();
|
|
26357
26372
|
}, timeoutMs);
|
|
26358
26373
|
});
|
|
@@ -26428,76 +26443,70 @@ ${JSON.stringify(error62.details)}` : ""}`;
|
|
|
26428
26443
|
var PROJECT_PROFILE = {
|
|
26429
26444
|
name: PROJECT.name,
|
|
26430
26445
|
envPrefix: PROJECT.envPrefix,
|
|
26431
|
-
toolsets: { names: PROJECT.toolsets, defaults: PROJECT.defaultToolsets }
|
|
26446
|
+
toolsets: { names: PROJECT.toolsets, defaults: PROJECT.defaultToolsets },
|
|
26447
|
+
options: PROJECT.options
|
|
26432
26448
|
};
|
|
26433
26449
|
|
|
26434
|
-
// src/entry/
|
|
26435
|
-
import {
|
|
26450
|
+
// src/entry/settings.ts
|
|
26451
|
+
import { homedir as homedir3 } from "node:os";
|
|
26452
|
+
import { isAbsolute as isAbsolute6, join as join10, resolve as resolvePath, sep as sep4 } from "node:path";
|
|
26436
26453
|
|
|
26437
26454
|
// src/entry/directory.ts
|
|
26438
26455
|
import { homedir as homedir2 } from "node:os";
|
|
26439
|
-
import { isAbsolute as isAbsolute5,
|
|
26456
|
+
import { isAbsolute as isAbsolute5, resolve as resolve4 } from "node:path";
|
|
26457
|
+
var DOWNLOADS_DIR = "Downloads";
|
|
26458
|
+
var DEFAULT_DOWNLOAD_MAX_MB = 100;
|
|
26440
26459
|
function homeDir(env) {
|
|
26441
26460
|
const envHome = env.HOME;
|
|
26442
26461
|
if (envHome && isAbsolute5(envHome)) return envHome;
|
|
26443
26462
|
return homedir2();
|
|
26444
26463
|
}
|
|
26445
|
-
function
|
|
26446
|
-
const
|
|
26447
|
-
|
|
26448
|
-
if (!text || !isAbsolute5(expanded)) {
|
|
26449
|
-
throw new ToolError("invalid_argument", `${given.source} must be an absolute path.`);
|
|
26450
|
-
}
|
|
26451
|
-
return resolve4(expanded);
|
|
26452
|
-
}
|
|
26453
|
-
|
|
26454
|
-
// src/entry/download-dir.ts
|
|
26455
|
-
var DOWNLOADS_DIR = "Downloads";
|
|
26456
|
-
function resolveDownloadDir(given, env, profile) {
|
|
26457
|
-
const home = homeDir(env);
|
|
26458
|
-
return given !== void 0 ? resolveGivenDirectory(given, home) : resolve5(home, DOWNLOADS_DIR, profile.name);
|
|
26464
|
+
function defaultStateDir(name, env, home) {
|
|
26465
|
+
const xdg = env.XDG_STATE_HOME;
|
|
26466
|
+
return xdg && isAbsolute5(xdg) ? resolve4(xdg, name) : resolve4(home, ".local", "state", name);
|
|
26459
26467
|
}
|
|
26460
|
-
|
|
26461
|
-
|
|
26462
|
-
function resolveSendDirs(given, env) {
|
|
26463
|
-
const home = homeDir(env);
|
|
26464
|
-
return given.map((directory) => resolveGivenDirectory(directory, home));
|
|
26468
|
+
function text(value) {
|
|
26469
|
+
return typeof value === "string" ? value : void 0;
|
|
26465
26470
|
}
|
|
26466
|
-
|
|
26467
|
-
// src/entry/state-dir.ts
|
|
26468
|
-
import { isAbsolute as isAbsolute6, resolve as resolve6 } from "node:path";
|
|
26469
|
-
function resolveStateDir(given, env, profile) {
|
|
26471
|
+
function resolveDirectorySettings(options, env, profile) {
|
|
26470
26472
|
const home = homeDir(env);
|
|
26471
|
-
|
|
26472
|
-
const
|
|
26473
|
-
|
|
26474
|
-
|
|
26475
|
-
|
|
26476
|
-
|
|
26473
|
+
const maxMb = options.download_max_mb;
|
|
26474
|
+
const sendDirs = options.send_dirs;
|
|
26475
|
+
return {
|
|
26476
|
+
state_dir: text(options.state_dir) ?? defaultStateDir(profile.name, env, home),
|
|
26477
|
+
download_dir: text(options.download_dir) ?? resolve4(home, DOWNLOADS_DIR, profile.name),
|
|
26478
|
+
download_max_mb: typeof maxMb === "number" ? maxMb : DEFAULT_DOWNLOAD_MAX_MB,
|
|
26479
|
+
send_dirs: Array.isArray(sendDirs) ? [...sendDirs] : []
|
|
26480
|
+
};
|
|
26477
26481
|
}
|
|
26478
26482
|
|
|
26479
26483
|
// src/entry/settings.ts
|
|
26480
26484
|
var ALL_TOOLSETS = "all";
|
|
26481
26485
|
var TRUE_VALUES = ["1", "true"];
|
|
26482
26486
|
var FALSE_VALUES = ["0", "false"];
|
|
26483
|
-
var DEFAULT_DOWNLOAD_MAX_MB = 100;
|
|
26484
|
-
var MAX_DOWNLOAD_MB = 2e3;
|
|
26485
26487
|
var OPTIONS = {
|
|
26486
26488
|
toolsets: { flag: "--toolsets", envSuffix: "TOOLSETS" },
|
|
26487
26489
|
read_only: { flag: "--read-only", envSuffix: "READ_ONLY", boolean: true },
|
|
26488
26490
|
tools: { flag: "--tools", envSuffix: "TOOLS" },
|
|
26489
26491
|
exclude_tools: { flag: "--exclude-tools", envSuffix: "EXCLUDE_TOOLS" },
|
|
26490
|
-
confirm: { flag: "--confirm", envSuffix: "CONFIRM" }
|
|
26491
|
-
state_dir: { flag: "--state-dir", envSuffix: "STATE_DIR" },
|
|
26492
|
-
download_dir: { flag: "--download-dir", envSuffix: "DOWNLOAD_DIR" },
|
|
26493
|
-
download_max_mb: { flag: "--download-max-mb", envSuffix: "DOWNLOAD_MAX_MB" },
|
|
26494
|
-
send_dirs: { flag: "--send-dirs", envSuffix: "SEND_DIRS" },
|
|
26495
|
-
keep_disappearing: { flag: "--keep-disappearing", envSuffix: "KEEP_DISAPPEARING", boolean: true },
|
|
26496
|
-
channels: { flag: "--channels", envSuffix: "CHANNELS", boolean: true }
|
|
26492
|
+
confirm: { flag: "--confirm", envSuffix: "CONFIRM" }
|
|
26497
26493
|
};
|
|
26498
|
-
|
|
26494
|
+
function profileOptions(profile) {
|
|
26495
|
+
return profile.options ?? {};
|
|
26496
|
+
}
|
|
26497
|
+
function settingOptions(profile) {
|
|
26498
|
+
const toolOptions = Object.entries(profileOptions(profile)).map(([name, spec]) => [
|
|
26499
|
+
name,
|
|
26500
|
+
{
|
|
26501
|
+
flag: `--${name.replace(/_/g, "-")}`,
|
|
26502
|
+
envSuffix: name.toUpperCase(),
|
|
26503
|
+
...optionType(spec) === "boolean" && { boolean: true }
|
|
26504
|
+
}
|
|
26505
|
+
]);
|
|
26506
|
+
return { ...OPTIONS, ...Object.fromEntries(toolOptions) };
|
|
26507
|
+
}
|
|
26499
26508
|
function envName(name, profile) {
|
|
26500
|
-
return `${profile.envPrefix}_${
|
|
26509
|
+
return `${profile.envPrefix}_${settingOptions(profile)[name].envSuffix}`;
|
|
26501
26510
|
}
|
|
26502
26511
|
function splitList(value) {
|
|
26503
26512
|
return value.split(",").map((item) => item.trim()).filter((item) => item !== "");
|
|
@@ -26512,43 +26521,87 @@ function checkToolsets(names, source, toolsets) {
|
|
|
26512
26521
|
return names.length ? names : void 0;
|
|
26513
26522
|
}
|
|
26514
26523
|
function parseBoolean(value, source) {
|
|
26515
|
-
const
|
|
26516
|
-
if (TRUE_VALUES.includes(
|
|
26517
|
-
if (FALSE_VALUES.includes(
|
|
26524
|
+
const text2 = value.trim().toLowerCase();
|
|
26525
|
+
if (TRUE_VALUES.includes(text2)) return true;
|
|
26526
|
+
if (FALSE_VALUES.includes(text2)) return false;
|
|
26518
26527
|
throw new ToolError(
|
|
26519
26528
|
"invalid_argument",
|
|
26520
26529
|
`Unknown value "${value}" in ${source}; use one of ${[...TRUE_VALUES, ...FALSE_VALUES].join(", ")}.`
|
|
26521
26530
|
);
|
|
26522
26531
|
}
|
|
26523
|
-
function
|
|
26524
|
-
|
|
26525
|
-
|
|
26526
|
-
|
|
26527
|
-
|
|
26528
|
-
throw new ToolError("invalid_argument", `${source} must be an integer from 1 to ${MAX_DOWNLOAD_MB}.`);
|
|
26532
|
+
function parseNumber2(value, source) {
|
|
26533
|
+
const trimmed = value.trim();
|
|
26534
|
+
const parsed = trimmed === "" ? Number.NaN : Number(trimmed);
|
|
26535
|
+
if (!Number.isFinite(parsed)) {
|
|
26536
|
+
throw new ToolError("invalid_argument", `Unknown number "${value}" in ${source}; use a finite number.`);
|
|
26529
26537
|
}
|
|
26530
|
-
return
|
|
26538
|
+
return parsed;
|
|
26539
|
+
}
|
|
26540
|
+
function absolutePath(text2, source, env) {
|
|
26541
|
+
const home = env.HOME !== void 0 && isAbsolute6(env.HOME) ? env.HOME : homedir3();
|
|
26542
|
+
const expanded = text2 === "~" || text2.startsWith("~/") || text2.startsWith(`~${sep4}`) ? join10(home, text2.slice(1)) : text2;
|
|
26543
|
+
if (!isAbsolute6(expanded)) throw new ToolError("invalid_argument", `${source} must be an absolute path.`);
|
|
26544
|
+
return resolvePath(expanded);
|
|
26531
26545
|
}
|
|
26532
|
-
function
|
|
26533
|
-
|
|
26534
|
-
return downloadMaxMb(/^\d+$/.test(trimmed) ? Number(trimmed) : Number.NaN, source);
|
|
26546
|
+
function absolutePaths(items, source, env) {
|
|
26547
|
+
return items.length > 0 ? items.map((item) => absolutePath(item, source, env)) : void 0;
|
|
26535
26548
|
}
|
|
26536
26549
|
function envText(name, env, profile) {
|
|
26537
26550
|
const variable = envName(name, profile);
|
|
26538
|
-
const
|
|
26539
|
-
return
|
|
26540
|
-
}
|
|
26541
|
-
|
|
26542
|
-
"
|
|
26543
|
-
|
|
26544
|
-
|
|
26545
|
-
"
|
|
26546
|
-
|
|
26547
|
-
|
|
26548
|
-
"
|
|
26549
|
-
"
|
|
26550
|
-
|
|
26551
|
-
|
|
26551
|
+
const text2 = env[variable];
|
|
26552
|
+
return text2 === void 0 || text2.trim() === "" ? void 0 : { text: text2, source: variable };
|
|
26553
|
+
}
|
|
26554
|
+
function optionType(spec) {
|
|
26555
|
+
return typeof spec === "string" ? spec : spec.type;
|
|
26556
|
+
}
|
|
26557
|
+
function itemCount(count) {
|
|
26558
|
+
return count === 1 ? "1 item" : `${count} items`;
|
|
26559
|
+
}
|
|
26560
|
+
function numberBoundsError({ integer: integer2, min, max }, source) {
|
|
26561
|
+
const range = min !== void 0 && max !== void 0 ? ` from ${min} to ${max}` : min !== void 0 ? ` of at least ${min}` : max !== void 0 ? ` of at most ${max}` : "";
|
|
26562
|
+
return new ToolError("invalid_argument", `${source} must be ${integer2 ? "a whole number" : "a number"}${range}.`);
|
|
26563
|
+
}
|
|
26564
|
+
function countBoundsError({ min, max }, source) {
|
|
26565
|
+
const range = min !== void 0 && max !== void 0 ? `from ${min} to ${max} items` : min !== void 0 ? `at least ${itemCount(min)}` : `at most ${itemCount(max)}`;
|
|
26566
|
+
return new ToolError("invalid_argument", `${source} must list ${range}.`);
|
|
26567
|
+
}
|
|
26568
|
+
function withinBounds(spec, value, source) {
|
|
26569
|
+
if (value === void 0 || typeof spec === "string") return value;
|
|
26570
|
+
const bounds = spec;
|
|
26571
|
+
const { integer: integer2, min, max } = bounds;
|
|
26572
|
+
if (typeof value === "number") {
|
|
26573
|
+
if (integer2 && !Number.isInteger(value) || min !== void 0 && value < min || max !== void 0 && value > max) {
|
|
26574
|
+
throw numberBoundsError(bounds, source);
|
|
26575
|
+
}
|
|
26576
|
+
} else if (typeof value === "object" && (min !== void 0 && value.length < min || max !== void 0 && value.length > max)) {
|
|
26577
|
+
throw countBoundsError(bounds, source);
|
|
26578
|
+
}
|
|
26579
|
+
return value;
|
|
26580
|
+
}
|
|
26581
|
+
function parseOptionText(spec, given, env) {
|
|
26582
|
+
return withinBounds(spec, parseTypedText(optionType(spec), given, env), given.source);
|
|
26583
|
+
}
|
|
26584
|
+
function parseTypedText(kind, given, env) {
|
|
26585
|
+
switch (kind) {
|
|
26586
|
+
case "text":
|
|
26587
|
+
return nonBlank(given.text);
|
|
26588
|
+
case "boolean":
|
|
26589
|
+
return parseBoolean(given.text, given.source);
|
|
26590
|
+
case "number":
|
|
26591
|
+
return parseNumber2(given.text, given.source);
|
|
26592
|
+
case "list": {
|
|
26593
|
+
const items = splitList(given.text);
|
|
26594
|
+
return items.length > 0 ? items : void 0;
|
|
26595
|
+
}
|
|
26596
|
+
case "path": {
|
|
26597
|
+
const text2 = nonBlank(given.text);
|
|
26598
|
+
return text2 === void 0 ? void 0 : absolutePath(text2, given.source, env);
|
|
26599
|
+
}
|
|
26600
|
+
case "paths":
|
|
26601
|
+
return absolutePaths(splitList(given.text), given.source, env);
|
|
26602
|
+
}
|
|
26603
|
+
}
|
|
26604
|
+
var TOOL_OPTION_NAMES = ["toolsets", "read_only", "tools", "exclude_tools"];
|
|
26552
26605
|
function stringList(value) {
|
|
26553
26606
|
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
|
|
26554
26607
|
}
|
|
@@ -26556,15 +26609,6 @@ var optionSource = (name) => `Option "${name}"`;
|
|
|
26556
26609
|
function optionError(name, expected) {
|
|
26557
26610
|
return new ToolError("invalid_argument", `${optionSource(name)} must be ${expected}.`);
|
|
26558
26611
|
}
|
|
26559
|
-
function directoryOption(name, value) {
|
|
26560
|
-
if (typeof value !== "string") throw optionError(name, "an absolute path");
|
|
26561
|
-
return value;
|
|
26562
|
-
}
|
|
26563
|
-
function sendDirsOption(value) {
|
|
26564
|
-
const list2 = stringList(value);
|
|
26565
|
-
if (!list2) throw optionError("send_dirs", "a list of absolute paths");
|
|
26566
|
-
return list2.map((text) => ({ text, source: optionSource("send_dirs") }));
|
|
26567
|
-
}
|
|
26568
26612
|
function toolsetsOption(value, toolsets) {
|
|
26569
26613
|
if (value === ALL_TOOLSETS) return ALL_TOOLSETS;
|
|
26570
26614
|
const names = stringList(value);
|
|
@@ -26585,12 +26629,14 @@ function listOption(name) {
|
|
|
26585
26629
|
};
|
|
26586
26630
|
}
|
|
26587
26631
|
var LANGUAGE_OPTION = "language";
|
|
26588
|
-
|
|
26632
|
+
function pluginOptionNames(profile) {
|
|
26633
|
+
return [...TOOL_OPTION_NAMES, LANGUAGE_OPTION, ...Object.keys(profileOptions(profile))];
|
|
26634
|
+
}
|
|
26589
26635
|
function languageVariable(profile = PROJECT_PROFILE) {
|
|
26590
26636
|
return `${profile.envPrefix}_LANGUAGE`;
|
|
26591
26637
|
}
|
|
26592
|
-
function nonBlank(
|
|
26593
|
-
const trimmed =
|
|
26638
|
+
function nonBlank(text2) {
|
|
26639
|
+
const trimmed = text2?.trim();
|
|
26594
26640
|
return trimmed === "" ? void 0 : trimmed;
|
|
26595
26641
|
}
|
|
26596
26642
|
function promptLanguage(flag, env, harness, profile = PROJECT_PROFILE) {
|
|
@@ -26600,42 +26646,80 @@ function languageOption(value) {
|
|
|
26600
26646
|
if (typeof value !== "string") throw optionError(LANGUAGE_OPTION, 'a language tag such as "ja"');
|
|
26601
26647
|
return nonBlank(value);
|
|
26602
26648
|
}
|
|
26649
|
+
function toolOption(name, spec, value, env) {
|
|
26650
|
+
return withinBounds(spec, toolOptionOfType(name, optionType(spec), value, env), `Option "${name}"`);
|
|
26651
|
+
}
|
|
26652
|
+
function toolOptionOfType(name, kind, value, env) {
|
|
26653
|
+
switch (kind) {
|
|
26654
|
+
case "text":
|
|
26655
|
+
if (typeof value !== "string") throw optionError(name, "text");
|
|
26656
|
+
return nonBlank(value);
|
|
26657
|
+
case "boolean":
|
|
26658
|
+
if (typeof value !== "boolean") throw optionError(name, "true or false");
|
|
26659
|
+
return value;
|
|
26660
|
+
case "number":
|
|
26661
|
+
if (typeof value !== "number" || !Number.isFinite(value)) throw optionError(name, "a finite number");
|
|
26662
|
+
return value;
|
|
26663
|
+
case "list": {
|
|
26664
|
+
const list2 = stringList(value);
|
|
26665
|
+
if (!list2) throw optionError(name, "a list of strings");
|
|
26666
|
+
const items = list2.map((item) => item.trim()).filter((item) => item !== "");
|
|
26667
|
+
return items.length > 0 ? items : void 0;
|
|
26668
|
+
}
|
|
26669
|
+
case "path": {
|
|
26670
|
+
if (typeof value !== "string") throw optionError(name, "an absolute path");
|
|
26671
|
+
const text2 = nonBlank(value);
|
|
26672
|
+
return text2 === void 0 ? void 0 : absolutePath(text2, `Option "${name}"`, env);
|
|
26673
|
+
}
|
|
26674
|
+
case "paths": {
|
|
26675
|
+
const list2 = stringList(value);
|
|
26676
|
+
if (!list2) throw optionError(name, "a list of absolute paths");
|
|
26677
|
+
return absolutePaths(
|
|
26678
|
+
list2.flatMap((item) => nonBlank(item) ?? []),
|
|
26679
|
+
`Option "${name}"`,
|
|
26680
|
+
env
|
|
26681
|
+
);
|
|
26682
|
+
}
|
|
26683
|
+
}
|
|
26684
|
+
}
|
|
26603
26685
|
function settingsFromOptions(options, env, profile = PROJECT_PROFILE) {
|
|
26604
26686
|
const given = options ?? {};
|
|
26605
|
-
const
|
|
26687
|
+
const names = pluginOptionNames(profile);
|
|
26688
|
+
const unknown2 = Object.keys(given).find((name) => !names.includes(name));
|
|
26606
26689
|
if (unknown2 !== void 0) {
|
|
26607
|
-
throw new ToolError(
|
|
26608
|
-
"invalid_argument",
|
|
26609
|
-
`Unknown option "${unknown2}"; use one of ${PLUGIN_OPTION_NAMES.join(", ")}.`
|
|
26610
|
-
);
|
|
26690
|
+
throw new ToolError("invalid_argument", `Unknown option "${unknown2}"; use one of ${names.join(", ")}.`);
|
|
26611
26691
|
}
|
|
26612
|
-
const
|
|
26692
|
+
const resolve6 = (name, fromOption, fromText) => {
|
|
26613
26693
|
if (given[name] !== void 0) return fromOption(given[name]);
|
|
26614
|
-
const
|
|
26615
|
-
return
|
|
26616
|
-
};
|
|
26617
|
-
const
|
|
26694
|
+
const text2 = envText(name, env, profile);
|
|
26695
|
+
return text2 !== void 0 ? fromText(text2) : void 0;
|
|
26696
|
+
};
|
|
26697
|
+
const parsedOptions = {};
|
|
26698
|
+
for (const [name, spec] of Object.entries(profileOptions(profile))) {
|
|
26699
|
+
let parsed;
|
|
26700
|
+
if (given[name] !== void 0) {
|
|
26701
|
+
parsed = toolOption(name, spec, given[name], env);
|
|
26702
|
+
} else {
|
|
26703
|
+
const fromEnv = envText(name, env, profile);
|
|
26704
|
+
if (fromEnv !== void 0) parsed = parseOptionText(spec, fromEnv, env);
|
|
26705
|
+
}
|
|
26706
|
+
if (parsed !== void 0) parsedOptions[name] = parsed;
|
|
26707
|
+
}
|
|
26618
26708
|
const settings = {
|
|
26619
|
-
|
|
26620
|
-
|
|
26621
|
-
download_dir: resolveDownloadDir(directoryText("download_dir"), env, profile),
|
|
26622
|
-
download_max_mb: resolve8("download_max_mb", (value) => downloadMaxMb(value, optionSource("download_max_mb")), downloadMaxMbText) ?? DEFAULT_DOWNLOAD_MAX_MB
|
|
26709
|
+
options: parsedOptions,
|
|
26710
|
+
...resolveDirectorySettings(parsedOptions, env, profile)
|
|
26623
26711
|
};
|
|
26624
|
-
const toolsets =
|
|
26712
|
+
const toolsets = resolve6(
|
|
26625
26713
|
"toolsets",
|
|
26626
26714
|
(value) => toolsetsOption(value, profile.toolsets),
|
|
26627
|
-
({ text, source }) => checkToolsets(splitList(
|
|
26715
|
+
({ text: text2, source }) => checkToolsets(splitList(text2), source, profile.toolsets)
|
|
26628
26716
|
);
|
|
26629
26717
|
if (toolsets !== void 0) settings.toolsets = toolsets;
|
|
26630
|
-
const readOnly =
|
|
26718
|
+
const readOnly = resolve6("read_only", booleanOption("read_only"), ({ text: text2, source }) => parseBoolean(text2, source));
|
|
26631
26719
|
if (readOnly !== void 0) settings.read_only = readOnly;
|
|
26632
|
-
|
|
26633
|
-
const given2 = resolve8(name, booleanOption(name), ({ text, source }) => parseBoolean(text, source));
|
|
26634
|
-
if (given2 !== void 0) settings[name] = given2;
|
|
26635
|
-
}
|
|
26636
|
-
const tools = resolve8("tools", listOption("tools"), ({ text }) => splitList(text));
|
|
26720
|
+
const tools = resolve6("tools", listOption("tools"), ({ text: text2 }) => splitList(text2));
|
|
26637
26721
|
if (tools !== void 0) settings.tools = tools;
|
|
26638
|
-
const excluded =
|
|
26722
|
+
const excluded = resolve6("exclude_tools", listOption("exclude_tools"), ({ text: text2 }) => splitList(text2));
|
|
26639
26723
|
if (excluded !== void 0) settings.exclude_tools = excluded;
|
|
26640
26724
|
const language = given[LANGUAGE_OPTION] !== void 0 ? languageOption(given[LANGUAGE_OPTION]) : promptLanguage(void 0, env, void 0, profile);
|
|
26641
26725
|
if (language !== void 0) settings.language = language;
|
|
@@ -26666,7 +26750,8 @@ function selectedTools(specs, options, deps) {
|
|
|
26666
26750
|
downloadMaxMb: settings.download_max_mb,
|
|
26667
26751
|
sendDirs: settings.send_dirs,
|
|
26668
26752
|
programName: PROJECT.name,
|
|
26669
|
-
translator: promptTranslator(deps.translations ?? {}, settings.language)
|
|
26753
|
+
translator: promptTranslator(deps.translations ?? {}, settings.language),
|
|
26754
|
+
options: settings.options
|
|
26670
26755
|
};
|
|
26671
26756
|
}
|
|
26672
26757
|
async function runTool(spec, args, ctx, pin) {
|
|
@@ -26689,8 +26774,8 @@ function describeArguments(spec) {
|
|
|
26689
26774
|
const { properties = {}, required: required2 = [] } = inputJsonSchema(spec);
|
|
26690
26775
|
const lines = Object.entries(properties).map(([name, property]) => {
|
|
26691
26776
|
const kind = required2.includes(name) ? typeName(property) : `${typeName(property)}, optional`;
|
|
26692
|
-
const
|
|
26693
|
-
return `- ${name} (${kind})${
|
|
26777
|
+
const text2 = property.description?.replace(/\s+/g, " ").trim();
|
|
26778
|
+
return `- ${name} (${kind})${text2 ? `: ${text2}` : ""}`;
|
|
26694
26779
|
});
|
|
26695
26780
|
return lines.length > 0 ? `
|
|
26696
26781
|
|
|
@@ -26734,7 +26819,7 @@ function createV1Server(specs, deps = {}) {
|
|
|
26734
26819
|
|
|
26735
26820
|
// src/opencode/skills.ts
|
|
26736
26821
|
import { readFile, readdir as readdir3 } from "node:fs/promises";
|
|
26737
|
-
import { join as join11, resolve as
|
|
26822
|
+
import { join as join11, resolve as resolve5 } from "node:path";
|
|
26738
26823
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
26739
26824
|
var SKILL_FILE = "SKILL.md";
|
|
26740
26825
|
var FRONTMATTER = /^---[ \t]*\r?\n([\s\S]*?\r?\n)?---[ \t]*(?:\r?\n|$)/;
|
|
@@ -26761,8 +26846,8 @@ function unquote(value) {
|
|
|
26761
26846
|
function scalar(raw) {
|
|
26762
26847
|
if (raw === "" || UNSUPPORTED_VALUE_START.test(raw)) return void 0;
|
|
26763
26848
|
if (raw.startsWith('"') || raw.startsWith("'")) return unquote(raw);
|
|
26764
|
-
const
|
|
26765
|
-
return
|
|
26849
|
+
const text2 = raw.replace(TRAILING_COMMENT, "").trim();
|
|
26850
|
+
return text2 === "" ? void 0 : text2;
|
|
26766
26851
|
}
|
|
26767
26852
|
function readToolset(line, indent) {
|
|
26768
26853
|
if (!line.startsWith(indent)) return void 0;
|
|
@@ -26797,8 +26882,8 @@ function readFrontmatter(block) {
|
|
|
26797
26882
|
}
|
|
26798
26883
|
return found;
|
|
26799
26884
|
}
|
|
26800
|
-
function parseSkill(directory,
|
|
26801
|
-
const match = FRONTMATTER.exec(
|
|
26885
|
+
function parseSkill(directory, text2, path) {
|
|
26886
|
+
const match = FRONTMATTER.exec(text2);
|
|
26802
26887
|
const { name, description, toolset } = match ? readFrontmatter(match[1] ?? "") : {};
|
|
26803
26888
|
const id = name ?? directory;
|
|
26804
26889
|
return {
|
|
@@ -26807,7 +26892,7 @@ function parseSkill(directory, text, path) {
|
|
|
26807
26892
|
name: id,
|
|
26808
26893
|
...description !== void 0 && { description },
|
|
26809
26894
|
path,
|
|
26810
|
-
content: match ?
|
|
26895
|
+
content: match ? text2.slice(match[0].length) : text2
|
|
26811
26896
|
},
|
|
26812
26897
|
...toolset !== void 0 && { toolset }
|
|
26813
26898
|
};
|
|
@@ -26825,7 +26910,7 @@ async function readSkillFile(path) {
|
|
|
26825
26910
|
}
|
|
26826
26911
|
}
|
|
26827
26912
|
async function readSkills(dir) {
|
|
26828
|
-
const root =
|
|
26913
|
+
const root = resolve5(typeof dir === "string" ? dir : fileURLToPath2(dir));
|
|
26829
26914
|
let entries;
|
|
26830
26915
|
try {
|
|
26831
26916
|
entries = (await readdir3(root, { withFileTypes: true })).filter((entry2) => !entry2.isFile()).map((entry2) => entry2.name);
|
|
@@ -26836,9 +26921,9 @@ async function readSkills(dir) {
|
|
|
26836
26921
|
const skills = /* @__PURE__ */ new Map();
|
|
26837
26922
|
for (const directory of entries.sort()) {
|
|
26838
26923
|
const path = join11(root, directory, SKILL_FILE);
|
|
26839
|
-
const
|
|
26840
|
-
if (
|
|
26841
|
-
const found = parseSkill(directory,
|
|
26924
|
+
const text2 = await readSkillFile(path);
|
|
26925
|
+
if (text2 === void 0) continue;
|
|
26926
|
+
const found = parseSkill(directory, text2, path);
|
|
26842
26927
|
if (!skills.has(found.skill.id)) skills.set(found.skill.id, found);
|
|
26843
26928
|
}
|
|
26844
26929
|
return [...skills.values()];
|