@ycodium-ai/plugin-im 0.2.2968 → 0.2.2972

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/dist/index.js CHANGED
@@ -24,9 +24,9 @@ var __commonJS = (cb, mod) => function __require2() {
24
24
  throw mod = 0, e;
25
25
  }
26
26
  };
27
- var __export = (target, all) => {
27
+ var __export = (target2, all) => {
28
28
  for (var name in all)
29
- __defProp(target, name, { get: all[name], enumerable: true });
29
+ __defProp(target2, name, { get: all[name], enumerable: true });
30
30
  };
31
31
  var __copyProps = (to, from, except, desc) => {
32
32
  if (from && typeof from === "object" || typeof from === "function") {
@@ -36,12 +36,12 @@ var __copyProps = (to, from, except, desc) => {
36
36
  }
37
37
  return to;
38
38
  };
39
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
39
+ var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
40
40
  // If the importer is in node compatibility mode or this is not an ESM
41
41
  // file that has been converted to a CommonJS file using a Babel-
42
42
  // compatible transform (i.e. "__esModule" has not been set), then set
43
43
  // "default" to the CommonJS "module.exports" for node compatibility.
44
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
44
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target2, "default", { value: mod, enumerable: true }) : target2,
45
45
  mod
46
46
  ));
47
47
 
@@ -9683,15 +9683,15 @@ var require_implementation = __commonJS({
9683
9683
  return str2;
9684
9684
  };
9685
9685
  module.exports = function bind(that) {
9686
- var target = this;
9687
- if (typeof target !== "function" || toStr.apply(target) !== funcType) {
9688
- throw new TypeError(ERROR_MESSAGE + target);
9686
+ var target2 = this;
9687
+ if (typeof target2 !== "function" || toStr.apply(target2) !== funcType) {
9688
+ throw new TypeError(ERROR_MESSAGE + target2);
9689
9689
  }
9690
9690
  var args = slicy(arguments, 1);
9691
9691
  var bound;
9692
9692
  var binder = function() {
9693
9693
  if (this instanceof bound) {
9694
- var result = target.apply(
9694
+ var result = target2.apply(
9695
9695
  this,
9696
9696
  concatty(args, arguments)
9697
9697
  );
@@ -9700,21 +9700,21 @@ var require_implementation = __commonJS({
9700
9700
  }
9701
9701
  return this;
9702
9702
  }
9703
- return target.apply(
9703
+ return target2.apply(
9704
9704
  that,
9705
9705
  concatty(args, arguments)
9706
9706
  );
9707
9707
  };
9708
- var boundLength = max(0, target.length - args.length);
9708
+ var boundLength = max(0, target2.length - args.length);
9709
9709
  var boundArgs = [];
9710
9710
  for (var i = 0; i < boundLength; i++) {
9711
9711
  boundArgs[i] = "$" + i;
9712
9712
  }
9713
9713
  bound = Function("binder", "return function (" + joiny(boundArgs, ",") + "){ return binder.apply(this,arguments); }")(binder);
9714
- if (target.prototype) {
9714
+ if (target2.prototype) {
9715
9715
  var Empty = function Empty2() {
9716
9716
  };
9717
- Empty.prototype = target.prototype;
9717
+ Empty.prototype = target2.prototype;
9718
9718
  bound.prototype = new Empty();
9719
9719
  Empty.prototype = null;
9720
9720
  }
@@ -12219,8 +12219,8 @@ var require_follow_redirects = __commonJS({
12219
12219
  }
12220
12220
  return input;
12221
12221
  }
12222
- function spreadUrlObject(urlObject, target) {
12223
- var spread = target || {};
12222
+ function spreadUrlObject(urlObject, target2) {
12223
+ var spread = target2 || {};
12224
12224
  for (var key of preservedUrlFields) {
12225
12225
  spread[key] = urlObject[key];
12226
12226
  }
@@ -12768,22 +12768,22 @@ var require_axios = __commonJS({
12768
12768
  }
12769
12769
  if (!("toJSON" in source)) {
12770
12770
  visited.add(source);
12771
- let target;
12771
+ let target2;
12772
12772
  if (isSet(source)) {
12773
- target = [];
12773
+ target2 = [];
12774
12774
  for (const value2 of source) {
12775
12775
  const reducedValue = visit(value2);
12776
- !isUndefined(reducedValue) && target.push(reducedValue);
12776
+ !isUndefined(reducedValue) && target2.push(reducedValue);
12777
12777
  }
12778
12778
  } else {
12779
- target = isArray(source) ? [] : {};
12779
+ target2 = isArray(source) ? [] : {};
12780
12780
  forEach(source, (value2, key) => {
12781
12781
  const reducedValue = visit(value2);
12782
- !isUndefined(reducedValue) && (target[key] = reducedValue);
12782
+ !isUndefined(reducedValue) && (target2[key] = reducedValue);
12783
12783
  });
12784
12784
  }
12785
12785
  visited.delete(source);
12786
- return target;
12786
+ return target2;
12787
12787
  }
12788
12788
  }
12789
12789
  return source;
@@ -13234,7 +13234,7 @@ var require_axios = __commonJS({
13234
13234
  }
13235
13235
  static concat(first, ...targets) {
13236
13236
  const computed = new this(first);
13237
- targets.forEach((target) => computed.set(target));
13237
+ targets.forEach((target2) => computed.set(target2));
13238
13238
  return computed;
13239
13239
  }
13240
13240
  static accessor(header) {
@@ -13862,27 +13862,27 @@ var require_axios = __commonJS({
13862
13862
  return obj;
13863
13863
  }
13864
13864
  function formDataToJSON(formData) {
13865
- function buildPath(path2, value2, target, index) {
13865
+ function buildPath(path2, value2, target2, index) {
13866
13866
  throwIfDepthExceeded(index);
13867
13867
  let name = path2[index++];
13868
13868
  if (name === "__proto__") return true;
13869
13869
  const isNumericKey = Number.isFinite(+name);
13870
13870
  const isLast = index >= path2.length;
13871
- name = !name && utils$1.isArray(target) ? target.length : name;
13871
+ name = !name && utils$1.isArray(target2) ? target2.length : name;
13872
13872
  if (isLast) {
13873
- if (utils$1.hasOwnProp(target, name)) {
13874
- target[name] = utils$1.isArray(target[name]) ? target[name].concat(value2) : [target[name], value2];
13873
+ if (utils$1.hasOwnProp(target2, name)) {
13874
+ target2[name] = utils$1.isArray(target2[name]) ? target2[name].concat(value2) : [target2[name], value2];
13875
13875
  } else {
13876
- target[name] = value2;
13876
+ target2[name] = value2;
13877
13877
  }
13878
13878
  return !isNumericKey;
13879
13879
  }
13880
- if (!utils$1.hasOwnProp(target, name) || !utils$1.isObject(target[name])) {
13881
- target[name] = [];
13880
+ if (!utils$1.hasOwnProp(target2, name) || !utils$1.isObject(target2[name])) {
13881
+ target2[name] = [];
13882
13882
  }
13883
- const result = buildPath(path2, value2, target[name], index);
13884
- if (result && utils$1.isArray(target[name])) {
13885
- target[name] = arrayToObject(target[name]);
13883
+ const result = buildPath(path2, value2, target2[name], index);
13884
+ if (result && utils$1.isArray(target2[name])) {
13885
+ target2[name] = arrayToObject(target2[name]);
13886
13886
  }
13887
13887
  return !isNumericKey;
13888
13888
  }
@@ -16043,11 +16043,11 @@ var require_axios = __commonJS({
16043
16043
  writable: true,
16044
16044
  configurable: true
16045
16045
  });
16046
- function getMergedValue(target, source, prop, caseless) {
16047
- if (utils$1.isPlainObject(target) && utils$1.isPlainObject(source)) {
16046
+ function getMergedValue(target2, source, prop, caseless) {
16047
+ if (utils$1.isPlainObject(target2) && utils$1.isPlainObject(source)) {
16048
16048
  return utils$1.merge.call({
16049
16049
  caseless
16050
- }, target, source);
16050
+ }, target2, source);
16051
16051
  } else if (utils$1.isPlainObject(source)) {
16052
16052
  return utils$1.merge({}, source);
16053
16053
  } else if (utils$1.isArray(source)) {
@@ -16862,14 +16862,14 @@ var require_axios = __commonJS({
16862
16862
  Response
16863
16863
  } = env;
16864
16864
  const seeds = [Request, Response, fetch2];
16865
- let len = seeds.length, i = len, seed, target, map = seedCache;
16865
+ let len = seeds.length, i = len, seed, target2, map = seedCache;
16866
16866
  while (i--) {
16867
16867
  seed = seeds[i];
16868
- target = map.get(seed);
16869
- target === void 0 && map.set(seed, target = i ? /* @__PURE__ */ new Map() : factory(env));
16870
- map = target;
16868
+ target2 = map.get(seed);
16869
+ target2 === void 0 && map.set(seed, target2 = i ? /* @__PURE__ */ new Map() : factory(env));
16870
+ map = target2;
16871
16871
  }
16872
- return target;
16872
+ return target2;
16873
16873
  };
16874
16874
  getFetch();
16875
16875
  var knownAdapters = {
@@ -18377,46 +18377,46 @@ var require_utils = __commonJS({
18377
18377
  obj[key] = value2;
18378
18378
  }
18379
18379
  };
18380
- var merge = function merge2(target, source, options) {
18380
+ var merge = function merge2(target2, source, options) {
18381
18381
  if (!source) {
18382
- return target;
18382
+ return target2;
18383
18383
  }
18384
18384
  if (typeof source !== "object" && typeof source !== "function") {
18385
- if (isArray(target)) {
18386
- var nextIndex = target.length;
18385
+ if (isArray(target2)) {
18386
+ var nextIndex = target2.length;
18387
18387
  if (options && typeof options.arrayLimit === "number" && nextIndex >= options.arrayLimit) {
18388
18388
  if (options.throwOnLimitExceeded) {
18389
18389
  throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array.");
18390
18390
  }
18391
- return markOverflow(arrayToObject(target.concat(source), options), nextIndex);
18392
- }
18393
- target[nextIndex] = source;
18394
- } else if (target && typeof target === "object") {
18395
- if (isOverflow(target)) {
18396
- var newIndex = getMaxIndex(target) + 1;
18397
- target[newIndex] = source;
18398
- setMaxIndex(target, newIndex);
18391
+ return markOverflow(arrayToObject(target2.concat(source), options), nextIndex);
18392
+ }
18393
+ target2[nextIndex] = source;
18394
+ } else if (target2 && typeof target2 === "object") {
18395
+ if (isOverflow(target2)) {
18396
+ var newIndex = getMaxIndex(target2) + 1;
18397
+ target2[newIndex] = source;
18398
+ setMaxIndex(target2, newIndex);
18399
18399
  } else if (options && options.strictMerge) {
18400
- return [target, source];
18400
+ return [target2, source];
18401
18401
  } else if (options && (options.plainObjects || options.allowPrototypes) || !has.call(Object.prototype, source)) {
18402
- target[source] = true;
18402
+ target2[source] = true;
18403
18403
  }
18404
18404
  } else {
18405
- return [target, source];
18405
+ return [target2, source];
18406
18406
  }
18407
- return target;
18407
+ return target2;
18408
18408
  }
18409
- if (!target || typeof target !== "object") {
18409
+ if (!target2 || typeof target2 !== "object") {
18410
18410
  if (isOverflow(source)) {
18411
18411
  var sourceKeys = Object.keys(source);
18412
- var result = options && options.plainObjects ? { __proto__: null, 0: target } : { 0: target };
18412
+ var result = options && options.plainObjects ? { __proto__: null, 0: target2 } : { 0: target2 };
18413
18413
  for (var m = 0; m < sourceKeys.length; m++) {
18414
18414
  var oldKey = parseInt(sourceKeys[m], 10);
18415
18415
  result[oldKey + 1] = source[sourceKeys[m]];
18416
18416
  }
18417
18417
  return markOverflow(result, getMaxIndex(source) + 1);
18418
18418
  }
18419
- var combined = [target].concat(source);
18419
+ var combined = [target2].concat(source);
18420
18420
  if (options && typeof options.arrayLimit === "number" && combined.length > options.arrayLimit) {
18421
18421
  if (options.throwOnLimitExceeded) {
18422
18422
  throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array.");
@@ -18425,30 +18425,30 @@ var require_utils = __commonJS({
18425
18425
  }
18426
18426
  return combined;
18427
18427
  }
18428
- var mergeTarget = target;
18429
- if (isArray(target) && !isArray(source)) {
18430
- mergeTarget = arrayToObject(target, options);
18428
+ var mergeTarget = target2;
18429
+ if (isArray(target2) && !isArray(source)) {
18430
+ mergeTarget = arrayToObject(target2, options);
18431
18431
  }
18432
- if (isArray(target) && isArray(source)) {
18432
+ if (isArray(target2) && isArray(source)) {
18433
18433
  source.forEach(function(item, i) {
18434
- if (has.call(target, i)) {
18435
- var targetItem = target[i];
18434
+ if (has.call(target2, i)) {
18435
+ var targetItem = target2[i];
18436
18436
  if (targetItem && typeof targetItem === "object" && item && typeof item === "object") {
18437
- target[i] = merge2(targetItem, item, options);
18437
+ target2[i] = merge2(targetItem, item, options);
18438
18438
  } else {
18439
- target[target.length] = item;
18439
+ target2[target2.length] = item;
18440
18440
  }
18441
18441
  } else {
18442
- target[i] = item;
18442
+ target2[i] = item;
18443
18443
  }
18444
18444
  });
18445
- if (options && typeof options.arrayLimit === "number" && target.length > options.arrayLimit) {
18445
+ if (options && typeof options.arrayLimit === "number" && target2.length > options.arrayLimit) {
18446
18446
  if (options.throwOnLimitExceeded) {
18447
18447
  throw new RangeError("Array limit exceeded. Only " + options.arrayLimit + " element" + (options.arrayLimit === 1 ? "" : "s") + " allowed in an array.");
18448
18448
  }
18449
- return markOverflow(arrayToObject(target, options), target.length - 1);
18449
+ return markOverflow(arrayToObject(target2, options), target2.length - 1);
18450
18450
  }
18451
- return target;
18451
+ return target2;
18452
18452
  }
18453
18453
  return Object.keys(source).reduce(function(acc, key) {
18454
18454
  var value2 = source[key];
@@ -18469,11 +18469,11 @@ var require_utils = __commonJS({
18469
18469
  return acc;
18470
18470
  }, mergeTarget);
18471
18471
  };
18472
- var assign = function assignSingleSource(target, source) {
18472
+ var assign = function assignSingleSource(target2, source) {
18473
18473
  return Object.keys(source).reduce(function(acc, key) {
18474
18474
  setProperty(acc, key, source[key]);
18475
18475
  return acc;
18476
- }, target);
18476
+ }, target2);
18477
18477
  };
18478
18478
  var decode2 = function(str2, defaultDecoder, charset) {
18479
18479
  var strWithoutPlus = str2.replace(/\+/g, " ");
@@ -20911,7 +20911,7 @@ var require_node_gyp_build = __commonJS({
20911
20911
  if (prebuild) return prebuild;
20912
20912
  var nearby = resolve(path.dirname(process.execPath));
20913
20913
  if (nearby) return nearby;
20914
- var target = [
20914
+ var target2 = [
20915
20915
  "platform=" + platform,
20916
20916
  "arch=" + arch,
20917
20917
  "runtime=" + runtime,
@@ -20924,7 +20924,7 @@ var require_node_gyp_build = __commonJS({
20924
20924
  typeof __webpack_require__ === "function" ? "webpack=true" : ""
20925
20925
  // eslint-disable-line
20926
20926
  ].filter(Boolean).join(" ");
20927
- throw new Error("No native build was found for " + target + "\n loaded from: " + dir + "\n");
20927
+ throw new Error("No native build was found for " + target2 + "\n loaded from: " + dir + "\n");
20928
20928
  function resolve(dir2) {
20929
20929
  var tuples = readdirSync(path.join(dir2, "prebuilds")).map(parseTuple);
20930
20930
  var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0];
@@ -21095,17 +21095,17 @@ var require_buffer_util = __commonJS({
21095
21095
  function concat(list2, totalLength) {
21096
21096
  if (list2.length === 0) return EMPTY_BUFFER;
21097
21097
  if (list2.length === 1) return list2[0];
21098
- const target = Buffer.allocUnsafe(totalLength);
21098
+ const target2 = Buffer.allocUnsafe(totalLength);
21099
21099
  let offset = 0;
21100
21100
  for (let i = 0; i < list2.length; i++) {
21101
21101
  const buf = list2[i];
21102
- target.set(buf, offset);
21102
+ target2.set(buf, offset);
21103
21103
  offset += buf.length;
21104
21104
  }
21105
21105
  if (offset < totalLength) {
21106
- return new FastBuffer(target.buffer, target.byteOffset, offset);
21106
+ return new FastBuffer(target2.buffer, target2.byteOffset, offset);
21107
21107
  }
21108
- return target;
21108
+ return target2;
21109
21109
  }
21110
21110
  function _mask(source, mask, output, offset, length) {
21111
21111
  for (let i = 0; i < length; i++) {
@@ -22587,29 +22587,29 @@ var require_sender = __commonJS({
22587
22587
  offset += 2;
22588
22588
  payloadLength = 126;
22589
22589
  }
22590
- const target = Buffer.allocUnsafe(merge ? dataLength + offset : offset);
22591
- target[0] = options.fin ? options.opcode | 128 : options.opcode;
22592
- if (options.rsv1) target[0] |= 64;
22593
- target[1] = payloadLength;
22590
+ const target2 = Buffer.allocUnsafe(merge ? dataLength + offset : offset);
22591
+ target2[0] = options.fin ? options.opcode | 128 : options.opcode;
22592
+ if (options.rsv1) target2[0] |= 64;
22593
+ target2[1] = payloadLength;
22594
22594
  if (payloadLength === 126) {
22595
- target.writeUInt16BE(dataLength, 2);
22595
+ target2.writeUInt16BE(dataLength, 2);
22596
22596
  } else if (payloadLength === 127) {
22597
- target[2] = target[3] = 0;
22598
- target.writeUIntBE(dataLength, 4, 6);
22599
- }
22600
- if (!options.mask) return [target, data];
22601
- target[1] |= 128;
22602
- target[offset - 4] = mask[0];
22603
- target[offset - 3] = mask[1];
22604
- target[offset - 2] = mask[2];
22605
- target[offset - 1] = mask[3];
22606
- if (skipMasking) return [target, data];
22597
+ target2[2] = target2[3] = 0;
22598
+ target2.writeUIntBE(dataLength, 4, 6);
22599
+ }
22600
+ if (!options.mask) return [target2, data];
22601
+ target2[1] |= 128;
22602
+ target2[offset - 4] = mask[0];
22603
+ target2[offset - 3] = mask[1];
22604
+ target2[offset - 2] = mask[2];
22605
+ target2[offset - 1] = mask[3];
22606
+ if (skipMasking) return [target2, data];
22607
22607
  if (merge) {
22608
- applyMask(data, mask, target, offset, dataLength);
22609
- return [target];
22608
+ applyMask(data, mask, target2, offset, dataLength);
22609
+ return [target2];
22610
22610
  }
22611
22611
  applyMask(data, mask, data, 0, dataLength);
22612
- return [target, data];
22612
+ return [target2, data];
22613
22613
  }
22614
22614
  /**
22615
22615
  * Sends a close message to the other peer.
@@ -126168,6 +126168,11 @@ var makeAcknowledgements = (core) => {
126168
126168
  const acknowledgements = /* @__PURE__ */ new Map();
126169
126169
  const markWorking = async (binding, threadId, messageId) => {
126170
126170
  const adapter = adapterFor(binding.platform);
126171
+ if (adapter?.sendTyping !== void 0) {
126172
+ void adapter.sendTyping(binding).catch((error) => {
126173
+ host.log.info("chat could not show typing", { error: describeError(error) });
126174
+ });
126175
+ }
126171
126176
  if (adapter?.acknowledge === void 0) return;
126172
126177
  try {
126173
126178
  const ackId = await adapter.acknowledge(binding, messageId);
@@ -126180,14 +126185,14 @@ var makeAcknowledgements = (core) => {
126180
126185
  host.log.warn("chat could not acknowledge the message", { error: describeError(error) });
126181
126186
  }
126182
126187
  };
126183
- const clearWorking = async (binding, threadId) => {
126188
+ const clearWorking = async (binding, threadId, outcome) => {
126184
126189
  const adapter = adapterFor(binding.platform);
126185
126190
  const pending = acknowledgements.get(threadId);
126186
126191
  if (pending === void 0 || adapter?.clearAcknowledge === void 0) return;
126187
126192
  acknowledgements.delete(threadId);
126188
126193
  for (const entry of pending) {
126189
126194
  try {
126190
- await adapter.clearAcknowledge(binding, entry.messageId, entry.ackId);
126195
+ await adapter.clearAcknowledge(binding, entry.messageId, entry.ackId, outcome);
126191
126196
  } catch (error) {
126192
126197
  host.log.warn("chat could not clear the acknowledgement", {
126193
126198
  error: describeError(error)
@@ -126398,8 +126403,8 @@ var foldImEvent = (state, name, data) => {
126398
126403
  else if (nonEmpty2(data["projectId"]) !== null) patch.projectId = nonEmpty2(data["projectId"]);
126399
126404
  if (data["threadId"] === null) patch.threadId = null;
126400
126405
  else if (nonEmpty2(data["threadId"]) !== null) patch.threadId = nonEmpty2(data["threadId"]);
126401
- const target = readTarget(data["target"]);
126402
- if (target !== null) patch.target = target;
126406
+ const target2 = readTarget(data["target"]);
126407
+ if (target2 !== null) patch.target = target2;
126403
126408
  if (data["model"] === null) patch.model = null;
126404
126409
  else if (isRecord(data["model"])) {
126405
126410
  const instanceId = nonEmpty2(data["model"]["instanceId"]);
@@ -127136,10 +127141,10 @@ var makeApprovals = (core) => {
127136
127141
  const found = findApprovalByToken(core.state, token);
127137
127142
  if (found === void 0) return null;
127138
127143
  if (found.approval.resolved) return t("approval.alreadyHandled");
127139
- const target = bindingForChatKey(found.approval.chatKey);
127140
- if (target === void 0 || !isAllowedSender(target, operatorId)) {
127144
+ const target2 = bindingForChatKey(found.approval.chatKey);
127145
+ if (target2 === void 0 || !isAllowedSender(target2, operatorId)) {
127141
127146
  host.log.warn("chat ignored an approval click from someone not on the allow list", {
127142
- bot: target?.displayName ?? found.approval.chatKey,
127147
+ bot: target2?.displayName ?? found.approval.chatKey,
127143
127148
  operator: operatorId
127144
127149
  });
127145
127150
  return t("reply.notAllowed");
@@ -127248,13 +127253,13 @@ var makeChatSetup = (core, deps) => {
127248
127253
  await deliver(binding, t("repo.notFound", { query: arg }));
127249
127254
  return;
127250
127255
  }
127251
- const target = rows.find((row) => row.projectId === picked);
127252
- if (target === void 0) {
127256
+ const target2 = rows.find((row) => row.projectId === picked);
127257
+ if (target2 === void 0) {
127253
127258
  await deliver(binding, t("repo.gone"));
127254
127259
  return;
127255
127260
  }
127256
- if (target.current) {
127257
- await deliver(binding, t("repo.already", { title: target.title }));
127261
+ if (target2.current) {
127262
+ await deliver(binding, t("repo.already", { title: target2.title }));
127258
127263
  return;
127259
127264
  }
127260
127265
  const threadId = chatOf(core.state, chatKey).threadId;
@@ -127273,7 +127278,7 @@ var makeChatSetup = (core, deps) => {
127273
127278
  });
127274
127279
  listedProjectsByChat.delete(chatKey);
127275
127280
  host.log.info("chat picked a project", { bot: binding.displayName, projectId: picked });
127276
- await deliver(binding, t("repo.done", { title: target.title }));
127281
+ await deliver(binding, t("repo.done", { title: target2.title }));
127277
127282
  };
127278
127283
  const handleGroup = async (binding, name, senderId) => {
127279
127284
  const adapter = adapterFor(binding.platform);
@@ -127428,9 +127433,9 @@ var helpText = (t, options = {}) => [
127428
127433
  t("help.aliases"),
127429
127434
  ...options.panel === true ? ["", t("help.panel")] : []
127430
127435
  ].join("\n");
127431
- var describeTargets = (target, teams, t) => {
127432
- const current = target.kind === "thread" ? t("targets.currentThread") : t("targets.currentTeam", {
127433
- title: teams.find((team) => team.teamId === target.teamId)?.title ?? target.teamId
127436
+ var describeTargets = (target2, teams, t) => {
127437
+ const current = target2.kind === "thread" ? t("targets.currentThread") : t("targets.currentTeam", {
127438
+ title: teams.find((team) => team.teamId === target2.teamId)?.title ?? target2.teamId
127434
127439
  });
127435
127440
  const list2 = teams.length === 0 ? t("targets.noTeams") : [t("targets.teamList"), ...teams.map((team) => `\xB7 ${team.title}`)].join("\n");
127436
127441
  return [current, "", list2, "", t("targets.hint")].join("\n");
@@ -127680,7 +127685,7 @@ var makeCommands = (core, deps) => {
127680
127685
  turnId: activeTurnId,
127681
127686
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
127682
127687
  });
127683
- await clearWorking(binding, threadId);
127688
+ await clearWorking(binding, threadId, "stopped");
127684
127689
  await deliver(binding, t("command.stopped"));
127685
127690
  return true;
127686
127691
  }
@@ -128146,19 +128151,19 @@ var makeInbound = (core, deps) => {
128146
128151
  );
128147
128152
  const projectPromptCooldown = makeCooldown(PROJECT_PROMPT_COOLDOWN_MS, () => Date.now());
128148
128153
  const handledMessages = makeBoundedSeen(SEEN_MESSAGE_LIMIT);
128149
- const alreadyHandled = (target, messageId) => {
128150
- return !handledMessages.claim(`${chatKeyOf(target)}:${messageId}`);
128154
+ const alreadyHandled = (target2, messageId) => {
128155
+ return !handledMessages.claim(`${chatKeyOf(target2)}:${messageId}`);
128151
128156
  };
128152
- const turnAwayStranger = (target, sender) => {
128157
+ const turnAwayStranger = (target2, sender) => {
128153
128158
  host.log.warn("chat ignored a message from someone not on the allow list", {
128154
- bot: target.displayName,
128159
+ bot: target2.displayName,
128155
128160
  sender
128156
128161
  });
128157
128162
  if (sender === null) return;
128158
- if (!notAllowedReplyCooldown.tryAcquire(`${target.rowId}:${sender}`)) return;
128163
+ if (!notAllowedReplyCooldown.tryAcquire(`${target2.rowId}:${sender}`)) return;
128159
128164
  enqueueForChat(
128160
- chatKeyOf(target),
128161
- () => deliver(target, t("reply.notAllowedYet", { id: sender }))
128165
+ chatKeyOf(target2),
128166
+ () => deliver(target2, t("reply.notAllowedYet", { id: sender }))
128162
128167
  );
128163
128168
  };
128164
128169
  const inboundHandlersFor = (bot) => ({
@@ -128201,16 +128206,16 @@ var makeInbound = (core, deps) => {
128201
128206
  return;
128202
128207
  }
128203
128208
  enqueueForChat(chatKeyOf(arrived), async () => {
128204
- const target = bindingOf2(current, message.chatId);
128205
- const chatKey = chatKeyOf(target);
128206
- const teams = await fetchTeams(target);
128207
- if (await handleCommand(target, message.text, teams ?? [], message.senderId)) return;
128208
- if (target.projectId === "") {
128209
+ const target2 = bindingOf2(current, message.chatId);
128210
+ const chatKey = chatKeyOf(target2);
128211
+ const teams = await fetchTeams(target2);
128212
+ if (await handleCommand(target2, message.text, teams ?? [], message.senderId)) return;
128213
+ if (target2.projectId === "") {
128209
128214
  const asked = message.text.trim();
128210
128215
  if (/^[1-9]\d{0,2}$/u.test(asked) && listedProjectsByChat.has(chatKey)) {
128211
- await handleRepo(target, asked);
128216
+ await handleRepo(target2, asked);
128212
128217
  } else if (projectPromptCooldown.tryAcquire(chatKey)) {
128213
- await promptProject(target);
128218
+ await promptProject(target2);
128214
128219
  }
128215
128220
  return;
128216
128221
  }
@@ -128218,23 +128223,23 @@ var makeInbound = (core, deps) => {
128218
128223
  if (boundThread !== null && message.text !== "" && await questionFlow.answerByText(chatKey, boundThread, message.text)) {
128219
128224
  return;
128220
128225
  }
128221
- const project = await host.projections.getProject(target.projectId);
128226
+ const project = await host.projections.getProject(target2.projectId);
128222
128227
  if (project === null || project.archivedAt != null) {
128223
128228
  if (project === null) {
128224
128229
  host.log.warn("chat cannot start work: the chat's project is gone", {
128225
- bot: target.displayName,
128226
- projectId: target.projectId
128230
+ bot: target2.displayName,
128231
+ projectId: target2.projectId
128227
128232
  });
128228
128233
  }
128229
128234
  if (archivedReplyCooldown.tryAcquire(chatKey)) {
128230
128235
  await deliver(
128231
- target,
128236
+ target2,
128232
128237
  project === null ? t("reply.projectMissing") : t("reply.projectArchived", { title: project.title })
128233
128238
  );
128234
128239
  }
128235
128240
  return;
128236
128241
  }
128237
- const routed = targetOf(target);
128242
+ const routed = targetOf(target2);
128238
128243
  const attachmentsOnly = message.text.trim() === "" && message.resources.length > 0;
128239
128244
  if (routed.kind === "team") {
128240
128245
  if (teams !== null && !teams.some((team) => team.teamId === routed.teamId)) {
@@ -128243,21 +128248,21 @@ var makeInbound = (core, deps) => {
128243
128248
  target: { kind: "thread" },
128244
128249
  threadId: null
128245
128250
  });
128246
- await deliver(target, t("reply.teamGone"));
128251
+ await deliver(target2, t("reply.teamGone"));
128247
128252
  } else {
128248
- if (message.resources.length > 0) await deliver(target, t("reply.attachmentsNoTeam"));
128253
+ if (message.resources.length > 0) await deliver(target2, t("reply.attachmentsNoTeam"));
128249
128254
  if (attachmentsOnly) return;
128250
- await startTeamRun(target, routed.teamId, message.text);
128251
- await markWorking(target, chatKey, message.messageId);
128255
+ await startTeamRun(target2, routed.teamId, message.text);
128256
+ await markWorking(target2, chatKey, message.messageId);
128252
128257
  return;
128253
128258
  }
128254
128259
  }
128255
128260
  if (attachmentsOnly) {
128256
- await receiveAttachmentsOnly(target, message);
128261
+ await receiveAttachmentsOnly(target2, message);
128257
128262
  return;
128258
128263
  }
128259
- const threadId = await startTurn(target, message);
128260
- if (threadId !== null) await markWorking(target, threadId, message.messageId);
128264
+ const threadId = await startTurn(target2, message);
128265
+ if (threadId !== null) await markWorking(target2, threadId, message.messageId);
128261
128266
  });
128262
128267
  }
128263
128268
  });
@@ -128376,12 +128381,12 @@ var makeQuestionFlow = (host) => {
128376
128381
  const redraw = async (requestId, questionId) => {
128377
128382
  const record2 = recordOf(requestId);
128378
128383
  const item = itemOf(requestId, questionId);
128379
- const target = record2 === void 0 ? void 0 : host.target(record2.chatKey);
128380
- if (record2 === void 0 || item?.cardId === void 0 || target === void 0) return;
128384
+ const target2 = record2 === void 0 ? void 0 : host.target(record2.chatKey);
128385
+ if (record2 === void 0 || item?.cardId === void 0 || target2 === void 0) return;
128381
128386
  if (record2.resolved || item.answer !== void 0) return;
128382
128387
  try {
128383
- await target.adapter.choiceCards?.update(
128384
- target.binding,
128388
+ await target2.adapter.choiceCards?.update(
128389
+ target2.binding,
128385
128390
  item.cardId,
128386
128391
  questionCardOf(item, record2.items.indexOf(item), record2.items.length, t)
128387
128392
  );
@@ -128392,11 +128397,11 @@ var makeQuestionFlow = (host) => {
128392
128397
  const freeze = async (requestId, questionId) => {
128393
128398
  const record2 = recordOf(requestId);
128394
128399
  const item = itemOf(requestId, questionId);
128395
- const target = record2 === void 0 ? void 0 : host.target(record2.chatKey);
128396
- if (record2 === void 0 || item?.cardId === void 0 || target === void 0) return;
128400
+ const target2 = record2 === void 0 ? void 0 : host.target(record2.chatKey);
128401
+ if (record2 === void 0 || item?.cardId === void 0 || target2 === void 0) return;
128397
128402
  try {
128398
- await target.adapter.choiceCards?.update(
128399
- target.binding,
128403
+ await target2.adapter.choiceCards?.update(
128404
+ target2.binding,
128400
128405
  item.cardId,
128401
128406
  questionSettledCardOf(
128402
128407
  item,
@@ -128422,9 +128427,9 @@ var makeQuestionFlow = (host) => {
128422
128427
  };
128423
128428
  const post = async (requestId) => {
128424
128429
  const first = recordOf(requestId);
128425
- const target = first === void 0 ? void 0 : host.target(first.chatKey);
128426
- if (first === void 0 || target === void 0) return;
128427
- const cards = target.adapter.choiceCards;
128430
+ const target2 = first === void 0 ? void 0 : host.target(first.chatKey);
128431
+ if (first === void 0 || target2 === void 0) return;
128432
+ const cards = target2.adapter.choiceCards;
128428
128433
  if (cards === void 0) {
128429
128434
  await sayNext(requestId);
128430
128435
  return;
@@ -128435,7 +128440,7 @@ var makeQuestionFlow = (host) => {
128435
128440
  if (record2 === void 0 || record2.resolved || item === void 0) return;
128436
128441
  try {
128437
128442
  const cardId = await cards.open(
128438
- target.binding,
128443
+ target2.binding,
128439
128444
  questionCardOf(item, record2.items.indexOf(item), record2.items.length, t)
128440
128445
  );
128441
128446
  if (cardId === null) continue;
@@ -128450,10 +128455,10 @@ var makeQuestionFlow = (host) => {
128450
128455
  }
128451
128456
  };
128452
128457
  const offer = (chatKey, threadId, pending) => {
128453
- const target = host.target(chatKey);
128454
- if (target === void 0) return;
128455
- const buttons = target.adapter.choiceCards !== void 0;
128456
- if (!buttons && target.adapter.answerByText === void 0) {
128458
+ const target2 = host.target(chatKey);
128459
+ if (target2 === void 0) return;
128460
+ const buttons = target2.adapter.choiceCards !== void 0;
128461
+ if (!buttons && target2.adapter.answerByText === void 0) {
128457
128462
  host.warn("chat cannot show questions on this platform");
128458
128463
  return;
128459
128464
  }
@@ -128674,8 +128679,8 @@ var makeQueueFlow = (host, deps) => {
128674
128679
  intent: execution.intents.find((intent) => intent.intentId === intentId)
128675
128680
  });
128676
128681
  const noteQueued = async (chatKey, threadId, messageId, text3) => {
128677
- const target = host.target(chatKey);
128678
- if (target === void 0) return;
128682
+ const target2 = host.target(chatKey);
128683
+ if (target2 === void 0) return;
128679
128684
  let execution;
128680
128685
  try {
128681
128686
  execution = await deps.readExecution(threadId);
@@ -128689,7 +128694,7 @@ var makeQueueFlow = (host, deps) => {
128689
128694
  (other) => other.intentId !== intent.intentId && LIVE_STATUSES.has(other.status) && other.sequence < intent.sequence
128690
128695
  );
128691
128696
  if (!waiting) return;
128692
- const cards = target.adapter.choiceCards;
128697
+ const cards = target2.adapter.choiceCards;
128693
128698
  if (cards === void 0) {
128694
128699
  await host.say(chatKey, t("queue.plainNotice"));
128695
128700
  return;
@@ -128718,7 +128723,7 @@ var makeQueueFlow = (host, deps) => {
128718
128723
  host.commit("queue-settled", { intentId, outcome: view.outcome });
128719
128724
  return;
128720
128725
  }
128721
- const cardId = await cards.open(target.binding, queueCardOf(record2, view, null, t));
128726
+ const cardId = await cards.open(target2.binding, queueCardOf(record2, view, null, t));
128722
128727
  if (cardId === null) return;
128723
128728
  host.commit("queue-carded", { intentId, cardId });
128724
128729
  shown.set(intentId, queueViewKey(view, null));
@@ -128729,8 +128734,8 @@ var makeQueueFlow = (host, deps) => {
128729
128734
  };
128730
128735
  const redraw = async (intentId, released) => {
128731
128736
  const record2 = recordOf(intentId);
128732
- const target = record2 === void 0 ? void 0 : host.target(record2.chatKey);
128733
- if (record2 === void 0 || record2.settled !== void 0 || target === void 0) return;
128737
+ const target2 = record2 === void 0 ? void 0 : host.target(record2.chatKey);
128738
+ if (record2 === void 0 || record2.settled !== void 0 || target2 === void 0) return;
128734
128739
  if (record2.cardId === void 0) return;
128735
128740
  let execution;
128736
128741
  try {
@@ -128754,14 +128759,14 @@ var makeQueueFlow = (host, deps) => {
128754
128759
  }
128755
128760
  };
128756
128761
  const paint = async (record2, view) => {
128757
- const target = host.target(record2.chatKey);
128758
- const cards = target?.adapter.choiceCards;
128759
- if (target === void 0 || cards === void 0 || record2.cardId === void 0) return;
128762
+ const target2 = host.target(record2.chatKey);
128763
+ const cards = target2?.adapter.choiceCards;
128764
+ if (target2 === void 0 || cards === void 0 || record2.cardId === void 0) return;
128760
128765
  const note = notes.get(record2.intentId) ?? null;
128761
128766
  const key = queueViewKey(view, note);
128762
128767
  if (shown.get(record2.intentId) === key) return;
128763
128768
  try {
128764
- await cards.update(target.binding, record2.cardId, queueCardOf(record2, view, note, t));
128769
+ await cards.update(target2.binding, record2.cardId, queueCardOf(record2, view, note, t));
128765
128770
  shown.set(record2.intentId, key);
128766
128771
  } catch (error) {
128767
128772
  host.warn("chat could not update the queued message card", error);
@@ -132374,13 +132379,13 @@ var LinkifyIt = class {
132374
132379
  var import_punycode = __toESM(require_punycode(), 1);
132375
132380
  var __defProp2 = Object.defineProperty;
132376
132381
  var __exportAll = (all, no_symbols) => {
132377
- let target = {};
132378
- for (var name in all) __defProp2(target, name, {
132382
+ let target2 = {};
132383
+ for (var name in all) __defProp2(target2, name, {
132379
132384
  get: all[name],
132380
132385
  enumerable: true
132381
132386
  });
132382
- if (!no_symbols) __defProp2(target, Symbol.toStringTag, { value: "Module" });
132383
- return target;
132387
+ if (!no_symbols) __defProp2(target2, Symbol.toStringTag, { value: "Module" });
132388
+ return target2;
132384
132389
  };
132385
132390
  var utils_exports = /* @__PURE__ */ __exportAll({
132386
132391
  arrayReplaceAt: () => arrayReplaceAt,
@@ -137092,7 +137097,7 @@ var en_default = {
137092
137097
  },
137093
137098
  deliveryPlatformChatId: {
137094
137099
  label: "Platform chat ID",
137095
- description: "Lark open_id/chat_id, Telegram chat id, WeCom user/group id, etc.",
137100
+ description: "Lark open_id/chat_id, Telegram chat id (a forum topic: chat id:topic id), WeCom user/group id, etc.",
137096
137101
  placeholder: "oc_\u2026 / ou_\u2026 / -100\u2026"
137097
137102
  },
137098
137103
  queueMode: {
@@ -137518,7 +137523,13 @@ var en_default = {
137518
137523
  running: "Checking {{rowId}}\u2026",
137519
137524
  done: "Connection OK",
137520
137525
  failed: "Connection failed (ref {{ref}})",
137521
- notSaved: "Save this row first (credentials are read from saved config only)."
137526
+ notSaved: "Save this row first (credentials are read from saved config only).",
137527
+ hint: {
137528
+ badToken: "This does not look like a bot token. Copy it again from BotFather: digits, a colon, then the key (ref {{ref}})",
137529
+ unauthorized: "Telegram does not accept this token. It may have been revoked; get the current one from BotFather (ref {{ref}})",
137530
+ notBot: "This token does not belong to a bot. Use the token BotFather gave you (ref {{ref}})",
137531
+ webhookActive: "This bot has a webhook set by another service, so it cannot receive messages here. Remove the webhook there, then check again (ref {{ref}})"
137532
+ }
137522
137533
  },
137523
137534
  copyDiagnostics: {
137524
137535
  label: "Copy diagnostics",
@@ -137545,6 +137556,21 @@ var en_default = {
137545
137556
  failed: "Could not verify the Lark app (ref {{ref}})",
137546
137557
  notLark: "This row is not a saved Lark bot."
137547
137558
  }
137559
+ },
137560
+ menu: {
137561
+ new: "Start a new session with the next message",
137562
+ stop: "Stop the turn that is running",
137563
+ continue: "Resume sending after a stop or a failure",
137564
+ status: "What is going on right now",
137565
+ sessions: "List the sessions for this chat's project",
137566
+ resume: "Switch to a session (number from /sessions)",
137567
+ model: "See or switch the model",
137568
+ plan: "Toggle plan mode",
137569
+ repo: "Pick the project this chat works on",
137570
+ team: "Send the next messages to a team",
137571
+ thread: "Go back to a normal session",
137572
+ panel: "Open the command panel",
137573
+ help: "Show all commands"
137548
137574
  }
137549
137575
  };
137550
137576
 
@@ -137677,7 +137703,7 @@ var zh_CN_default = {
137677
137703
  },
137678
137704
  deliveryPlatformChatId: {
137679
137705
  label: "\u5E73\u53F0\u804A\u5929 ID",
137680
- description: "\u98DE\u4E66 open_id\uFF0Fchat_id\u3001Telegram chat id\u3001\u4F01\u5FAE\u7528\u6237\uFF0F\u7FA4 id \u7B49\u3002",
137706
+ description: "\u98DE\u4E66 open_id\uFF0Fchat_id\u3001Telegram chat id\uFF08\u8BBA\u575B\u8BDD\u9898\u586B \u7FA4\u53F7:\u8BDD\u9898\u53F7\uFF09\u3001\u4F01\u5FAE\u7528\u6237\uFF0F\u7FA4 id \u7B49\u3002",
137681
137707
  placeholder: "oc_\u2026 / ou_\u2026 / -100\u2026"
137682
137708
  },
137683
137709
  queueMode: {
@@ -138103,7 +138129,13 @@ var zh_CN_default = {
138103
138129
  running: "\u6B63\u5728\u68C0\u67E5 {{rowId}} \u2026",
138104
138130
  done: "\u8FDE\u63A5\u6B63\u5E38",
138105
138131
  failed: "\u8FDE\u63A5\u5931\u8D25\uFF08\u53C2\u8003\u53F7 {{ref}}\uFF09",
138106
- notSaved: "\u8BF7\u5148\u4FDD\u5B58\u8FD9\u4E00\u884C\u518D\u68C0\u67E5\u8FDE\u63A5\uFF08\u51ED\u636E\u53EA\u4ECE\u5DF2\u4FDD\u5B58\u914D\u7F6E\u8BFB\u53D6\uFF09\u3002"
138132
+ notSaved: "\u8BF7\u5148\u4FDD\u5B58\u8FD9\u4E00\u884C\u518D\u68C0\u67E5\u8FDE\u63A5\uFF08\u51ED\u636E\u53EA\u4ECE\u5DF2\u4FDD\u5B58\u914D\u7F6E\u8BFB\u53D6\uFF09\u3002",
138133
+ hint: {
138134
+ badToken: "\u8FD9\u4E0D\u50CF\u673A\u5668\u4EBA\u7684 token\u3002\u5230 BotFather \u91CD\u65B0\u590D\u5236\u4E00\u4EFD\uFF1A\u6570\u5B57\u3001\u5192\u53F7\uFF0C\u540E\u9762\u662F\u5BC6\u94A5\uFF08\u53C2\u8003\u53F7 {{ref}}\uFF09",
138135
+ unauthorized: "Telegram \u4E0D\u8BA4\u8FD9\u4E2A token\uFF0C\u53EF\u80FD\u5DF2\u7ECF\u4F5C\u5E9F\u3002\u5230 BotFather \u53D6\u73B0\u5728\u7684\u90A3\u4E00\u4EFD\uFF08\u53C2\u8003\u53F7 {{ref}}\uFF09",
138136
+ notBot: "\u8FD9\u4E2A token \u4E0D\u662F\u673A\u5668\u4EBA\u7684\u3002\u8BF7\u7528 BotFather \u7ED9\u7684\u90A3\u4E00\u4EFD\uFF08\u53C2\u8003\u53F7 {{ref}}\uFF09",
138137
+ webhookActive: "\u8FD9\u4E2A\u673A\u5668\u4EBA\u88AB\u522B\u7684\u670D\u52A1\u8BBE\u4E86 webhook\uFF0C\u5728\u8FD9\u91CC\u6536\u4E0D\u5230\u6D88\u606F\u3002\u5148\u5230\u90A3\u8FB9\u64A4\u6389 webhook\uFF0C\u518D\u68C0\u67E5\u4E00\u6B21\uFF08\u53C2\u8003\u53F7 {{ref}}\uFF09"
138138
+ }
138107
138139
  },
138108
138140
  copyDiagnostics: {
138109
138141
  label: "\u590D\u5236\u8BCA\u65AD",
@@ -138130,6 +138162,21 @@ var zh_CN_default = {
138130
138162
  failed: "\u65E0\u6CD5\u9A8C\u8BC1\u98DE\u4E66\u5E94\u7528\uFF08\u53C2\u8003\u53F7 {{ref}}\uFF09",
138131
138163
  notLark: "\u8FD9\u4E00\u884C\u4E0D\u662F\u5DF2\u4FDD\u5B58\u7684\u98DE\u4E66\u673A\u5668\u4EBA\u3002"
138132
138164
  }
138165
+ },
138166
+ menu: {
138167
+ new: "\u4E0B\u4E00\u53E5\u5F00\u4E00\u4E2A\u65B0\u4F1A\u8BDD",
138168
+ stop: "\u505C\u6389\u6B63\u5728\u8DD1\u7684\u8FD9\u4E00\u8F6E",
138169
+ continue: "\u505C\u4E0B\u6216\u5931\u8D25\u4E4B\u540E\u63A5\u7740\u53D1",
138170
+ status: "\u770B\u73B0\u5728\u5728\u5E72\u4EC0\u4E48",
138171
+ sessions: "\u5217\u51FA\u8FD9\u4E2A\u804A\u5929\u6240\u5728\u9879\u76EE\u7684\u4F1A\u8BDD",
138172
+ resume: "\u5207\u5230\u67D0\u4E2A\u4F1A\u8BDD\uFF08/sessions \u91CC\u7684\u7F16\u53F7\uFF09",
138173
+ model: "\u770B\u6216\u6362\u6A21\u578B",
138174
+ plan: "\u5F00\u5173\u8BA1\u5212\u6A21\u5F0F",
138175
+ repo: "\u9009\u8FD9\u4E2A\u804A\u5929\u5728\u54EA\u4E2A\u9879\u76EE\u4E0A\u5E72\u6D3B",
138176
+ team: "\u628A\u63A5\u4E0B\u6765\u7684\u8BDD\u53D1\u7ED9\u4E00\u652F\u56E2\u961F",
138177
+ thread: "\u5207\u56DE\u666E\u901A\u4F1A\u8BDD",
138178
+ panel: "\u6253\u5F00\u547D\u4EE4\u9762\u677F",
138179
+ help: "\u5217\u51FA\u5168\u90E8\u547D\u4EE4"
138133
138180
  }
138134
138181
  };
138135
138182
 
@@ -138237,6 +138284,14 @@ var makeModelPlan = (core, deps) => {
138237
138284
  return { currentModelOf, handleModel, handlePlan };
138238
138285
  };
138239
138286
 
138287
+ // src/turnOutcome.ts
138288
+ var outcomeOfSession = (status) => {
138289
+ if (status === "error") return "failed";
138290
+ if (status === "interrupted" || status === "stopped") return "stopped";
138291
+ return "done";
138292
+ };
138293
+ var outcomeOfTeamRun = (state) => state === "settled" ? "done" : state === "failed" ? "failed" : "stopped";
138294
+
138240
138295
  // src/notifications.ts
138241
138296
  var THREAD_PROJECT_CACHE_LIMIT = 256;
138242
138297
  var makeNotifications = (core, deps) => {
@@ -138297,7 +138352,8 @@ ${final.text}`;
138297
138352
  }
138298
138353
  }
138299
138354
  }
138300
- for (const binding of targets) await clearWorking(binding, threadId);
138355
+ const outcome = outcomeOfSession(payload.session?.status);
138356
+ for (const binding of targets) await clearWorking(binding, threadId, outcome);
138301
138357
  }
138302
138358
  });
138303
138359
  host.events.on("thread.failed", async (event) => {
@@ -138317,7 +138373,7 @@ ${final.text}`;
138317
138373
  if (notice !== null && drawingTurn !== null)
138318
138374
  failures.holdForCard(threadId, drawingTurn, notice);
138319
138375
  for (const binding of targets) {
138320
- await clearWorking(binding, threadId);
138376
+ await clearWorking(binding, threadId, "failed");
138321
138377
  if (notice !== null && textTargets.includes(binding)) await deliver(binding, notice);
138322
138378
  }
138323
138379
  });
@@ -138909,16 +138965,16 @@ var makePanelWiring = (core, deps) => {
138909
138965
  }
138910
138966
  });
138911
138967
  const handlePanelClick = (bot, click) => {
138912
- const target = bindingOf2(bot, click.chatId);
138913
- if (!isAllowedSender(target, click.operatorId)) {
138968
+ const target2 = bindingOf2(bot, click.chatId);
138969
+ if (!isAllowedSender(target2, click.operatorId)) {
138914
138970
  host.log.warn("chat ignored a panel click from someone not on the allow list", {
138915
- bot: target.displayName,
138971
+ bot: target2.displayName,
138916
138972
  operator: click.operatorId
138917
138973
  });
138918
138974
  return t("reply.notAllowed");
138919
138975
  }
138920
138976
  return panel.click({
138921
- chatKey: chatKeyOf(target),
138977
+ chatKey: chatKeyOf(target2),
138922
138978
  cardId: click.cardId,
138923
138979
  op: click.op,
138924
138980
  arg: click.arg
@@ -139094,8 +139150,8 @@ var makeTurnCards = (deps) => {
139094
139150
  const finalize = async (slot, threadId, progress, end) => {
139095
139151
  const live = slot.live;
139096
139152
  slot.live = null;
139097
- const target = live?.target ?? deps.resolveTarget(threadId);
139098
- if (target === null) return;
139153
+ const target2 = live?.target ?? deps.resolveTarget(threadId);
139154
+ if (target2 === null) return;
139099
139155
  rememberEnded(threadId, progress.turnId ?? live?.turnId ?? null);
139100
139156
  if (end.status === "error") erroredThreads.add(threadId);
139101
139157
  const title = live?.title ?? await deps.titleOf(threadId);
@@ -139106,14 +139162,14 @@ var makeTurnCards = (deps) => {
139106
139162
  return;
139107
139163
  }
139108
139164
  const card = await makeCardStream({
139109
- open: target.open,
139110
- update: target.update,
139165
+ open: target2.open,
139166
+ update: target2.update,
139111
139167
  schedule: deps.schedule,
139112
- throttleMs: target.throttleMs,
139168
+ throttleMs: target2.throttleMs,
139113
139169
  warn: deps.warn
139114
139170
  }).open(view);
139115
139171
  if (card === null) {
139116
- await deps.fallback(threadId, target.chatKey, view);
139172
+ await deps.fallback(threadId, target2.chatKey, view);
139117
139173
  return;
139118
139174
  }
139119
139175
  };
@@ -139138,14 +139194,14 @@ var makeTurnCards = (deps) => {
139138
139194
  }
139139
139195
  erroredThreads.delete(threadId);
139140
139196
  if (live === null) {
139141
- const target = deps.resolveTarget(threadId);
139142
- if (target === null) return;
139197
+ const target2 = deps.resolveTarget(threadId);
139198
+ if (target2 === null) return;
139143
139199
  const title = await deps.titleOf(threadId);
139144
139200
  const fresh = {
139145
- chatKey: target.chatKey,
139201
+ chatKey: target2.chatKey,
139146
139202
  title,
139147
139203
  card: null,
139148
- target,
139204
+ target: target2,
139149
139205
  turnId: item.turnId,
139150
139206
  lastSeq: item.seq,
139151
139207
  lastProgress: item,
@@ -139158,15 +139214,15 @@ var makeTurnCards = (deps) => {
139158
139214
  status: "working"
139159
139215
  });
139160
139216
  const card = await makeCardStream({
139161
- open: target.open,
139162
- update: target.update,
139217
+ open: target2.open,
139218
+ update: target2.update,
139163
139219
  schedule: deps.schedule,
139164
- throttleMs: target.throttleMs,
139220
+ throttleMs: target2.throttleMs,
139165
139221
  warn: deps.warn
139166
139222
  }).open(view);
139167
139223
  slot.live = { ...fresh, card };
139168
139224
  if (card !== null) {
139169
- deps.onOpened({ cardId: card.cardId, chatKey: target.chatKey, threadId, title });
139225
+ deps.onOpened({ cardId: card.cardId, chatKey: target2.chatKey, threadId, title });
139170
139226
  }
139171
139227
  return;
139172
139228
  }
@@ -139264,14 +139320,15 @@ var makeReplyCards = (core, failures) => {
139264
139320
  const stopped = stopRequested.delete(threadId);
139265
139321
  const thread = await host.projections.getThread(threadId).catch(() => null);
139266
139322
  const session = thread?.session;
139323
+ const outcome = outcomeOfSession(session?.status);
139267
139324
  const errorText2 = failures.forCard(
139268
139325
  threadId,
139269
139326
  turnId,
139270
139327
  session?.lastError,
139271
- session?.status === "error"
139328
+ outcome === "failed"
139272
139329
  );
139273
139330
  if (errorText2 !== null) return { status: "error", errorText: errorText2 };
139274
- if (stopped || session?.status === "interrupted" || session?.status === "stopped") {
139331
+ if (stopped || outcome === "stopped") {
139275
139332
  return { status: "interrupted", errorText: null };
139276
139333
  }
139277
139334
  return { status: "done", errorText: null };
@@ -139359,16 +139416,16 @@ var makeDeliverySender = (core, config2) => {
139359
139416
  if (bot === void 0) {
139360
139417
  throw new DeliverySendError("unknown-bot", `Unknown bot '${input.botId}'.`);
139361
139418
  }
139362
- const target = findDeliveryTarget(readDeliveryTargets(config2), input.botId, input.targetId);
139363
- if (target === void 0) {
139419
+ const target2 = findDeliveryTarget(readDeliveryTargets(config2), input.botId, input.targetId);
139420
+ if (target2 === void 0) {
139364
139421
  throw new DeliverySendError(
139365
139422
  "unknown-target",
139366
139423
  `Unknown target '${input.targetId}' for bot '${input.botId}'.`
139367
139424
  );
139368
139425
  }
139369
- const binding = core.bindingOf(bot, target.platformChatId);
139426
+ const binding = core.bindingOf(bot, target2.platformChatId);
139370
139427
  try {
139371
- await core.adapterFor(bot.platform)?.sendText(binding, input.text, { targetKind: target.kind });
139428
+ await core.adapterFor(bot.platform)?.sendText(binding, input.text, { targetKind: target2.kind });
139372
139429
  } catch (error) {
139373
139430
  throw new DeliverySendError(
139374
139431
  error instanceof ImNotConnectedError ? "bot-not-connected" : "delivery-failed",
@@ -139795,22 +139852,22 @@ var makeSessions = (core) => {
139795
139852
  listedByChat.set(chatKeyOf(binding), listedThreadIds(rows));
139796
139853
  await deliver(binding, formatSessions(rows, Date.now(), t));
139797
139854
  };
139798
- const bindToSession = async (binding, chatKey, target) => {
139855
+ const bindToSession = async (binding, chatKey, target2) => {
139799
139856
  for (const [otherKey, record2] of Object.entries(core.state.chats)) {
139800
- if (otherKey !== chatKey && record2.threadId === target.threadId) bindChat(otherKey, null);
139857
+ if (otherKey !== chatKey && record2.threadId === target2.threadId) bindChat(otherKey, null);
139801
139858
  }
139802
- if (target.origin === "web" && !hasAttached(core.state, chatKey, target.threadId)) {
139859
+ if (target2.origin === "web" && !hasAttached(core.state, chatKey, target2.threadId)) {
139803
139860
  commit("thread-attached", {
139804
139861
  chatKey,
139805
- threadId: target.threadId,
139862
+ threadId: target2.threadId,
139806
139863
  projectId: binding.projectId,
139807
139864
  attachedAt: (/* @__PURE__ */ new Date()).toISOString()
139808
139865
  });
139809
139866
  }
139810
- commit("chat-updated", { chatKey, threadId: target.threadId, target: { kind: "thread" } });
139867
+ commit("chat-updated", { chatKey, threadId: target2.threadId, target: { kind: "thread" } });
139811
139868
  pendingAttachByChat.delete(chatKey);
139812
139869
  listedByChat.delete(chatKey);
139813
- await deliver(binding, t("resume.done", { title: target.title }));
139870
+ await deliver(binding, t("resume.done", { title: target2.title }));
139814
139871
  };
139815
139872
  const resumeSession = async (binding, arg) => {
139816
139873
  const chatKey = chatKeyOf(binding);
@@ -139845,8 +139902,8 @@ var makeSessions = (core) => {
139845
139902
  return;
139846
139903
  }
139847
139904
  }
139848
- const target = rows.find((row) => row.threadId === targetId);
139849
- if (target === void 0) {
139905
+ const target2 = rows.find((row) => row.threadId === targetId);
139906
+ if (target2 === void 0) {
139850
139907
  if (confirming) pendingAttachByChat.delete(chatKey);
139851
139908
  await deliver(binding, t("resume.gone"));
139852
139909
  return;
@@ -139855,21 +139912,21 @@ var makeSessions = (core) => {
139855
139912
  await deliver(binding, t("resume.busy"));
139856
139913
  return;
139857
139914
  }
139858
- if (target.current) {
139915
+ if (target2.current) {
139859
139916
  if (confirming) pendingAttachByChat.delete(chatKey);
139860
139917
  await deliver(binding, t("resume.already"));
139861
139918
  return;
139862
139919
  }
139863
- if (target.running && target.elsewhere) {
139920
+ if (target2.running && target2.elsewhere) {
139864
139921
  await deliver(binding, t("resume.runningElsewhere"));
139865
139922
  return;
139866
139923
  }
139867
- if (target.origin === "web" && !confirming && pending !== target.threadId && !hasAttached(core.state, chatKey, target.threadId)) {
139868
- pendingAttachByChat.set(chatKey, target.threadId);
139869
- await deliver(binding, t("resume.confirmWeb", { title: target.title }));
139924
+ if (target2.origin === "web" && !confirming && pending !== target2.threadId && !hasAttached(core.state, chatKey, target2.threadId)) {
139925
+ pendingAttachByChat.set(chatKey, target2.threadId);
139926
+ await deliver(binding, t("resume.confirmWeb", { title: target2.title }));
139870
139927
  return;
139871
139928
  }
139872
- await bindToSession(binding, chatKey, target);
139929
+ await bindToSession(binding, chatKey, target2);
139873
139930
  };
139874
139931
  return { listedByChat, sessionRowsFor, showSessions, resumeSession };
139875
139932
  };
@@ -139915,7 +139972,7 @@ var makeTeamRuns = (core, deps) => {
139915
139972
  const binding = chatByRun.get(runId);
139916
139973
  if (binding === void 0) return;
139917
139974
  chatByRun.delete(runId);
139918
- await clearWorking(binding, chatKeyOf(binding));
139975
+ await clearWorking(binding, chatKeyOf(binding), outcomeOfTeamRun(event.data.state));
139919
139976
  await deliver(binding, event.summary);
139920
139977
  });
139921
139978
  return { fetchTeams, startTeamRun };
@@ -139924,7 +139981,26 @@ var makeTeamRuns = (core, deps) => {
139924
139981
  // src/telegramApi.ts
139925
139982
  var API_BASE = "https://api.telegram.org";
139926
139983
  var POLL_TIMEOUT_SECONDS = 45;
139984
+ var CALL_TIMEOUT_MS = 15e3;
139985
+ var POLL_CALL_TIMEOUT_MS = (POLL_TIMEOUT_SECONDS + 10) * 1e3;
139986
+ var UPLOAD_TIMEOUT_MS = 12e4;
139987
+ var DOWNLOAD_TIMEOUT_MS = 6e4;
139988
+ var HINT_TIMEOUT_MS = 3e3;
139989
+ var isTelegramToken = (token) => /^\d{5,20}:[A-Za-z0-9_-]{20,}$/u.test(token);
139927
139990
  var TELEGRAM_TEXT_MAX_CHARS = 4e3;
139991
+ var chatIdOf = (message) => {
139992
+ const thread = message.message_thread_id;
139993
+ return message.is_topic_message === true && thread !== void 0 && thread > 0 ? `${String(message.chat.id)}:${String(thread)}` : String(message.chat.id);
139994
+ };
139995
+ var splitChatId = (chatId) => {
139996
+ const match = /^(.+):([1-9]\d*)$/u.exec(chatId);
139997
+ return match === null ? { chat: chatId, thread: null } : { chat: match[1] ?? chatId, thread: Number(match[2]) };
139998
+ };
139999
+ var target = (chatId) => {
140000
+ const { chat, thread } = splitChatId(chatId);
140001
+ return { chat_id: chat, ...thread === null ? {} : { message_thread_id: thread } };
140002
+ };
140003
+ var chatOnly = (chatId) => ({ chat_id: splitChatId(chatId).chat });
139928
140004
  var TelegramApiError = class extends Error {
139929
140005
  code;
139930
140006
  /** 限流(429)时平台给的等待秒数;别的错误没有。 */
@@ -140019,12 +140095,27 @@ var passesGroupGate2 = (input) => {
140019
140095
  return input.groupMention === "ambient" && names.length === 0;
140020
140096
  };
140021
140097
  var makeTelegramApi = (input) => {
140022
- const call = async (method, body) => {
140023
- const response = await input.http(`${API_BASE}/bot${input.token}/${method}`, {
140024
- method: "POST",
140025
- headers: { "content-type": "application/json" },
140026
- body: JSON.stringify(body)
140027
- });
140098
+ const send = async (method, url, init, timeoutMs) => {
140099
+ try {
140100
+ return await input.http(url, { ...init, signal: AbortSignal.timeout(timeoutMs) });
140101
+ } catch (error) {
140102
+ if (error instanceof Error && error.name === "TimeoutError") {
140103
+ throw new TelegramApiError(method, void 0, `timed out after ${String(timeoutMs)} ms`);
140104
+ }
140105
+ throw error;
140106
+ }
140107
+ };
140108
+ const call = async (method, body, timeoutMs = CALL_TIMEOUT_MS) => {
140109
+ const response = await send(
140110
+ method,
140111
+ `${API_BASE}/bot${input.token}/${method}`,
140112
+ {
140113
+ method: "POST",
140114
+ headers: { "content-type": "application/json" },
140115
+ body: JSON.stringify(body)
140116
+ },
140117
+ timeoutMs
140118
+ );
140028
140119
  const envelope = await response.json();
140029
140120
  if (envelope.ok !== true) {
140030
140121
  throw new TelegramApiError(
@@ -140038,12 +140129,18 @@ var makeTelegramApi = (input) => {
140038
140129
  };
140039
140130
  const upload = async (method, field, chatId, file) => {
140040
140131
  const form = new FormData();
140041
- form.set("chat_id", chatId);
140132
+ const where = target(chatId);
140133
+ form.set("chat_id", where.chat_id);
140134
+ if (where.message_thread_id !== void 0) {
140135
+ form.set("message_thread_id", String(where.message_thread_id));
140136
+ }
140042
140137
  form.set(field, new Blob([new Uint8Array(file.bytes)], { type: file.mimeType }), file.name);
140043
- const response = await input.http(`${API_BASE}/bot${input.token}/${method}`, {
140044
- method: "POST",
140045
- body: form
140046
- });
140138
+ const response = await send(
140139
+ method,
140140
+ `${API_BASE}/bot${input.token}/${method}`,
140141
+ { method: "POST", body: form },
140142
+ UPLOAD_TIMEOUT_MS
140143
+ );
140047
140144
  const envelope = await response.json();
140048
140145
  if (envelope.ok !== true) {
140049
140146
  throw new TelegramApiError(
@@ -140061,7 +140158,7 @@ var makeTelegramApi = (input) => {
140061
140158
  });
140062
140159
  const sendSingle = async (method, chatId, body, rows) => {
140063
140160
  const sent = await call(method, {
140064
- chat_id: chatId,
140161
+ ...target(chatId),
140065
140162
  ...body,
140066
140163
  ...rows === void 0 ? {} : { reply_markup: keyboard(rows) }
140067
140164
  });
@@ -140070,7 +140167,7 @@ var makeTelegramApi = (input) => {
140070
140167
  const editSingle = async (chatId, messageId, body, rows) => {
140071
140168
  try {
140072
140169
  await call("editMessageText", {
140073
- chat_id: chatId,
140170
+ ...chatOnly(chatId),
140074
140171
  message_id: Number(messageId),
140075
140172
  ...body,
140076
140173
  reply_markup: keyboard(rows)
@@ -140081,23 +140178,49 @@ var makeTelegramApi = (input) => {
140081
140178
  };
140082
140179
  return {
140083
140180
  /** 机器人自己是谁;群里的命令靠它的 `username` 认出是不是发给自己的。 */
140084
- getMe: () => call("getMe", {}),
140181
+ getMe: () => call(
140182
+ "getMe",
140183
+ {}
140184
+ ),
140185
+ /**
140186
+ * 这个机器人是不是还挂着别处设的 webhook。挂着的话 `getUpdates` 一直回 409,表现就是
140187
+ * 「没反应」。只查不删:那多半是另一个服务正在用这个机器人。
140188
+ */
140189
+ getWebhookInfo: () => call("getWebhookInfo", {}),
140190
+ /** 整表替换输入 `/` 时弹出的命令菜单(缺省范围、缺省语言)。 */
140191
+ setMyCommands: (commands) => call("setMyCommands", { commands }),
140192
+ /** 「正在输入」:客户端显示几秒,或机器人发出下一条消息时消失。 */
140193
+ sendTyping: (chatId) => call("sendChatAction", { ...target(chatId), action: "typing" }, HINT_TIMEOUT_MS),
140194
+ /** 给一条消息贴一个表情(整体替换);`emoji` 为 null 就撤掉。 */
140195
+ setReaction: (chatId, messageId, emoji) => call(
140196
+ "setMessageReaction",
140197
+ {
140198
+ ...chatOnly(chatId),
140199
+ message_id: Number(messageId),
140200
+ reaction: emoji === null ? [] : [{ type: "emoji", emoji }]
140201
+ },
140202
+ HINT_TIMEOUT_MS
140203
+ ),
140085
140204
  /** 群里一共多少成员(含机器人自己)。单人群放宽靠它:两个成员就是发命令的人加机器人。 */
140086
- getChatMemberCount: (chatId) => call("getChatMemberCount", { chat_id: chatId }),
140205
+ getChatMemberCount: (chatId) => call("getChatMemberCount", chatOnly(chatId)),
140087
140206
  /**
140088
140207
  * 拉一批更新。挂在服务端最多 `POLL_TIMEOUT_SECONDS` 秒。
140089
140208
  *
140090
140209
  * `allowed_updates` 必须列全:它是服务端白名单,不写 `callback_query` 的话按钮点击
140091
140210
  * 根本不会投递过来,而且不会有任何报错。
140092
140211
  */
140093
- getUpdates: (offset) => call("getUpdates", {
140094
- offset,
140095
- timeout: POLL_TIMEOUT_SECONDS,
140096
- allowed_updates: ["message", "callback_query"]
140097
- }),
140212
+ getUpdates: (offset) => call(
140213
+ "getUpdates",
140214
+ {
140215
+ offset,
140216
+ timeout: POLL_TIMEOUT_SECONDS,
140217
+ allowed_updates: ["message", "callback_query"]
140218
+ },
140219
+ POLL_CALL_TIMEOUT_MS
140220
+ ),
140098
140221
  sendMessage: async (chatId, text3) => {
140099
140222
  for (const chunk of splitForTelegram(text3)) {
140100
- await call("sendMessage", { chat_id: chatId, text: chunk });
140223
+ await call("sendMessage", { ...target(chatId), text: chunk });
140101
140224
  }
140102
140225
  },
140103
140226
  /**
@@ -140147,7 +140270,12 @@ var makeTelegramApi = (input) => {
140147
140270
  });
140148
140271
  const path = file.file_path;
140149
140272
  if (path === void 0) throw new TelegramApiError("getFile", void 0, "no file_path");
140150
- const response = await input.http(`${API_BASE}/file/bot${input.token}/${path}`);
140273
+ const response = await send(
140274
+ "file",
140275
+ `${API_BASE}/file/bot${input.token}/${path}`,
140276
+ {},
140277
+ DOWNLOAD_TIMEOUT_MS
140278
+ );
140151
140279
  if (!response.ok) {
140152
140280
  throw new TelegramApiError("file", response.status, "download failed");
140153
140281
  }
@@ -140156,6 +140284,29 @@ var makeTelegramApi = (input) => {
140156
140284
  };
140157
140285
  };
140158
140286
 
140287
+ // src/telegramCommandMenu.ts
140288
+ var DESCRIPTIONS = {
140289
+ new: "menu.new",
140290
+ stop: "menu.stop",
140291
+ continue: "menu.continue",
140292
+ repo: "menu.repo",
140293
+ sessions: "menu.sessions",
140294
+ team: "menu.team",
140295
+ thread: "menu.thread",
140296
+ model: "menu.model",
140297
+ plan: "menu.plan",
140298
+ status: "menu.status",
140299
+ help: "menu.help",
140300
+ resume: "menu.resume",
140301
+ panel: "menu.panel"
140302
+ };
140303
+ var TELEGRAM_MENU = [
140304
+ ...PANEL_COMMANDS.map((spec) => ({ command: spec.line.slice(1), key: DESCRIPTIONS[spec.id] })),
140305
+ { command: "resume", key: DESCRIPTIONS.resume },
140306
+ { command: "panel", key: DESCRIPTIONS.panel }
140307
+ ];
140308
+ var telegramCommandMenu = (t) => TELEGRAM_MENU.map((item) => ({ command: item.command, description: t(item.key) }));
140309
+
140159
140310
  // src/telegramChoice.ts
140160
140311
  var renderChoiceCard = (card) => ({
140161
140312
  text: [card.title, card.heading ?? "", card.body, card.note ?? ""].filter((part) => part !== "").join("\n\n"),
@@ -140294,8 +140445,18 @@ var BACKOFF_MAX_MS = 6e4;
140294
140445
  var TELEGRAM_CARD_THROTTLE_MS = 1200;
140295
140446
  var FLOOD_WAIT_MAX_SECONDS = 30;
140296
140447
  var REMEMBERED_CARD_LIMIT = 200;
140297
- var tokenOf = (binding) => binding.values["telegramToken"] ?? "";
140448
+ var tokenOf = (binding) => (binding.values["telegramToken"] ?? "").trim();
140449
+ var REACTION_WORKING = "\u{1F440}";
140450
+ var REACTION_DONE = "\u{1F44D}";
140451
+ var REACTION_FAILED = "\u{1F44E}";
140298
140452
  var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
140453
+ var webhookHost = (url) => {
140454
+ try {
140455
+ return new URL(url).host;
140456
+ } catch {
140457
+ return "(unreadable)";
140458
+ }
140459
+ };
140299
140460
  var makeTelegramAdapter = (deps) => {
140300
140461
  const apis = /* @__PURE__ */ new Map();
140301
140462
  const sleep3 = deps.sleep ?? defaultSleep;
@@ -140340,14 +140501,14 @@ var makeTelegramAdapter = (deps) => {
140340
140501
  const panelKeyboards = remembering();
140341
140502
  const panelClick = (rowId, callback, operatorId, handlers) => {
140342
140503
  const messageId = callback.message?.message_id;
140343
- const chatId = callback.message?.chat.id;
140504
+ const chatId = callback.message === void 0 ? void 0 : chatIdOf(callback.message);
140344
140505
  if (messageId === void 0 || chatId === void 0) return t("panel.expired");
140345
- const keyboard = panelKeyboards.get(`${rowId}:${String(chatId)}:${String(messageId)}`);
140506
+ const keyboard = panelKeyboards.get(`${rowId}:${chatId}:${String(messageId)}`);
140346
140507
  const parsed = parsePanelData(callback.data ?? "");
140347
140508
  const action = keyboard === void 0 || parsed === null || parsed.version !== keyboard.version ? void 0 : keyboard.actions[parsed.index];
140348
140509
  if (action === void 0) return t("panel.expired");
140349
140510
  return handlers.onPanelClick?.({
140350
- chatId: String(chatId),
140511
+ chatId,
140351
140512
  cardId: String(messageId),
140352
140513
  operatorId,
140353
140514
  op: action.op,
@@ -140393,6 +140554,7 @@ var makeTelegramAdapter = (deps) => {
140393
140554
  let offset = 0;
140394
140555
  let backoff = BACKOFF_START_MS;
140395
140556
  let botUsername;
140557
+ let menuSent = false;
140396
140558
  const isSoloGroup = makeSoloGroupCheck(async (chatId) => {
140397
140559
  const count = await (await apiFor(binding)).getChatMemberCount(chatId);
140398
140560
  return Number.isFinite(count) ? count <= 2 : void 0;
@@ -140403,6 +140565,15 @@ var makeTelegramAdapter = (deps) => {
140403
140565
  try {
140404
140566
  const api = await apiFor(binding);
140405
140567
  botUsername ??= (await api.getMe()).username ?? null;
140568
+ if (!menuSent) {
140569
+ menuSent = true;
140570
+ void api.setMyCommands(telegramCommandMenu(t)).catch((error) => {
140571
+ deps.log.warn("telegram could not set the command menu", {
140572
+ bot: binding.displayName,
140573
+ error: describeError(error)
140574
+ });
140575
+ });
140576
+ }
140406
140577
  const updates = await api.getUpdates(offset);
140407
140578
  if (!running) return;
140408
140579
  backoff = BACKOFF_START_MS;
@@ -140438,7 +140609,7 @@ var makeTelegramAdapter = (deps) => {
140438
140609
  if (unsupported === null) continue;
140439
140610
  handlers.onMessage({
140440
140611
  messageId: String(message.message_id),
140441
- chatId: String(message.chat.id),
140612
+ chatId: chatIdOf(message),
140442
140613
  senderId: message.from === void 0 ? null : String(message.from.id),
140443
140614
  text: "",
140444
140615
  chatKind: message.chat.type === "private" ? "private" : "group",
@@ -140449,7 +140620,7 @@ var makeTelegramAdapter = (deps) => {
140449
140620
  }
140450
140621
  handlers.onMessage({
140451
140622
  messageId: String(message.message_id),
140452
- chatId: String(message.chat.id),
140623
+ chatId: chatIdOf(message),
140453
140624
  senderId: message.from === void 0 ? null : String(message.from.id),
140454
140625
  text: text3,
140455
140626
  chatKind: message.chat.type === "private" ? "private" : "group",
@@ -140487,16 +140658,68 @@ var makeTelegramAdapter = (deps) => {
140487
140658
  await api.sendMessage(binding.chatId, text3);
140488
140659
  },
140489
140660
  checkConnection: async (bot) => {
140490
- if (tokenOf(bot) === "") {
140661
+ const token = tokenOf(bot);
140662
+ if (token === "") {
140491
140663
  return { stage: "credentials", ok: false, detail: "missing bot token in saved config" };
140492
140664
  }
140665
+ if (!isTelegramToken(token)) {
140666
+ return {
140667
+ stage: "token-format",
140668
+ ok: false,
140669
+ detail: "saved token is not in the BotFather format",
140670
+ hint: "badToken"
140671
+ };
140672
+ }
140673
+ const api = await apiFor(bot);
140674
+ let username;
140493
140675
  try {
140494
- const me = await (await apiFor(bot)).getMe();
140495
- const username = me.username !== void 0 && me.username !== "" ? `@${me.username}` : "(no username)";
140496
- return { stage: "getMe", ok: true, detail: `username=${username}` };
140676
+ const me = await api.getMe();
140677
+ if (me.is_bot !== true) {
140678
+ return { stage: "getMe", ok: false, detail: "token is not a bot's", hint: "notBot" };
140679
+ }
140680
+ username = me.username !== void 0 && me.username !== "" ? `@${me.username}` : "(no username)";
140497
140681
  } catch (error) {
140498
- return { stage: "getMe", ok: false, detail: describeError(error) };
140682
+ const rejected = error instanceof TelegramApiError && (error.code === 401 || error.code === 404);
140683
+ return {
140684
+ stage: "getMe",
140685
+ ok: false,
140686
+ detail: describeError(error),
140687
+ ...rejected ? { hint: "unauthorized" } : {}
140688
+ };
140689
+ }
140690
+ try {
140691
+ const webhook = (await api.getWebhookInfo()).url ?? "";
140692
+ if (webhook !== "") {
140693
+ return {
140694
+ stage: "getWebhookInfo",
140695
+ ok: false,
140696
+ detail: `webhook is set (host ${webhookHost(webhook)})`,
140697
+ hint: "webhookActive"
140698
+ };
140699
+ }
140700
+ } catch (error) {
140701
+ return { stage: "getWebhookInfo", ok: false, detail: describeError(error) };
140499
140702
  }
140703
+ return { stage: "getMe", ok: true, detail: `username=${username} webhook=none` };
140704
+ },
140705
+ sendTyping: async (binding) => {
140706
+ await (await apiFor(binding)).sendTyping(binding.chatId);
140707
+ },
140708
+ acknowledge: async (binding, messageId) => {
140709
+ try {
140710
+ await (await apiFor(binding)).setReaction(binding.chatId, messageId, REACTION_WORKING);
140711
+ return REACTION_WORKING;
140712
+ } catch (error) {
140713
+ if (error instanceof TelegramApiError && error.code === 400) {
140714
+ deps.log.info("telegram could not react to the message", { reason: error.message });
140715
+ return null;
140716
+ }
140717
+ throw error;
140718
+ }
140719
+ },
140720
+ clearAcknowledge: async (binding, messageId, _ackId, outcome) => {
140721
+ const emoji = outcome === "done" ? REACTION_DONE : outcome === "failed" ? REACTION_FAILED : null;
140722
+ await (await apiFor(binding)).setReaction(binding.chatId, messageId, emoji);
140500
140723
  },
140501
140724
  sendImage: async (binding, image2) => {
140502
140725
  const api = await apiFor(binding);
@@ -140842,7 +141065,7 @@ var botOf = (config2, adapters, rowId) => {
140842
141065
  const adapterFor = (platform) => adapters.find((adapter) => adapter.platform === platform);
140843
141066
  return readBots(config2, adapterFor).find((bot) => bot.rowId === rowId);
140844
141067
  };
140845
- var reportOf = (bot, stage, ok, detail) => ({
141068
+ var reportOf = (bot, stage, ok, detail, hint) => ({
140846
141069
  ref: diagnosticRef("conn"),
140847
141070
  platform: bot.platform,
140848
141071
  botName: bot.displayName,
@@ -140850,7 +141073,8 @@ var reportOf = (bot, stage, ok, detail) => ({
140850
141073
  stage,
140851
141074
  ok,
140852
141075
  detail,
140853
- at: (/* @__PURE__ */ new Date()).toISOString()
141076
+ at: (/* @__PURE__ */ new Date()).toISOString(),
141077
+ ...hint === void 0 ? {} : { hint }
140854
141078
  });
140855
141079
  var probe = async (adapters, bot) => {
140856
141080
  const adapter = adapters.find((candidate) => candidate.platform === bot.platform);
@@ -140867,7 +141091,8 @@ var probe = async (adapters, bot) => {
140867
141091
  bot,
140868
141092
  result.stage,
140869
141093
  result.ok,
140870
- result.ok ? result.detail : redactor.redact(result.detail)
141094
+ result.ok ? result.detail : redactor.redact(result.detail),
141095
+ result.hint
140871
141096
  );
140872
141097
  } catch (error) {
140873
141098
  return reportOf(bot, "check", false, redactor.redact(describeError(error)));
@@ -140886,7 +141111,7 @@ var emitReport = (emit, report, action) => {
140886
141111
  }
140887
141112
  emit({
140888
141113
  kind: "failed",
140889
- reasonKey: `${action.keyPrefix}.failed`,
141114
+ reasonKey: report.hint !== void 0 && action.keyPrefix === "rowAction.checkConnection" ? `rowAction.checkConnection.hint.${report.hint}` : `${action.keyPrefix}.failed`,
140890
141115
  params: { ref: report.ref },
140891
141116
  detail
140892
141117
  });