@ycodium-ai/plugin-im 0.2.2698 → 0.2.2706

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
@@ -14549,20 +14549,20 @@ var require_axios = __commonJS({
14549
14549
  if (parts[0] !== "127") return false;
14550
14550
  return parts.every((p) => /^\d+$/.test(p) && Number(p) >= 0 && Number(p) <= 255);
14551
14551
  };
14552
- var parseIPv4Octet = (text2) => {
14553
- if (/^0[xX][0-9a-fA-F]+$/.test(text2)) {
14554
- const n = parseInt(text2.slice(2), 16);
14552
+ var parseIPv4Octet = (text3) => {
14553
+ if (/^0[xX][0-9a-fA-F]+$/.test(text3)) {
14554
+ const n = parseInt(text3.slice(2), 16);
14555
14555
  return Number.isFinite(n) ? n : null;
14556
14556
  }
14557
- if (text2.length > 1 && /^0[0-7]+$/.test(text2)) {
14558
- const n = parseInt(text2, 8);
14557
+ if (text3.length > 1 && /^0[0-7]+$/.test(text3)) {
14558
+ const n = parseInt(text3, 8);
14559
14559
  return Number.isFinite(n) ? n : null;
14560
14560
  }
14561
- if (text2.length > 1 && /^0[0-9]+$/.test(text2)) {
14561
+ if (text3.length > 1 && /^0[0-9]+$/.test(text3)) {
14562
14562
  return null;
14563
14563
  }
14564
- if (/^[0-9]+$/.test(text2)) {
14565
- const n = parseInt(text2, 10);
14564
+ if (/^[0-9]+$/.test(text3)) {
14565
+ const n = parseInt(text3, 10);
14566
14566
  return Number.isFinite(n) ? n : null;
14567
14567
  }
14568
14568
  return null;
@@ -122993,10 +122993,10 @@ var require_lib2 = __commonJS({
122993
122993
  }
122994
122994
  return prev + next;
122995
122995
  }
122996
- function splitWithCodeFences(text2, limit) {
122997
- if (text2.length <= limit)
122998
- return [text2];
122999
- const lines = text2.split("\n");
122996
+ function splitWithCodeFences(text3, limit) {
122997
+ if (text3.length <= limit)
122998
+ return [text3];
122999
+ const lines = text3.split("\n");
123000
123000
  const out = [];
123001
123001
  let buf = [];
123002
123002
  let bufLen = 0;
@@ -123041,10 +123041,10 @@ var require_lib2 = __commonJS({
123041
123041
  var ERROR_FOOTER = "\n\n\u2014 _(Generation interrupted)_";
123042
123042
  var DEFAULT_MAX_ELEMENT_CHARS = 3e4;
123043
123043
  var ELEMENT_ID = "stream_md";
123044
- function truncateSummary(text2, max = SUMMARY_MAX_CHARS) {
123045
- if (!text2)
123044
+ function truncateSummary(text3, max = SUMMARY_MAX_CHARS) {
123045
+ if (!text3)
123046
123046
  return "";
123047
- const cleaned = text2.replace(/\s+/g, " ").trim();
123047
+ const cleaned = text3.replace(/\s+/g, " ").trim();
123048
123048
  return cleaned.length <= max ? cleaned : cleaned.slice(0, max - 1) + "\u2026";
123049
123049
  }
123050
123050
  function buildStreamingCard(initialText) {
@@ -123755,21 +123755,21 @@ var require_lib2 = __commonJS({
123755
123755
  }
123756
123756
  return parts.length > 0 ? parts.join(" ") + " " : "";
123757
123757
  }
123758
- function optimizeMarkdownStyle(text2, cardVersion = 1) {
123758
+ function optimizeMarkdownStyle(text3, cardVersion = 1) {
123759
123759
  try {
123760
- return _optimize(text2, cardVersion);
123760
+ return _optimize(text3, cardVersion);
123761
123761
  } catch (_a) {
123762
- return text2;
123762
+ return text3;
123763
123763
  }
123764
123764
  }
123765
- function _optimize(text2, cardVersion) {
123765
+ function _optimize(text3, cardVersion) {
123766
123766
  const MARK = "___CB_";
123767
123767
  const codeBlocks = [];
123768
- let r = text2.replace(/(^|\n)(`{3,})([^\n]*)\n[\s\S]*?\n\2(?=\n|$)/g, (m, prefix = "") => {
123768
+ let r = text3.replace(/(^|\n)(`{3,})([^\n]*)\n[\s\S]*?\n\2(?=\n|$)/g, (m, prefix = "") => {
123769
123769
  const block2 = m.slice(String(prefix).length);
123770
123770
  return `${prefix}${MARK}${codeBlocks.push(block2) - 1}___`;
123771
123771
  });
123772
- const hasH1toH3 = /^#{1,3} /m.test(text2);
123772
+ const hasH1toH3 = /^#{1,3} /m.test(text3);
123773
123773
  if (hasH1toH3) {
123774
123774
  r = r.replace(/^#{2,6} (.+)$/gm, "##### $1");
123775
123775
  r = r.replace(/^# (.+)$/gm, "#### $1");
@@ -123805,11 +123805,11 @@ ${block2}
123805
123805
  function markdownToPost(md2, opts) {
123806
123806
  var _a, _b;
123807
123807
  const prefix = composeMentionsTextPrefix((_a = opts === null || opts === void 0 ? void 0 : opts.mentions) !== null && _a !== void 0 ? _a : []);
123808
- const text2 = optimizeMarkdownStyle(prefix + md2, 1);
123808
+ const text3 = optimizeMarkdownStyle(prefix + md2, 1);
123809
123809
  return {
123810
123810
  zh_cn: {
123811
123811
  title: (_b = opts === null || opts === void 0 ? void 0 : opts.title) !== null && _b !== void 0 ? _b : "",
123812
- content: [[{ tag: "md", text: text2 }]]
123812
+ content: [[{ tag: "md", text: text3 }]]
123813
123813
  }
123814
123814
  };
123815
123815
  }
@@ -124002,11 +124002,11 @@ ${block2}
124002
124002
  return this.makeResult(ids);
124003
124003
  });
124004
124004
  }
124005
- sendText(to, idType, text2, opts) {
124005
+ sendText(to, idType, text3, opts) {
124006
124006
  var _a;
124007
124007
  return __awaiter(this, void 0, void 0, function* () {
124008
124008
  const prefix = composeMentionsTextPrefix((_a = opts.mentions) !== null && _a !== void 0 ? _a : []);
124009
- const body = prefix + text2;
124009
+ const body = prefix + text3;
124010
124010
  const chunks = splitPlain(body, this.chunkLimit);
124011
124011
  const ids = [];
124012
124012
  for (let i = 0; i < chunks.length; i++) {
@@ -124328,12 +124328,12 @@ ${block2}
124328
124328
  };
124329
124329
  }
124330
124330
  };
124331
- function splitPlain(text2, limit) {
124332
- if (text2.length <= limit)
124333
- return [text2];
124331
+ function splitPlain(text3, limit) {
124332
+ if (text3.length <= limit)
124333
+ return [text3];
124334
124334
  const out = [];
124335
- for (let i = 0; i < text2.length; i += limit) {
124336
- out.push(text2.slice(i, i + limit));
124335
+ for (let i = 0; i < text3.length; i += limit) {
124336
+ out.push(text3.slice(i, i + limit));
124337
124337
  }
124338
124338
  return out;
124339
124339
  }
@@ -124854,10 +124854,10 @@ ${block2}
124854
124854
  return void 0;
124855
124855
  }
124856
124856
  }
124857
- function applyStyle(text2, style) {
124857
+ function applyStyle(text3, style) {
124858
124858
  if (!style || style.length === 0)
124859
- return text2;
124860
- let out = text2;
124859
+ return text3;
124860
+ let out = text3;
124861
124861
  if (style.includes("bold"))
124862
124862
  out = `**${out}**`;
124863
124863
  if (style.includes("italic"))
@@ -124921,8 +124921,8 @@ ${block2}
124921
124921
  const s = String(d.getUTCSeconds()).padStart(2, "0");
124922
124922
  return `${y}-${mo}-${day}T${h}:${mi}:${s}+08:00`;
124923
124923
  }
124924
- function indentLines(text2, indent) {
124925
- return text2.split("\n").map((line) => `${indent}${line}`).join("\n");
124924
+ function indentLines(text3, indent) {
124925
+ return text3.split("\n").map((line) => `${indent}${line}`).join("\n");
124926
124926
  }
124927
124927
  function escapeAttr(s) {
124928
124928
  return s.replace(/"/g, "&quot;");
@@ -125044,9 +125044,9 @@ ${formatCalendarInner(raw)}
125044
125044
  if (obj.text)
125045
125045
  visit(obj.text, out);
125046
125046
  if (typeof tag === "string" && tag === "button") {
125047
- const text2 = obj.text;
125048
- if (text2)
125049
- visit(text2, out);
125047
+ const text3 = obj.text;
125048
+ if (text3)
125049
+ visit(text3, out);
125050
125050
  }
125051
125051
  if (obj.label)
125052
125052
  visit(obj.label, out);
@@ -125800,13 +125800,13 @@ ${lines.join("\n")}
125800
125800
  * use this on a card would hit the same API and fail with a clearer
125801
125801
  * Feishu-side error.
125802
125802
  */
125803
- editMessage(messageId, text2) {
125803
+ editMessage(messageId, text3) {
125804
125804
  return __awaiter(this, void 0, void 0, function* () {
125805
125805
  yield this.rawClient.im.v1.message.update({
125806
125806
  path: { message_id: messageId },
125807
125807
  data: {
125808
125808
  msg_type: "text",
125809
- content: JSON.stringify({ text: text2 })
125809
+ content: JSON.stringify({ text: text3 })
125810
125810
  }
125811
125811
  });
125812
125812
  });
@@ -126775,11 +126775,11 @@ var makeImCore = (input) => {
126775
126775
  }
126776
126776
  }
126777
126777
  };
126778
- const deliver = async (binding, text2, attachments = []) => {
126778
+ const deliver = async (binding, text3, attachments = []) => {
126779
126779
  await postImages(binding, attachments);
126780
- if (text2.trim() === "") return;
126780
+ if (text3.trim() === "") return;
126781
126781
  try {
126782
- await adapterFor(binding.platform)?.sendText(binding, text2);
126782
+ await adapterFor(binding.platform)?.sendText(binding, text3);
126783
126783
  } catch (error) {
126784
126784
  host.log.warn("chat could not deliver", { error: describeError(error) });
126785
126785
  }
@@ -127111,46 +127111,46 @@ var makeChatSetup = (core, deps) => {
127111
127111
  };
127112
127112
 
127113
127113
  // src/chatCommand.ts
127114
- var teamArgument = (text2, chinese) => {
127115
- const match = text2.match(/^\/team(?:\s+([\s\S]*))?$/i);
127114
+ var teamArgument = (text3, chinese) => {
127115
+ const match = text3.match(/^\/team(?:\s+([\s\S]*))?$/i);
127116
127116
  if (match) return (match[1] ?? "").trim();
127117
127117
  if (!chinese) return void 0;
127118
- const alias = text2.match(/^换团队(?:\s+([\s\S]*))?$/);
127118
+ const alias = text3.match(/^换团队(?:\s+([\s\S]*))?$/);
127119
127119
  return alias ? (alias[1] ?? "").trim() : void 0;
127120
127120
  };
127121
- var resumeArgument = (text2, chinese) => {
127122
- const match = text2.match(/^\/resume(?:\s+([\s\S]*))?$/i);
127121
+ var resumeArgument = (text3, chinese) => {
127122
+ const match = text3.match(/^\/resume(?:\s+([\s\S]*))?$/i);
127123
127123
  if (match) return (match[1] ?? "").trim();
127124
127124
  if (!chinese) return void 0;
127125
- const alias = text2.match(/^切换会话(?:\s+([\s\S]*))?$/);
127125
+ const alias = text3.match(/^切换会话(?:\s+([\s\S]*))?$/);
127126
127126
  return alias ? (alias[1] ?? "").trim() : void 0;
127127
127127
  };
127128
- var modelArgument = (text2, chinese) => {
127129
- const match = text2.match(/^\/model(?:\s+([\s\S]*))?$/i);
127128
+ var modelArgument = (text3, chinese) => {
127129
+ const match = text3.match(/^\/model(?:\s+([\s\S]*))?$/i);
127130
127130
  if (match) return (match[1] ?? "").trim();
127131
127131
  if (!chinese) return void 0;
127132
- const alias = text2.match(/^换模型(?:\s+([\s\S]*))?$/);
127132
+ const alias = text3.match(/^换模型(?:\s+([\s\S]*))?$/);
127133
127133
  return alias ? (alias[1] ?? "").trim() : void 0;
127134
127134
  };
127135
- var planArgument = (text2, chinese) => {
127136
- const match = text2.match(/^\/plan(?:\s+([\s\S]*))?$/i);
127135
+ var planArgument = (text3, chinese) => {
127136
+ const match = text3.match(/^\/plan(?:\s+([\s\S]*))?$/i);
127137
127137
  if (match) return (match[1] ?? "").trim().toLowerCase();
127138
127138
  if (!chinese) return void 0;
127139
- const alias = text2.match(/^计划模式(?:\s+([\s\S]*))?$/);
127139
+ const alias = text3.match(/^计划模式(?:\s+([\s\S]*))?$/);
127140
127140
  return alias ? (alias[1] ?? "").trim().toLowerCase() : void 0;
127141
127141
  };
127142
- var repoArgument = (text2, chinese) => {
127143
- const match = text2.match(/^\/repo(?:\s+([\s\S]*))?$/i);
127142
+ var repoArgument = (text3, chinese) => {
127143
+ const match = text3.match(/^\/repo(?:\s+([\s\S]*))?$/i);
127144
127144
  if (match) return (match[1] ?? "").trim();
127145
127145
  if (!chinese) return void 0;
127146
- const alias = text2.match(/^换项目(?:\s+([\s\S]*))?$/);
127146
+ const alias = text3.match(/^换项目(?:\s+([\s\S]*))?$/);
127147
127147
  return alias ? (alias[1] ?? "").trim() : void 0;
127148
127148
  };
127149
- var groupArgument = (text2, chinese) => {
127150
- const match = text2.match(/^\/group(?:\s+([\s\S]*))?$/i);
127149
+ var groupArgument = (text3, chinese) => {
127150
+ const match = text3.match(/^\/group(?:\s+([\s\S]*))?$/i);
127151
127151
  if (match) return (match[1] ?? "").trim();
127152
127152
  if (!chinese) return void 0;
127153
- const alias = text2.match(/^建群(?:\s+([\s\S]*))?$/);
127153
+ const alias = text3.match(/^建群(?:\s+([\s\S]*))?$/);
127154
127154
  return alias ? (alias[1] ?? "").trim() : void 0;
127155
127155
  };
127156
127156
  var planModeOf = (argument, chinese) => {
@@ -127159,7 +127159,7 @@ var planModeOf = (argument, chinese) => {
127159
127159
  if (argument === "off" || chinese && argument === "\u5173") return "off";
127160
127160
  return "invalid";
127161
127161
  };
127162
- var isThreadCommand = (text2, chinese) => /^\/thread$/i.test(text2.trim()) || chinese && text2.trim() === "\u6362\u5BF9\u8BDD";
127162
+ var isThreadCommand = (text3, chinese) => /^\/thread$/i.test(text3.trim()) || chinese && text3.trim() === "\u6362\u5BF9\u8BDD";
127163
127163
  var ZH_ALIASES = {
127164
127164
  \u505C: "stop",
127165
127165
  \u505C\u6B62: "stop",
@@ -127313,9 +127313,9 @@ var makeCommands = (core, deps) => {
127313
127313
  const { handleModel, handlePlan } = deps.modelPlan;
127314
127314
  const { openPanel } = deps;
127315
127315
  const targetOf = (binding) => chatOf(core.state, chatKeyOf(binding)).target;
127316
- const handleCommand = async (binding, text2, teams, senderId = null) => {
127316
+ const handleCommand = async (binding, text3, teams, senderId = null) => {
127317
127317
  const command = parseChatCommand({
127318
- text: text2,
127318
+ text: text3,
127319
127319
  teams,
127320
127320
  // 中文别名只在回话语言是中文时认,免得英文用户打一个「停」就被当成命令。
127321
127321
  chinese: t.language === "zh-CN"
@@ -127986,8 +127986,8 @@ var optionDescriptionOf = (item, option, t) => {
127986
127986
  };
127987
127987
  var QUESTION_TEXT_MAX_CHARS = 1500;
127988
127988
  var ANSWER_ECHO_MAX_CHARS = 200;
127989
- var clip = (text2, limit) => {
127990
- const chars = Array.from(text2.trim());
127989
+ var clip = (text3, limit) => {
127990
+ const chars = Array.from(text3.trim());
127991
127991
  return chars.length <= limit ? chars.join("") : `${chars.slice(0, limit).join("")}\u2026`;
127992
127992
  };
127993
127993
  var titleOf = (item, index, total, t) => {
@@ -128043,8 +128043,8 @@ var questionPlainText = (item, index, total, t) => [
128043
128043
  item.multiSelect ? t("question.replyMany") : t("question.replyOne"),
128044
128044
  ...item.allowFreeform ? [t("question.freeformHint")] : []
128045
128045
  ].join("\n");
128046
- var parseNumberedReply = (item, text2, t) => {
128047
- const trimmed = text2.trim();
128046
+ var parseNumberedReply = (item, text3, t) => {
128047
+ const trimmed = text3.trim();
128048
128048
  const pattern = item.multiSelect ? /^\d+(?:[\s,,、]+\d+)*$/ : /^\d+$/;
128049
128049
  if (!pattern.test(trimmed)) return null;
128050
128050
  const numbers = [...new Set(trimmed.split(/[\s,,、]+/).map(Number))];
@@ -128237,9 +128237,9 @@ var makeQuestionFlow = (host) => {
128237
128237
  );
128238
128238
  return handledWith(null);
128239
128239
  };
128240
- const answerByText = async (chatKey, threadId, text2) => {
128240
+ const answerByText = async (chatKey, threadId, text3) => {
128241
128241
  const record2 = openQuestionOf(host.state(), chatKey, threadId);
128242
- const trimmed = text2.trim();
128242
+ const trimmed = text3.trim();
128243
128243
  if (record2 === void 0 || trimmed === "") return false;
128244
128244
  const unanswered = record2.items.filter(isUnanswered);
128245
128245
  const first = unanswered[0];
@@ -128367,7 +128367,7 @@ var makeQueueFlow = (host, deps) => {
128367
128367
  queuePaused: execution.queuePaused,
128368
128368
  intent: execution.intents.find((intent) => intent.intentId === intentId)
128369
128369
  });
128370
- const noteQueued = async (chatKey, threadId, messageId, text2) => {
128370
+ const noteQueued = async (chatKey, threadId, messageId, text3) => {
128371
128371
  const target = host.target(chatKey);
128372
128372
  if (target === void 0) return;
128373
128373
  let execution;
@@ -128393,7 +128393,7 @@ var makeQueueFlow = (host, deps) => {
128393
128393
  chatKey,
128394
128394
  threadId,
128395
128395
  intentId,
128396
- text: text2,
128396
+ text: text3,
128397
128397
  steerToken: host.newToken(),
128398
128398
  withdrawToken: host.newToken(),
128399
128399
  resumeToken: host.newToken()
@@ -128582,9 +128582,9 @@ var makeInteractions = (core, deps) => {
128582
128582
  return false;
128583
128583
  },
128584
128584
  dispatch: (command) => host.commands.dispatch(command),
128585
- say: async (chatKey, text2) => {
128585
+ say: async (chatKey, text3) => {
128586
128586
  const binding = bindingForChatKey(chatKey);
128587
- if (binding !== void 0) await deliver(binding, text2);
128587
+ if (binding !== void 0) await deliver(binding, text3);
128588
128588
  },
128589
128589
  newToken: () => crypto.randomUUID().slice(0, 8),
128590
128590
  newId: () => crypto.randomUUID(),
@@ -128768,8 +128768,121 @@ var RETRY_AFTER_CAP_MS = 1e4;
128768
128768
  var CALL_SPACING_MS = 150;
128769
128769
  var DETAIL_MAX_CHARS = 200;
128770
128770
 
128771
+ // src/lark/setup/setupItemSchema.ts
128772
+ var SETUP_STEP_IDS = [
128773
+ "login",
128774
+ "identity",
128775
+ "findApp",
128776
+ "createApp",
128777
+ "enableBot",
128778
+ "longConnection",
128779
+ "scopes",
128780
+ "events",
128781
+ "callbacks",
128782
+ "publish",
128783
+ "secret"
128784
+ ];
128785
+ var STEP_STATES = ["pending", "running", "done", "skipped", "failed"];
128786
+ var SETUP_ITEM_SCHEMA = {
128787
+ type: "object",
128788
+ additionalProperties: false,
128789
+ required: ["kind"],
128790
+ properties: {
128791
+ kind: { type: "string" },
128792
+ payload: { type: "string" },
128793
+ expiresAt: { type: "string" },
128794
+ statusKey: { type: "string" },
128795
+ params: { type: "object" },
128796
+ expired: { type: "boolean" },
128797
+ steps: {
128798
+ type: "array",
128799
+ items: {
128800
+ type: "object",
128801
+ additionalProperties: false,
128802
+ required: ["id", "labelKey", "state"],
128803
+ properties: {
128804
+ id: { type: "string", enum: [...SETUP_STEP_IDS] },
128805
+ labelKey: { type: "string" },
128806
+ state: { type: "string", enum: [...STEP_STATES] }
128807
+ }
128808
+ }
128809
+ },
128810
+ // 卡片动作的 done 不往草稿里填:宿主要求带这个字段,内容永远是空对象。
128811
+ fills: { type: "object", additionalProperties: false },
128812
+ messageKey: { type: "string" },
128813
+ warnings: {
128814
+ type: "array",
128815
+ items: {
128816
+ type: "object",
128817
+ additionalProperties: false,
128818
+ required: ["key"],
128819
+ properties: {
128820
+ key: { type: "string" },
128821
+ params: { type: "object" }
128822
+ }
128823
+ }
128824
+ },
128825
+ reasonKey: { type: "string" },
128826
+ detail: { type: "string" }
128827
+ },
128828
+ oneOf: [
128829
+ { properties: { kind: { const: "qr" } }, required: ["payload", "expiresAt"] },
128830
+ { properties: { kind: { const: "status" } }, required: ["statusKey"] },
128831
+ { properties: { kind: { const: "steps" } }, required: ["steps"] },
128832
+ { properties: { kind: { const: "done" } }, required: ["messageKey"] },
128833
+ { properties: { kind: { const: "failed" } }, required: ["reasonKey"] }
128834
+ ]
128835
+ };
128836
+
128837
+ // src/lark/setup/saveBot.ts
128838
+ var OPEN_ID_PREFIX = "ou_";
128839
+ var LARK_PLATFORM = "lark";
128840
+ var asRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? { ...value } : {};
128841
+ var text = (row, key) => {
128842
+ const value = row[key];
128843
+ return typeof value === "string" ? value.trim() : "";
128844
+ };
128845
+ var freeRowId = (table2) => {
128846
+ if (!(LARK_PLATFORM in table2)) return LARK_PLATFORM;
128847
+ for (let n = 2; ; n += 1) {
128848
+ const candidate = `${LARK_PLATFORM}-${String(n)}`;
128849
+ if (!(candidate in table2)) return candidate;
128850
+ }
128851
+ };
128852
+ var senderIdOf = (creatorId) => creatorId !== void 0 && creatorId.startsWith(OPEN_ID_PREFIX) ? creatorId : void 0;
128853
+ var upsertLarkBot = (current, result) => {
128854
+ const config2 = asRecord(current);
128855
+ const table2 = asRecord(config2[BOTS_FIELD]);
128856
+ const sender = senderIdOf(result.creatorId);
128857
+ const existingId = Object.keys(table2).find((rowId2) => {
128858
+ const row2 = asRecord(table2[rowId2]);
128859
+ const platform = text(row2, "platform") || DEFAULT_PLATFORM;
128860
+ return platform === LARK_PLATFORM && text(row2, "larkAppId") === result.appId;
128861
+ });
128862
+ const rowId = existingId ?? freeRowId(table2);
128863
+ const base2 = existingId === void 0 ? {} : asRecord(table2[existingId]);
128864
+ const keptList = text(base2, "allowedSenders");
128865
+ const allowedSenders = keptList !== "" ? keptList : sender ?? "";
128866
+ const row = {
128867
+ ...base2,
128868
+ displayName: text(base2, "displayName") || result.appName,
128869
+ platform: LARK_PLATFORM,
128870
+ larkAppId: result.appId,
128871
+ larkAppSecret: result.appSecret,
128872
+ allowedSenders
128873
+ };
128874
+ table2[rowId] = row;
128875
+ config2[BOTS_FIELD] = table2;
128876
+ return {
128877
+ config: config2,
128878
+ rowId,
128879
+ secretPath: [BOTS_FIELD, rowId, "larkAppSecret"],
128880
+ allowListEmpty: allowedSenders === ""
128881
+ };
128882
+ };
128883
+
128771
128884
  // src/lark/setup/consolePayloads.ts
128772
- var asRecord = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
128885
+ var asRecord2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
128773
128886
  var pickString = (record2, keys) => {
128774
128887
  for (const key of keys) {
128775
128888
  const value = record2[key];
@@ -128779,8 +128892,8 @@ var pickString = (record2, keys) => {
128779
128892
  return void 0;
128780
128893
  };
128781
128894
  var pickDeep = (payload, keys) => {
128782
- const record2 = asRecord(payload);
128783
- return pickString(record2, keys) ?? pickString(asRecord(record2.data), keys);
128895
+ const record2 = asRecord2(payload);
128896
+ return pickString(record2, keys) ?? pickString(asRecord2(record2.data), keys);
128784
128897
  };
128785
128898
  var uniq = (values) => [...new Set(values.filter((v) => v !== ""))];
128786
128899
  var extractCsrfToken = (html) => {
@@ -128816,14 +128929,14 @@ var extractIdentity = (html) => {
128816
128929
  if (json === null) return null;
128817
128930
  let user;
128818
128931
  try {
128819
- user = asRecord(JSON.parse(json));
128932
+ user = asRecord2(JSON.parse(json));
128820
128933
  } catch {
128821
128934
  return null;
128822
128935
  }
128823
128936
  const userId = pickString(user, ["id", "userId", "user_id"]);
128824
- const userName = pickString(user, ["name", "userName", "user_name"]) ?? pickString(asRecord(user.displayName), ["value"]);
128937
+ const userName = pickString(user, ["name", "userName", "user_name"]) ?? pickString(asRecord2(user.displayName), ["value"]);
128825
128938
  const tenantId = pickString(user, ["tenantId", "tenant_id"]);
128826
- const tenantName = pickString(asRecord(user.tenantDisplayName), ["value"]) ?? pickString(user, ["tenantName", "tenant_name"]);
128939
+ const tenantName = pickString(asRecord2(user.tenantDisplayName), ["value"]) ?? pickString(user, ["tenantName", "tenant_name"]);
128827
128940
  if (!userId || !userName || !tenantId || !tenantName) return null;
128828
128941
  return { userId, userName, tenantId, tenantName };
128829
128942
  };
@@ -128894,12 +129007,12 @@ var extractClientId = (payload) => {
128894
129007
  var extractUploadedUrl = (payload) => pickDeep(payload, ["url"]);
128895
129008
  var extractSecret = (payload) => pickDeep(payload, ["secret"]);
128896
129009
  var extractAppListPage = (payload) => {
128897
- const record2 = asRecord(payload);
128898
- const data = asRecord(record2.data);
129010
+ const record2 = asRecord2(payload);
129011
+ const data = asRecord2(record2.data);
128899
129012
  const raw = Array.isArray(data.apps) ? data.apps : Array.isArray(record2.apps) ? record2.apps : [];
128900
129013
  const apps = [];
128901
129014
  for (const item of raw) {
128902
- const entry = asRecord(item);
129015
+ const entry = asRecord2(item);
128903
129016
  const clientId = pickString(entry, ["clientId", "client_id", "appId", "app_id", "appID"]);
128904
129017
  if (clientId === void 0 || !clientId.startsWith("cli_")) continue;
128905
129018
  apps.push({
@@ -128913,14 +129026,14 @@ var extractAppListPage = (payload) => {
128913
129026
  };
128914
129027
  var eventIds = (value) => Array.isArray(value) ? uniq(
128915
129028
  value.flatMap((item) => {
128916
- const id = typeof item === "string" ? item : pickString(asRecord(item), ["id"]);
129029
+ const id = typeof item === "string" ? item : pickString(asRecord2(item), ["id"]);
128917
129030
  return id === void 0 ? [] : [id];
128918
129031
  })
128919
129032
  ) : [];
128920
- var eventIdsFromDetails = (value) => Array.isArray(value) ? uniq(value.flatMap((group) => eventIds(asRecord(group).items))) : [];
129033
+ var eventIdsFromDetails = (value) => Array.isArray(value) ? uniq(value.flatMap((group) => eventIds(asRecord2(group).items))) : [];
128921
129034
  var unwrapData = (payload) => {
128922
- const root = asRecord(payload);
128923
- const wrapped = asRecord(root.data);
129035
+ const root = asRecord2(payload);
129036
+ const wrapped = asRecord2(root.data);
128924
129037
  return Object.keys(wrapped).length > 0 ? wrapped : root;
128925
129038
  };
128926
129039
  var extractEventState = (payload) => {
@@ -129000,10 +129113,10 @@ var planScopes = (wanted, catalog) => {
129000
129113
  return { tenantIds, userIds, missing, toAdd, alreadyGranted };
129001
129114
  };
129002
129115
  var extractVersionList = (payload) => {
129003
- const data = asRecord(asRecord(payload).data);
129116
+ const data = asRecord2(asRecord2(payload).data);
129004
129117
  const versions = Array.isArray(data.versions) ? data.versions : [];
129005
129118
  return versions.flatMap((item) => {
129006
- const row = asRecord(item);
129119
+ const row = asRecord2(item);
129007
129120
  const appVersion = pickString(row, ["appVersion"]);
129008
129121
  return appVersion === void 0 ? [] : [{ appVersion, versionId: pickString(row, ["versionId", "version_id", "id"]) }];
129009
129122
  });
@@ -129023,12 +129136,12 @@ var nextAppVersion = (versions) => {
129023
129136
  };
129024
129137
  var extractVersionId = (payload) => {
129025
129138
  const keys = ["versionId", "version_id", "id"];
129026
- const root = asRecord(payload);
129027
- const data = asRecord(root.data);
129028
- return pickString(root, keys) ?? pickString(data, keys) ?? pickString(asRecord(data.appVersion), keys);
129139
+ const root = asRecord2(payload);
129140
+ const data = asRecord2(root.data);
129141
+ return pickString(root, keys) ?? pickString(data, keys) ?? pickString(asRecord2(data.appVersion), keys);
129029
129142
  };
129030
129143
  var visibilityOf = (value) => {
129031
- const record2 = asRecord(value);
129144
+ const record2 = asRecord2(value);
129032
129145
  const strings = (key) => Array.isArray(record2[key]) ? record2[key].filter((item) => typeof item === "string") : [];
129033
129146
  return {
129034
129147
  departments: strings("departments"),
@@ -129038,7 +129151,7 @@ var visibilityOf = (value) => {
129038
129151
  };
129039
129152
  };
129040
129153
  var extractOnlineVisibility = (payload) => {
129041
- const data = asRecord(asRecord(payload).data);
129154
+ const data = asRecord2(asRecord2(payload).data);
129042
129155
  const visible = data.visibleSuggest ?? data.visible_suggest;
129043
129156
  if (visible === void 0) return null;
129044
129157
  return {
@@ -129227,10 +129340,10 @@ var openConsole = async (deps, jar) => {
129227
129340
  ...body === void 0 ? {} : { body },
129228
129341
  signal
129229
129342
  });
129230
- const text2 = await response.text();
129343
+ const text3 = await response.text();
129231
129344
  let data = null;
129232
129345
  try {
129233
- data = JSON.parse(text2);
129346
+ data = JSON.parse(text3);
129234
129347
  } catch {
129235
129348
  data = null;
129236
129349
  }
@@ -129298,6 +129411,12 @@ var openConsole = async (deps, jar) => {
129298
129411
  };
129299
129412
  };
129300
129413
 
129414
+ // src/lark/setup/consoleFailurePolicy.ts
129415
+ var isDefiniteRejection = (error) => error instanceof ConsoleError && (error.kind === "api" || error.kind === "http" && error.status === 404);
129416
+ var resultUnknown = (error) => error instanceof ConsoleError && (error.kind === "network" || error.kind === "timeout" || error.kind === "protocol" || error.kind === "http" && (error.status ?? 0) >= 500);
129417
+ var isOwnerDenied = (error) => error.status === 403 && error.code === 10003;
129418
+ var isRecoverable = (error) => error instanceof ConsoleError && (error.kind === "api" || error.kind === "http" || error.kind === "protocol") && error.status !== 401 && error.status !== 403;
129419
+
129301
129420
  // src/lark/setup/cookieJar.ts
129302
129421
  var MAX_REDIRECT_HOPS = 10;
129303
129422
  var parseSetCookie = (responseUrl, header) => {
@@ -129562,8 +129681,8 @@ var TOKEN_LIKE = /[A-Za-z0-9_=-]{24,}/g;
129562
129681
  var MIN_SECRET_LENGTH = 6;
129563
129682
  var makeRedactor = () => {
129564
129683
  const secrets = /* @__PURE__ */ new Set();
129565
- const redact = (text2) => {
129566
- let out = text2;
129684
+ const redact = (text3) => {
129685
+ let out = text3;
129567
129686
  for (const secret of [...secrets].sort((a, b) => b.length - a.length)) {
129568
129687
  out = out.split(secret).join(MASK);
129569
129688
  }
@@ -129574,38 +129693,30 @@ var makeRedactor = () => {
129574
129693
  if (typeof secret === "string" && secret.length >= MIN_SECRET_LENGTH) secrets.add(secret);
129575
129694
  },
129576
129695
  redact,
129577
- detail: (text2) => redact(text2).slice(0, DETAIL_MAX_CHARS)
129696
+ detail: (text3) => redact(text3).slice(0, DETAIL_MAX_CHARS)
129578
129697
  };
129579
129698
  };
129580
129699
 
129581
129700
  // src/lark/setup/setupFlow.ts
129582
- var SETUP_STEP_IDS = [
129583
- "login",
129584
- "identity",
129585
- "findApp",
129586
- "createApp",
129587
- "enableBot",
129588
- "longConnection",
129589
- "scopes",
129590
- "events",
129591
- "callbacks",
129592
- "publish",
129593
- "secret"
129594
- ];
129595
129701
  var SETUP_KEYS = {
129596
129702
  statusWaiting: "setup.status.waiting",
129597
129703
  statusScanned: "setup.status.scanned",
129598
129704
  statusExpired: "setup.status.expired",
129599
129705
  done: "setup.done",
129706
+ /** 读不到扫码人的聊天 id,允许名单留空。 */
129707
+ warnSenderUnknown: "setup.warn.senderUnknown",
129600
129708
  warnScopesMissing: "setup.warn.scopesMissing",
129601
129709
  /** 建应用的结果不明:控制台里可能已经有了,重试会按标记找回它。 */
129602
129710
  failureCreateUnknown: "setup.failure.createUnknown",
129603
129711
  /** 应用已经发布,只差 secret 没读到。 */
129604
129712
  failureSecretMissing: "setup.failure.secretMissing",
129605
129713
  /** 配置被中止(插件停用),订阅方还在听。 */
129606
- failureStopped: "setup.failure.stopped"
129714
+ failureStopped: "setup.failure.stopped",
129715
+ /** 应用已配好并发布,但凭据没能存进设置。 */
129716
+ failureSaveFailed: "setup.failure.saveFailed"
129607
129717
  };
129608
129718
  var stepLabelKey = (id) => `setup.step.${id}`;
129719
+ var stepProgressKey = (id) => `setup.progress.${id}`;
129609
129720
  var FAILURE_REASON_KEYS = {
129610
129721
  "qr-expired": "setup.failure.qrExpired",
129611
129722
  "scan-timeout": "setup.failure.scanTimeout",
@@ -129634,10 +129745,6 @@ var newSession = () => {
129634
129745
  return { jar: makeCookieJar((value) => redactor.register(value)), redactor };
129635
129746
  };
129636
129747
  var errorText = (error) => error instanceof Error ? error.message : String(error);
129637
- var isDefiniteRejection = (error) => error instanceof ConsoleError && (error.kind === "api" || error.kind === "http" && error.status === 404);
129638
- var resultUnknown = (error) => error instanceof ConsoleError && (error.kind === "network" || error.kind === "timeout" || error.kind === "protocol" || error.kind === "http" && (error.status ?? 0) >= 500);
129639
- var isOwnerDenied = (error) => error.status === 403 && error.code === 10003;
129640
- var isRecoverable = (error) => error instanceof ConsoleError && (error.kind === "api" || error.kind === "http" || error.kind === "protocol") && error.status !== 401 && error.status !== 403;
129641
129748
  var toFailure = (error, budgetExpired, redactor) => {
129642
129749
  const detail = redactor.detail(errorText(error));
129643
129750
  if (error instanceof SetupFailure) return { reason: error.reason, detail };
@@ -129709,7 +129816,7 @@ var createSetupRunner = (deps) => {
129709
129816
  const run = async (input, emit, signal) => {
129710
129817
  if (running) {
129711
129818
  emit({ kind: "failed", reasonKey: failureReasonKey("busy") });
129712
- return;
129819
+ return void 0;
129713
129820
  }
129714
129821
  running = true;
129715
129822
  const work = new AbortController();
@@ -129739,11 +129846,15 @@ var createSetupRunner = (deps) => {
129739
129846
  });
129740
129847
  const setStep = (id, state) => {
129741
129848
  steps.set(id, state);
129742
- publishSteps();
129743
129849
  };
129744
129850
  const step = async (id, body) => {
129745
129851
  progress.current = id;
129746
129852
  setStep(id, "running");
129853
+ emit({
129854
+ kind: "status",
129855
+ statusKey: stepProgressKey(id),
129856
+ params: { n: String(SETUP_STEP_IDS.indexOf(id) + 1), total: String(SETUP_STEP_IDS.length) }
129857
+ });
129747
129858
  try {
129748
129859
  const result = await body();
129749
129860
  if (steps.get(id) === "running") setStep(id, "done");
@@ -129771,7 +129882,6 @@ var createSetupRunner = (deps) => {
129771
129882
  };
129772
129883
  try {
129773
129884
  deps.log.info("lark setup started", { reusingSession: reused });
129774
- publishSteps();
129775
129885
  let client;
129776
129886
  if (reused) {
129777
129887
  try {
@@ -130085,24 +130195,22 @@ var createSetupRunner = (deps) => {
130085
130195
  });
130086
130196
  session.redactor.register(secret);
130087
130197
  deps.log.info("lark setup finished", { appId: id, adopted });
130088
- emit({
130089
- kind: "done",
130090
- fills: { larkAppId: id, larkAppSecret: secret },
130091
- messageKey: SETUP_KEYS.done,
130092
- ...scopesMissing.length > 0 ? {
130093
- warnings: [
130094
- { key: SETUP_KEYS.warnScopesMissing, params: { names: scopesMissing.join(", ") } }
130095
- ]
130096
- } : {}
130097
- });
130098
130198
  session.jar.clear();
130199
+ return {
130200
+ appId: id,
130201
+ appSecret: secret,
130202
+ appName: baseName2,
130203
+ creatorId: identity?.userId,
130204
+ scopesMissing
130205
+ };
130099
130206
  } catch (error) {
130100
130207
  if (work.signal.aborted && !budgetExpired) {
130101
130208
  session.jar.clear();
130102
130209
  if (!signal.aborted) emit({ kind: "failed", reasonKey: SETUP_KEYS.failureStopped });
130103
- return;
130210
+ return void 0;
130104
130211
  }
130105
130212
  const failure2 = toFailure(error, budgetExpired, session.redactor);
130213
+ publishSteps();
130106
130214
  if (failure2.reason === "qr-expired") {
130107
130215
  emit({ kind: "status", statusKey: SETUP_KEYS.statusExpired, expired: true });
130108
130216
  }
@@ -130122,6 +130230,7 @@ var createSetupRunner = (deps) => {
130122
130230
  });
130123
130231
  if (clientReady || reused) hold(session);
130124
130232
  else session.jar.clear();
130233
+ return void 0;
130125
130234
  } finally {
130126
130235
  budgetTimer.abort();
130127
130236
  signal.removeEventListener("abort", abortFromParent);
@@ -130142,6 +130251,14 @@ var createSetupRunner = (deps) => {
130142
130251
  // src/lark/setup/setupCommands.ts
130143
130252
  var SETUP_START_COMMAND = "larkSetup.start";
130144
130253
  var SETUP_CHECKLIST_COMMAND = "larkSetup.checklist";
130254
+ var LARK_SETUP_CARD_ACTION = {
130255
+ id: "larkSetup",
130256
+ labelKey: "setup.action.label",
130257
+ descriptionKey: "setup.action.description",
130258
+ badgeKey: "setup.action.badge",
130259
+ warningKey: "setup.action.warning",
130260
+ command: SETUP_START_COMMAND
130261
+ };
130145
130262
  var MANUAL_STEP_IDS = [
130146
130263
  "createApp",
130147
130264
  "enableBot",
@@ -130150,80 +130267,9 @@ var MANUAL_STEP_IDS = [
130150
130267
  "publish",
130151
130268
  "fillRow"
130152
130269
  ];
130153
- var STEP_STATES = ["pending", "running", "done", "skipped", "failed"];
130154
- var SETUP_ITEM_SCHEMA = {
130155
- type: "object",
130156
- additionalProperties: false,
130157
- required: ["kind"],
130158
- properties: {
130159
- kind: { type: "string" },
130160
- payload: { type: "string" },
130161
- expiresAt: { type: "string" },
130162
- statusKey: { type: "string" },
130163
- params: { type: "object" },
130164
- expired: { type: "boolean" },
130165
- steps: {
130166
- type: "array",
130167
- items: {
130168
- type: "object",
130169
- additionalProperties: false,
130170
- required: ["id", "labelKey", "state"],
130171
- properties: {
130172
- id: { type: "string", enum: [...SETUP_STEP_IDS] },
130173
- labelKey: { type: "string" },
130174
- state: { type: "string", enum: [...STEP_STATES] }
130175
- }
130176
- }
130177
- },
130178
- fills: {
130179
- type: "object",
130180
- additionalProperties: false,
130181
- required: ["larkAppId", "larkAppSecret"],
130182
- properties: {
130183
- larkAppId: { type: "string" },
130184
- larkAppSecret: { type: "string" }
130185
- }
130186
- },
130187
- messageKey: { type: "string" },
130188
- warnings: {
130189
- type: "array",
130190
- items: {
130191
- type: "object",
130192
- additionalProperties: false,
130193
- required: ["key"],
130194
- properties: {
130195
- key: { type: "string" },
130196
- params: { type: "object" }
130197
- }
130198
- }
130199
- },
130200
- reasonKey: { type: "string" },
130201
- detail: { type: "string" }
130202
- },
130203
- oneOf: [
130204
- { properties: { kind: { const: "qr" } }, required: ["payload", "expiresAt"] },
130205
- { properties: { kind: { const: "status" } }, required: ["statusKey"] },
130206
- { properties: { kind: { const: "steps" } }, required: ["steps"] },
130207
- { properties: { kind: { const: "done" } }, required: ["fills"] },
130208
- { properties: { kind: { const: "failed" } }, required: ["reasonKey"] }
130209
- ]
130210
- };
130211
130270
  var SETUP_START_PAYLOAD_SCHEMA = {
130212
130271
  type: "object",
130213
- additionalProperties: false,
130214
- properties: {
130215
- rowId: { type: "string", pattern: "^[a-zA-Z][a-zA-Z0-9_-]*$", maxLength: 64 },
130216
- values: { type: "object" }
130217
- }
130218
- };
130219
- var NAME_COLUMN = "displayName";
130220
- var APP_NAME_MAX_CHARS = 60;
130221
- var appNameFromValues = (values) => {
130222
- if (values === null || typeof values !== "object") return void 0;
130223
- const raw = values[NAME_COLUMN];
130224
- if (typeof raw !== "string") return void 0;
130225
- const name = raw.trim();
130226
- return name === "" || name.length > APP_NAME_MAX_CHARS ? void 0 : name;
130272
+ additionalProperties: false
130227
130273
  };
130228
130274
  var CHECKLIST_RESULT_SCHEMA = {
130229
130275
  type: "object",
@@ -130276,6 +130322,42 @@ var makeRealClock = () => ({
130276
130322
  signal?.addEventListener("abort", onAbort, { once: true });
130277
130323
  })
130278
130324
  });
130325
+ var saveAndConclude = async (ctx, result) => {
130326
+ try {
130327
+ const saved = upsertLarkBot(await ctx.settings.read(), result);
130328
+ await ctx.settings.write(saved.config, { secrets: [saved.secretPath] });
130329
+ ctx.log.info("lark setup saved the bot", {
130330
+ appId: result.appId,
130331
+ rowId: saved.rowId,
130332
+ allowListed: !saved.allowListEmpty
130333
+ });
130334
+ const warnings = [
130335
+ ...saved.allowListEmpty ? [{ key: SETUP_KEYS.warnSenderUnknown }] : [],
130336
+ ...result.scopesMissing.length > 0 ? [
130337
+ {
130338
+ key: SETUP_KEYS.warnScopesMissing,
130339
+ params: { names: result.scopesMissing.join(", ") }
130340
+ }
130341
+ ] : []
130342
+ ];
130343
+ return {
130344
+ kind: "done",
130345
+ fills: {},
130346
+ messageKey: SETUP_KEYS.done,
130347
+ ...warnings.length > 0 ? { warnings } : {}
130348
+ };
130349
+ } catch (error) {
130350
+ ctx.log.warn("lark setup could not save the bot", {
130351
+ appId: result.appId,
130352
+ error: error instanceof Error ? error.message : String(error)
130353
+ });
130354
+ return {
130355
+ kind: "failed",
130356
+ reasonKey: SETUP_KEYS.failureSaveFailed,
130357
+ params: { appId: result.appId }
130358
+ };
130359
+ }
130360
+ };
130279
130361
  var registerLarkSetup = (ctx, options = {}) => {
130280
130362
  const runner = createSetupRunner({
130281
130363
  fetch: ctx.http,
@@ -130296,15 +130378,16 @@ var registerLarkSetup = (ctx, options = {}) => {
130296
130378
  itemSchema: SETUP_ITEM_SCHEMA,
130297
130379
  // 条目是一份份快照与终态,慢订阅方丢掉的只该是旧的。
130298
130380
  buffer: { latest: 16 },
130299
- handle: async (payload, emit, signal) => {
130300
- await runner.run(
130301
- { appName: appNameFromValues(payload["values"]) },
130302
- (item) => {
130303
- const wire = item;
130304
- emit(wire);
130305
- },
130381
+ handle: async (_payload, emit, signal) => {
130382
+ const send = (item) => emit(item);
130383
+ const result = await runner.run(
130384
+ {},
130385
+ // 先落到宿主约定的条目类型上:形状不对在编译期就报,而不是到客户端被整条丢掉。
130386
+ (item) => send(item),
130306
130387
  signal
130307
130388
  );
130389
+ if (result === void 0) return;
130390
+ send(await saveAndConclude(ctx, result));
130308
130391
  }
130309
130392
  });
130310
130393
  ctx.command({
@@ -130320,10 +130403,10 @@ var registerLarkSetup = (ctx, options = {}) => {
130320
130403
  };
130321
130404
 
130322
130405
  // src/splitMessage.ts
130323
- var splitMessage = (text2, limit) => {
130324
- if (text2.length <= limit) return [text2];
130406
+ var splitMessage = (text3, limit) => {
130407
+ if (text3.length <= limit) return [text3];
130325
130408
  const chunks = [];
130326
- let rest = text2;
130409
+ let rest = text3;
130327
130410
  while (rest.length > limit) {
130328
130411
  const window2 = rest.slice(0, limit);
130329
130412
  const paragraph2 = window2.lastIndexOf("\n\n");
@@ -130549,7 +130632,7 @@ var createChat = async (input) => {
130549
130632
  }
130550
130633
  return chatId;
130551
130634
  };
130552
- var splitForLark = (text2) => splitMessage(text2, LARK_TEXT_MAX_CHARS);
130635
+ var splitForLark = (text3) => splitMessage(text3, LARK_TEXT_MAX_CHARS);
130553
130636
 
130554
130637
  // src/larkCardStream.ts
130555
130638
  var LARK_CARD_THROTTLE_MS = 400;
@@ -131591,10 +131674,10 @@ var REBuilder = class {
131591
131674
  }
131592
131675
  };
131593
131676
  var web_schema = {
131594
- validate: (text2, pos, self2) => {
131677
+ validate: (text3, pos, self2) => {
131595
131678
  const re = self2.re.get_http_validator();
131596
131679
  re.lastIndex = pos;
131597
- const m = re.exec(text2);
131680
+ const m = re.exec(text3);
131598
131681
  return m ? m[0].length : 0;
131599
131682
  },
131600
131683
  normalize: (match, self2) => self2.normalize(match)
@@ -131604,13 +131687,13 @@ var defaultSchemas = {
131604
131687
  "https:": web_schema,
131605
131688
  "ftp:": web_schema,
131606
131689
  "//": {
131607
- validate: function(text2, pos, self2) {
131690
+ validate: function(text3, pos, self2) {
131608
131691
  const re = self2.re.get_relative_proto_validator();
131609
131692
  re.lastIndex = pos;
131610
- const m = re.exec(text2);
131693
+ const m = re.exec(text3);
131611
131694
  if (m) {
131612
- if (pos >= 3 && text2[pos - 3] === ":") return 0;
131613
- if (pos >= 3 && text2[pos - 3] === "/") return 0;
131695
+ if (pos >= 3 && text3[pos - 3] === ":") return 0;
131696
+ if (pos >= 3 && text3[pos - 3] === "/") return 0;
131614
131697
  return m[0].length;
131615
131698
  }
131616
131699
  return 0;
@@ -131618,10 +131701,10 @@ var defaultSchemas = {
131618
131701
  normalize: (match, self2) => self2.normalize(match)
131619
131702
  },
131620
131703
  "mailto:": {
131621
- validate: function(text2, pos, self2) {
131704
+ validate: function(text3, pos, self2) {
131622
131705
  const re = self2.re.get_mailto_validator();
131623
131706
  re.lastIndex = pos;
131624
- const m = re.exec(text2);
131707
+ const m = re.exec(text3);
131625
131708
  return m ? m[0].length : 0;
131626
131709
  },
131627
131710
  normalize: (match, self2) => self2.normalize(match)
@@ -131660,8 +131743,8 @@ var Match = class {
131660
131743
  text;
131661
131744
  /** Normalized URL of matched string. */
131662
131745
  url;
131663
- constructor(text2, schema, index, lastIndex) {
131664
- const raw = text2.slice(index, lastIndex);
131746
+ constructor(text3, schema, index, lastIndex) {
131747
+ const raw = text3.slice(index, lastIndex);
131665
131748
  this.schema = schema.toLowerCase();
131666
131749
  this.index = index;
131667
131750
  this.lastIndex = lastIndex;
@@ -131767,24 +131850,24 @@ var LinkifyIt = class {
131767
131850
  *
131768
131851
  * @param text Text to scan.
131769
131852
  */
131770
- test(text2) {
131771
- if (!text2.length) return false;
131853
+ test(text3) {
131854
+ if (!text3.length) return false;
131772
131855
  let m, re;
131773
131856
  re = this.re.get_schema_search();
131774
131857
  re.lastIndex = 0;
131775
- while ((m = re.exec(text2)) !== null) if (this.testSchemaAt(text2, m[2], re.lastIndex)) return true;
131858
+ while ((m = re.exec(text3)) !== null) if (this.testSchemaAt(text3, m[2], re.lastIndex)) return true;
131776
131859
  if (this.__opts__.fuzzyLink && this.__schemas__["http:"]) {
131777
131860
  re = this.re.get_fuzzy_link_search();
131778
131861
  re.lastIndex = 0;
131779
- if (re.exec(text2) !== null) return true;
131862
+ if (re.exec(text3) !== null) return true;
131780
131863
  }
131781
131864
  if (this.__opts__.fuzzyEmail && this.__schemas__["mailto:"]) {
131782
- if (text2.indexOf("@") >= 0) {
131865
+ if (text3.indexOf("@") >= 0) {
131783
131866
  const mailHostRe = this.re.get_fuzzy_mail_host_search();
131784
131867
  const mailNameRe = this.re.get_mail_name_validator();
131785
131868
  mailHostRe.lastIndex = 0;
131786
- while ((m = mailHostRe.exec(text2)) !== null) {
131787
- const name = text2.slice(Math.max(0, m.index - 65), m.index);
131869
+ while ((m = mailHostRe.exec(text3)) !== null) {
131870
+ const name = text3.slice(Math.max(0, m.index - 65), m.index);
131788
131871
  if (mailNameRe.test(name)) return true;
131789
131872
  }
131790
131873
  }
@@ -131799,9 +131882,9 @@ var LinkifyIt = class {
131799
131882
  * @param schema Rule (schema) name.
131800
131883
  * @param pos Text offset to check from.
131801
131884
  */
131802
- testSchemaAt(text2, schema, pos) {
131885
+ testSchemaAt(text3, schema, pos) {
131803
131886
  if (!this.__schemas__[schema.toLowerCase()]) return 0;
131804
- return this.__schemas__[schema.toLowerCase()].validate(text2.slice(0, pos + this.__opts__.maxLength), pos, this);
131887
+ return this.__schemas__[schema.toLowerCase()].validate(text3.slice(0, pos + this.__opts__.maxLength), pos, this);
131805
131888
  }
131806
131889
  /**
131807
131890
  * Returns array of found link descriptions or `null` on fail. We strongly
@@ -131809,7 +131892,7 @@ var LinkifyIt = class {
131809
131892
  *
131810
131893
  * @param text Text to scan.
131811
131894
  */
131812
- match(text2) {
131895
+ match(text3) {
131813
131896
  const result = [];
131814
131897
  const schemaRe = this.re.get_schema_search();
131815
131898
  let fuzzyLinkRe;
@@ -131822,7 +131905,7 @@ var LinkifyIt = class {
131822
131905
  let fuzzyLinkDone = false;
131823
131906
  let fuzzyEmailDone = false;
131824
131907
  let pos = 0;
131825
- if (!text2.length) return null;
131908
+ if (!text3.length) return null;
131826
131909
  schemaRe.lastIndex = 0;
131827
131910
  if (this.__opts__.fuzzyLink && this.__schemas__["http:"]) {
131828
131911
  fuzzyLinkRe = this.re.get_fuzzy_link_search();
@@ -131838,13 +131921,13 @@ var LinkifyIt = class {
131838
131921
  if (mailHostRe && mailNameRe && !fuzzyEmailDone && (!fuzzyEmailCandidate || fuzzyEmailCandidate.index < pos)) {
131839
131922
  if (mailHostRe.lastIndex < scanFrom) mailHostRe.lastIndex = scanFrom;
131840
131923
  for (; ; ) {
131841
- const m = mailHostRe.exec(text2);
131924
+ const m = mailHostRe.exec(text3);
131842
131925
  if (!m) {
131843
131926
  fuzzyEmailDone = true;
131844
131927
  fuzzyEmailCandidate = void 0;
131845
131928
  break;
131846
131929
  }
131847
- const name = mailNameRe.exec(text2.slice(Math.max(0, m.index - 65), m.index));
131930
+ const name = mailNameRe.exec(text3.slice(Math.max(0, m.index - 65), m.index));
131848
131931
  if (!name) continue;
131849
131932
  fuzzyEmailCandidate = {
131850
131933
  schema: "mailto:",
@@ -131858,7 +131941,7 @@ var LinkifyIt = class {
131858
131941
  if (fuzzyLinkRe && !fuzzyLinkDone && (!fuzzyLinkCandidate || fuzzyLinkCandidate.index < pos)) {
131859
131942
  if (fuzzyLinkRe.lastIndex < scanFrom) fuzzyLinkRe.lastIndex = scanFrom;
131860
131943
  for (; ; ) {
131861
- const m = fuzzyLinkRe.exec(text2);
131944
+ const m = fuzzyLinkRe.exec(text3);
131862
131945
  if (!m) {
131863
131946
  fuzzyLinkDone = true;
131864
131947
  fuzzyLinkCandidate = void 0;
@@ -131879,7 +131962,7 @@ var LinkifyIt = class {
131879
131962
  if (!schemaDone) for (; ; ) {
131880
131963
  if (!schemaPrefix) {
131881
131964
  if (schemaRe.lastIndex < scanFrom) schemaRe.lastIndex = scanFrom;
131882
- const m = schemaRe.exec(text2);
131965
+ const m = schemaRe.exec(text3);
131883
131966
  if (!m) {
131884
131967
  schemaDone = true;
131885
131968
  break;
@@ -131897,7 +131980,7 @@ var LinkifyIt = class {
131897
131980
  if (fuzzyCandidate && schemaPrefix.index > fuzzyCandidate.index) break;
131898
131981
  const prefix = schemaPrefix;
131899
131982
  schemaPrefix = void 0;
131900
- const len = this.testSchemaAt(text2, prefix.schema, prefix.lastIndex);
131983
+ const len = this.testSchemaAt(text3, prefix.schema, prefix.lastIndex);
131901
131984
  if (len) {
131902
131985
  schemaCandidate = {
131903
131986
  schema: prefix.schema,
@@ -131913,7 +131996,7 @@ var LinkifyIt = class {
131913
131996
  if (!candidate) break;
131914
131997
  if (candidate === fuzzyEmailCandidate) fuzzyEmailCandidate = void 0;
131915
131998
  else if (candidate === fuzzyLinkCandidate) fuzzyLinkCandidate = void 0;
131916
- const match = new Match(text2, candidate.schema, candidate.index, candidate.lastIndex);
131999
+ const match = new Match(text3, candidate.schema, candidate.index, candidate.lastIndex);
131917
132000
  if (match.schema) this.__schemas__[match.schema].normalize(match, this);
131918
132001
  else this.normalize(match);
131919
132002
  result.push(match);
@@ -131928,13 +132011,13 @@ var LinkifyIt = class {
131928
132011
  *
131929
132012
  * @param text Text to scan.
131930
132013
  */
131931
- matchAtStart(text2) {
131932
- if (!text2.length) return null;
131933
- const m = this.re.get_schema_at_start().exec(text2);
132014
+ matchAtStart(text3) {
132015
+ if (!text3.length) return null;
132016
+ const m = this.re.get_schema_at_start().exec(text3);
131934
132017
  if (!m) return null;
131935
- const len = this.testSchemaAt(text2, m[2], m[0].length);
132018
+ const len = this.testSchemaAt(text3, m[2], m[0].length);
131936
132019
  if (!len) return null;
131937
- const match = new Match(text2, m[2], m.index + m[1].length, m.index + m[0].length + len);
132020
+ const match = new Match(text3, m[2], m.index + m[1].length, m.index + m[0].length + len);
131938
132021
  this.__schemas__[match.schema].normalize(match, this);
131939
132022
  return match;
131940
132023
  }
@@ -132914,8 +132997,8 @@ function linkify$1(state) {
132914
132997
  }
132915
132998
  if (htmlLinkLevel > 0) continue;
132916
132999
  if (currentToken.type === "text" && state.md.linkify.test(currentToken.content)) {
132917
- const text2 = currentToken.content;
132918
- let links = state.md.linkify.match(text2);
133000
+ const text3 = currentToken.content;
133001
+ let links = state.md.linkify.match(text3);
132919
133002
  const nodes = [];
132920
133003
  let level = currentToken.level;
132921
133004
  let lastPos = 0;
@@ -132931,7 +133014,7 @@ function linkify$1(state) {
132931
133014
  const pos = links[ln].index;
132932
133015
  if (pos > lastPos) {
132933
133016
  const token = new state.Token("text", "", 0);
132934
- token.content = text2.slice(lastPos, pos);
133017
+ token.content = text3.slice(lastPos, pos);
132935
133018
  token.level = level;
132936
133019
  nodes.push(token);
132937
133020
  }
@@ -132952,9 +133035,9 @@ function linkify$1(state) {
132952
133035
  nodes.push(token_c);
132953
133036
  lastPos = links[ln].lastIndex;
132954
133037
  }
132955
- if (lastPos < text2.length) {
133038
+ if (lastPos < text3.length) {
132956
133039
  const token = new state.Token("text", "", 0);
132957
- token.content = text2.slice(lastPos);
133040
+ token.content = text3.slice(lastPos);
132958
133041
  token.level = level;
132959
133042
  nodes.push(token);
132960
133043
  }
@@ -133065,19 +133148,19 @@ function process_inlines(tokens, state) {
133065
133148
  for (j = stack.length - 1; j >= 0; j--) if (stack[j].level <= thisLevel) break;
133066
133149
  truncateStack(stack, heads, j + 1);
133067
133150
  if (token.type !== "text") continue;
133068
- const text2 = token.content;
133151
+ const text3 = token.content;
133069
133152
  let pos = 0;
133070
- const max = text2.length;
133153
+ const max = text3.length;
133071
133154
  OUTER: while (pos < max) {
133072
133155
  QUOTE_RE.lastIndex = pos;
133073
- const t = QUOTE_RE.exec(text2);
133156
+ const t = QUOTE_RE.exec(text3);
133074
133157
  if (!t) break;
133075
133158
  let canOpen = true;
133076
133159
  let canClose = true;
133077
133160
  pos = t.index + 1;
133078
133161
  const isSingle = t[0] === "'";
133079
133162
  let lastChar = 32;
133080
- if (t.index - 1 >= 0) lastChar = text2.charCodeAt(t.index - 1);
133163
+ if (t.index - 1 >= 0) lastChar = text3.charCodeAt(t.index - 1);
133081
133164
  else for (j = i - 1; j >= 0; j--) {
133082
133165
  if (tokens[j].type === "softbreak" || tokens[j].type === "hardbreak") break;
133083
133166
  if (!tokens[j].content) continue;
@@ -133085,7 +133168,7 @@ function process_inlines(tokens, state) {
133085
133168
  break;
133086
133169
  }
133087
133170
  let nextChar = 32;
133088
- if (pos < max) nextChar = text2.charCodeAt(pos);
133171
+ if (pos < max) nextChar = text3.charCodeAt(pos);
133089
133172
  else for (j = i + 1; j < tokens.length; j++) {
133090
133173
  if (tokens[j].type === "softbreak" || tokens[j].type === "hardbreak") break;
133091
133174
  if (!tokens[j].content) continue;
@@ -134420,7 +134503,7 @@ function isTerminatorChar(ch) {
134420
134503
  return false;
134421
134504
  }
134422
134505
  }
134423
- function text(state, silent) {
134506
+ function text2(state, silent) {
134424
134507
  let pos = state.pos;
134425
134508
  while (pos < state.posMax && !isTerminatorChar(state.src.charCodeAt(pos))) pos++;
134426
134509
  if (pos === state.pos) return false;
@@ -135094,7 +135177,7 @@ function fragments_join(state) {
135094
135177
  if (curr !== last) tokens.length = last;
135095
135178
  }
135096
135179
  var _rules = [
135097
- ["text", text],
135180
+ ["text", text2],
135098
135181
  ["linkify", linkify],
135099
135182
  ["newline", newline],
135100
135183
  ["escape", escape2],
@@ -135730,8 +135813,8 @@ var markdownToElements = (input) => {
135730
135813
  const buffer = [];
135731
135814
  let tableCount = 0;
135732
135815
  const flushBuffer = () => {
135733
- const text2 = buffer.join("\n\n").replace(/\n{3,}/g, "\n\n").trim();
135734
- if (text2 !== "") elements.push({ tag: "markdown", content: text2 });
135816
+ const text3 = buffer.join("\n\n").replace(/\n{3,}/g, "\n\n").trim();
135817
+ if (text3 !== "") elements.push({ tag: "markdown", content: text3 });
135735
135818
  buffer.length = 0;
135736
135819
  };
135737
135820
  let index = 0;
@@ -135743,8 +135826,8 @@ var markdownToElements = (input) => {
135743
135826
  continue;
135744
135827
  }
135745
135828
  if (token.type === "heading_open") {
135746
- const text2 = (tokens[index + 1]?.content ?? "").replace(/^#{1,6}\s+/, "").trim();
135747
- if (text2 !== "") buffer.push(`**${text2}**`);
135829
+ const text3 = (tokens[index + 1]?.content ?? "").replace(/^#{1,6}\s+/, "").trim();
135830
+ if (text3 !== "") buffer.push(`**${text3}**`);
135748
135831
  index += 3;
135749
135832
  continue;
135750
135833
  }
@@ -135805,23 +135888,23 @@ var STATUS_TEMPLATE = {
135805
135888
  interrupted: "orange"
135806
135889
  };
135807
135890
  var encoder = new TextEncoder();
135808
- var stripAngleBrackets = (text2) => text2.replaceAll("<", "").replaceAll(">", "");
135809
- var truncateTail = (text2, t, maxBytes = MAX_CARD_BODY_BYTES) => {
135810
- if (encoder.encode(text2).length <= maxBytes) return text2;
135891
+ var stripAngleBrackets = (text3) => text3.replaceAll("<", "").replaceAll(">", "");
135892
+ var truncateTail = (text3, t, maxBytes = MAX_CARD_BODY_BYTES) => {
135893
+ if (encoder.encode(text3).length <= maxBytes) return text3;
135811
135894
  const marker = `${t("card.truncated", { count: 9999999 })}
135812
135895
  `;
135813
135896
  const budget = maxBytes - encoder.encode(marker).length;
135814
135897
  if (budget < 1) return "";
135815
135898
  const kept = [];
135816
135899
  let used = 0;
135817
- for (const char of Array.from(text2).toReversed()) {
135900
+ for (const char of Array.from(text3).toReversed()) {
135818
135901
  const size = encoder.encode(char).length;
135819
135902
  if (used + size > budget) break;
135820
135903
  used += size;
135821
135904
  kept.push(char);
135822
135905
  }
135823
135906
  const tail = kept.toReversed().join("");
135824
- const dropped = Array.from(text2).length - kept.length;
135907
+ const dropped = Array.from(text3).length - kept.length;
135825
135908
  return `${t("card.truncated", { count: dropped })}
135826
135909
  ${tail}`;
135827
135910
  };
@@ -135978,8 +136061,8 @@ var buildChoiceCard = (card) => {
135978
136061
  var import_node_sdk = __toESM(require_lib2(), 1);
135979
136062
 
135980
136063
  // src/larkPost.ts
135981
- var styledText = (text2, style) => {
135982
- let out = text2;
136064
+ var styledText = (text3, style) => {
136065
+ let out = text3;
135983
136066
  if (style?.includes("bold")) out = `**${out}**`;
135984
136067
  if (style?.includes("italic")) out = `*${out}*`;
135985
136068
  if (style?.includes("lineThrough")) out = `~~${out}~~`;
@@ -136063,18 +136146,18 @@ var serializePost = (content, botIds = /* @__PURE__ */ new Set()) => {
136063
136146
  placeholderByKey.set(key, placeholderOf(element, index));
136064
136147
  }
136065
136148
  }
136066
- const text3 = md2.replace(
136149
+ const text4 = md2.replace(
136067
136150
  /!\[(?:img|video|file)\]\(([^)]+)\)/g,
136068
136151
  (whole, rawKey) => placeholderByKey.get(rawKey.trim()) ?? whole
136069
136152
  );
136070
- return { text: text3, resources };
136153
+ return { text: text4, resources };
136071
136154
  }
136072
136155
  const paragraphs = (parsed.content ?? []).map(
136073
136156
  (row) => row.map((element) => serializeElement(element, indexOf.get(element) ?? null, botIds)).join("")
136074
136157
  );
136075
- const text2 = paragraphs.map((line) => line.trim()).filter((line) => line !== "").join("\n");
136076
- if (text2 === "" && resources.length === 0) return void 0;
136077
- return { text: text2, resources };
136158
+ const text3 = paragraphs.map((line) => line.trim()).filter((line) => line !== "").join("\n");
136159
+ if (text3 === "" && resources.length === 0) return void 0;
136160
+ return { text: text3, resources };
136078
136161
  };
136079
136162
 
136080
136163
  // src/larkInbound.ts
@@ -136147,8 +136230,8 @@ var readResource = (messageType, content) => {
136147
136230
  return null;
136148
136231
  };
136149
136232
  var readText = (content) => {
136150
- const text2 = readJson(content)?.["text"];
136151
- return typeof text2 === "string" ? text2 : null;
136233
+ const text3 = readJson(content)?.["text"];
136234
+ return typeof text3 === "string" ? text3 : null;
136152
136235
  };
136153
136236
  var parseInboundMessage = (event, appId, groupMention = "always") => {
136154
136237
  if (event.sender?.sender_type === "app") return null;
@@ -136176,9 +136259,9 @@ var parseInboundMessage = (event, appId, groupMention = "always") => {
136176
136259
  const single = post === void 0 ? readResource(messageType, message.content) : null;
136177
136260
  const resources = post !== void 0 ? post.resources : single === null ? [] : [single];
136178
136261
  const raw = post !== void 0 ? post.text : messageType === "text" ? readText(message.content) : null;
136179
- const text2 = mentions.reduce((value, mention) => value.replaceAll(mention.key, ""), raw ?? "").trim();
136180
- if (text2.length === 0 && resources.length === 0) return null;
136181
- return { messageId, chatId, chatType, senderOpenId, text: text2, resources };
136262
+ const text3 = mentions.reduce((value, mention) => value.replaceAll(mention.key, ""), raw ?? "").trim();
136263
+ if (text3.length === 0 && resources.length === 0) return null;
136264
+ return { messageId, chatId, chatType, senderOpenId, text: text3, resources };
136182
136265
  };
136183
136266
  var fetchMessageResource = async (input) => {
136184
136267
  const url = `${LARK_BASE}/im/v1/messages/${encodeURIComponent(
@@ -136403,9 +136486,9 @@ var makeLarkAdapter = (deps) => {
136403
136486
  name: input.name,
136404
136487
  memberOpenIds: input.memberIds
136405
136488
  }),
136406
- sendText: async (binding, text2) => {
136489
+ sendText: async (binding, text3) => {
136407
136490
  const token = await tenantToken(binding);
136408
- for (const chunk of splitForLark(text2)) {
136491
+ for (const chunk of splitForLark(text3)) {
136409
136492
  const messageId = await sendChatText({
136410
136493
  http: deps.http,
136411
136494
  token,
@@ -136547,7 +136630,7 @@ var makeLarkAdapter = (deps) => {
136547
136630
  var en_default = {
136548
136631
  settings: {
136549
136632
  title: "Chat",
136550
- description: "Connect chat bots to Ycodium. One row per bot: create the bot on its platform, paste its credentials, and list the people allowed to use it. Those people message the bot (or add it to a group), pick a project in the chat, and can start work.",
136633
+ description: "Connect chat bots to Ycodium. One row per bot: create the bot on its platform, paste its credentials, and list the people allowed to use it. For Lark, Connect a Lark bot above does all of that with one scan. Those people message the bot (or add it to a group), pick a project in the chat, and can start work.",
136551
136634
  bots: "Bots",
136552
136635
  language: {
136553
136636
  label: "Reply language",
@@ -136858,10 +136941,10 @@ var en_default = {
136858
136941
  },
136859
136942
  setup: {
136860
136943
  action: {
136861
- label: "Set up with one scan",
136862
- description: "Scan with the Feishu app. Ycodium creates a bot app under your account, publishes it, and fills in the App ID and App secret on this row.",
136944
+ label: "Connect a Lark bot",
136945
+ description: "Scan once with the Lark app. Ycodium creates a bot app under your account, publishes it for you only, and adds the bot to the list below with its credentials saved. Nothing to fill in.",
136863
136946
  badge: "Beta",
136864
- warning: "This uses Feishu developer console interfaces that are not public, so it may stop working. If it does, set the app up by hand in the developer console."
136947
+ warning: "This relies on Lark developer console interfaces that are not public, so it may stop working. If it does, set the app up by hand in the developer console."
136865
136948
  },
136866
136949
  manual: {
136867
136950
  createApp: {
@@ -136885,8 +136968,8 @@ var en_default = {
136885
136968
  body: 'Create a version and publish it. Choose "visible to me only" so it is approved at once, without waiting for an administrator.'
136886
136969
  },
136887
136970
  fillRow: {
136888
- title: "Fill in the row",
136889
- body: "Paste the App ID and App secret into this bot's row on the Chat card and save."
136971
+ title: "Add the bot",
136972
+ body: "On the Chat card, add a bot: choose Lark, paste the App ID and App secret, put your own Lark user id in Allowed people (message the bot and it tells you your id), then save."
136890
136973
  }
136891
136974
  },
136892
136975
  status: {
@@ -136907,8 +136990,22 @@ var en_default = {
136907
136990
  publish: "Publish a version",
136908
136991
  secret: "Read the App secret"
136909
136992
  },
136910
- done: "Done. The App ID and App secret are filled in. Save to start the connection, then message the bot and pick a project in the chat.",
136993
+ progress: {
136994
+ login: "Signing in ({{n}}/{{total}})",
136995
+ identity: "Reading your account ({{n}}/{{total}})",
136996
+ findApp: "Looking for an app from an earlier try ({{n}}/{{total}})",
136997
+ createApp: "Creating the app ({{n}}/{{total}})",
136998
+ enableBot: "Turning on the bot ({{n}}/{{total}})",
136999
+ longConnection: "Switching events and callbacks to the long connection ({{n}}/{{total}})",
137000
+ scopes: "Adding permissions ({{n}}/{{total}})",
137001
+ events: "Subscribing to events ({{n}}/{{total}})",
137002
+ callbacks: "Subscribing to card callbacks ({{n}}/{{total}})",
137003
+ publish: "Publishing a version ({{n}}/{{total}})",
137004
+ secret: "Reading the App secret ({{n}}/{{total}})"
137005
+ },
137006
+ done: "Connected and saved. Message the bot in Lark to try it, then pick a project in the chat.",
136911
137007
  warn: {
137008
+ senderUnknown: "Could not read your Lark user id, so this bot's Allowed people list is empty and nobody can use it yet. Message the bot: it replies with your id. Put that id in Allowed people on the bot's row and save.",
136912
137009
  scopesMissing: "These permissions could not be added automatically: {{names}}. Add them in the developer console."
136913
137010
  },
136914
137011
  failure: {
@@ -136920,12 +137017,13 @@ var en_default = {
136920
137017
  consoleRejected: "The developer console turned the request down. Follow the manual steps, or try again later.",
136921
137018
  ownerDenied: "This account is not the owner of that app, so it cannot change it. Scan with the account that created it, or follow the manual steps.",
136922
137019
  verificationFailed: "The console did not keep the event settings, so the bot would receive nothing. Nothing was published. Follow the manual steps.",
136923
- publishNeedsManual: "The app is set up but its version could not be published. Publish it in the developer console, then paste the App ID and App secret here.",
137020
+ publishNeedsManual: "The app is set up but its version could not be published. Publish it in the developer console, then add the bot here by hand with its App ID and App secret.",
136924
137021
  busy: "Another setup is already running on this machine.",
136925
137022
  unknown: "Setup stopped on an unexpected error. Try again, or follow the manual steps.",
136926
137023
  createUnknown: "The console did not confirm whether the app was created. Try again: an app made by an earlier try is found and reused.",
136927
137024
  secretMissing: "The app {{appId}} is published, but its App secret could not be read. Copy it from Credentials & Basic Info in the developer console.",
136928
- stopped: "Setup was stopped."
137025
+ stopped: "Setup was stopped.",
137026
+ saveFailed: "The app {{appId}} is set up and published, but the bot could not be saved here. Add it by hand: choose Lark, paste the App ID and the App secret from Credentials & Basic Info, and fill in Allowed people."
136929
137027
  }
136930
137028
  },
136931
137029
  repo: {
@@ -136953,7 +137051,7 @@ var en_default = {
136953
137051
  var zh_CN_default = {
136954
137052
  settings: {
136955
137053
  title: "\u804A\u5929",
136956
- description: "\u628A\u804A\u5929\u673A\u5668\u4EBA\u63A5\u5230 Ycodium\u3002\u4E00\u884C\u4E00\u4E2A\u673A\u5668\u4EBA\uFF1A\u5148\u5728\u5BF9\u5E94\u5E73\u53F0\u5EFA\u597D\u673A\u5668\u4EBA\u3001\u628A\u51ED\u636E\u586B\u8FDB\u6765\uFF0C\u518D\u628A\u5141\u8BB8\u4F7F\u7528\u5B83\u7684\u4EBA\u586B\u8FDB\u300C\u5141\u8BB8\u7684\u4EBA\u300D\u3002\u540D\u5355\u91CC\u7684\u4EBA\u79C1\u804A\u673A\u5668\u4EBA\uFF08\u6216\u628A\u5B83\u62C9\u8FDB\u7FA4\uFF09\u3001\u5728\u804A\u5929\u91CC\u9009\u597D\u9879\u76EE\uFF0C\u5C31\u80FD\u6D3E\u6D3B\u3002",
137054
+ description: "\u628A\u804A\u5929\u673A\u5668\u4EBA\u63A5\u5230 Ycodium\u3002\u4E00\u884C\u4E00\u4E2A\u673A\u5668\u4EBA\uFF1A\u5148\u5728\u5BF9\u5E94\u5E73\u53F0\u5EFA\u597D\u673A\u5668\u4EBA\u3001\u628A\u51ED\u636E\u586B\u8FDB\u6765\uFF0C\u518D\u628A\u5141\u8BB8\u4F7F\u7528\u5B83\u7684\u4EBA\u586B\u8FDB\u300C\u5141\u8BB8\u7684\u4EBA\u300D\u3002\u98DE\u4E66\u53EF\u4EE5\u7528\u4E0A\u9762\u7684\u300C\u8FDE\u63A5\u98DE\u4E66\u673A\u5668\u4EBA\u300D\uFF0C\u626B\u4E00\u6B21\u7801\u5168\u90E8\u914D\u597D\u3002\u540D\u5355\u91CC\u7684\u4EBA\u79C1\u804A\u673A\u5668\u4EBA\uFF08\u6216\u628A\u5B83\u62C9\u8FDB\u7FA4\uFF09\u3001\u5728\u804A\u5929\u91CC\u9009\u597D\u9879\u76EE\uFF0C\u5C31\u80FD\u6D3E\u6D3B\u3002",
136957
137055
  bots: "\u673A\u5668\u4EBA",
136958
137056
  language: {
136959
137057
  label: "\u56DE\u8BDD\u8BED\u8A00",
@@ -137264,10 +137362,10 @@ var zh_CN_default = {
137264
137362
  },
137265
137363
  setup: {
137266
137364
  action: {
137267
- label: "\u626B\u7801\u4E00\u952E\u914D\u7F6E",
137268
- description: "\u7528\u98DE\u4E66 App \u626B\u7801\u3002Ycodium \u4F1A\u5728\u4F60\u7684\u8D26\u53F7\u4E0B\u5EFA\u4E00\u4E2A\u673A\u5668\u4EBA\u5E94\u7528\u5E76\u53D1\u5E03\uFF0C\u518D\u628A App ID \u4E0E App Secret \u586B\u8FDB\u8FD9\u4E00\u884C\u3002",
137365
+ label: "\u8FDE\u63A5\u98DE\u4E66\u673A\u5668\u4EBA",
137366
+ description: "\u7528\u98DE\u4E66 App \u626B\u4E00\u6B21\u7801\u3002Ycodium \u4F1A\u5728\u4F60\u7684\u8D26\u53F7\u4E0B\u5EFA\u597D\u673A\u5668\u4EBA\u5E94\u7528\uFF0C\u53D1\u5E03\u4E3A\u4EC5\u81EA\u5DF1\u53EF\u89C1\uFF0C\u5E76\u628A\u8FD9\u4E2A\u673A\u5668\u4EBA\u8FDE\u540C\u51ED\u636E\u76F4\u63A5\u5B58\u8FDB\u4E0B\u9762\u7684\u5217\u8868\uFF0C\u4E0D\u7528\u624B\u586B\u3002",
137269
137367
  badge: "\u6D4B\u8BD5\u7248",
137270
- warning: "\u8FD9\u4E2A\u529F\u80FD\u7528\u7684\u662F\u98DE\u4E66\u5F00\u53D1\u8005\u540E\u53F0\u7684\u975E\u516C\u5F00\u63A5\u53E3\uFF0C\u53EF\u80FD\u4F1A\u5931\u6548\u3002\u5931\u6548\u65F6\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u624B\u52A8\u914D\u7F6E\u5E94\u7528\u3002"
137368
+ warning: "\u8FD9\u4E2A\u529F\u80FD\u4F9D\u8D56\u98DE\u4E66\u5F00\u53D1\u8005\u540E\u53F0\u7684\u975E\u516C\u5F00\u63A5\u53E3\uFF0C\u53EF\u80FD\u4F1A\u5931\u6548\u3002\u5931\u6548\u65F6\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u624B\u52A8\u914D\u7F6E\u5E94\u7528\u3002"
137271
137369
  },
137272
137370
  manual: {
137273
137371
  createApp: {
@@ -137291,8 +137389,8 @@ var zh_CN_default = {
137291
137389
  body: "\u521B\u5EFA\u4E00\u4E2A\u7248\u672C\u5E76\u53D1\u5E03\u3002\u53EF\u89C1\u8303\u56F4\u9009\u300C\u4EC5\u81EA\u5DF1\u53EF\u89C1\u300D\uFF0C\u8FD9\u6837\u4F1A\u7ACB\u5373\u901A\u8FC7\u5BA1\u6279\uFF0C\u4E0D\u7528\u7B49\u7BA1\u7406\u5458\u3002"
137292
137390
  },
137293
137391
  fillRow: {
137294
- title: "\u586B\u8FDB\u8FD9\u4E00\u884C",
137295
- body: "\u628A App ID \u4E0E App Secret \u586B\u8FDB\u804A\u5929\u5361\u91CC\u8FD9\u4E2A\u673A\u5668\u4EBA\u7684\u90A3\u4E00\u884C\uFF0C\u4FDD\u5B58\u3002"
137392
+ title: "\u6DFB\u52A0\u673A\u5668\u4EBA",
137393
+ body: "\u5728\u804A\u5929\u5361\u91CC\u6DFB\u52A0\u4E00\u4E2A\u673A\u5668\u4EBA\uFF1A\u5E73\u53F0\u9009\u98DE\u4E66\uFF0C\u586B\u5165 App ID \u4E0E App Secret\uFF0C\u628A\u4F60\u81EA\u5DF1\u7684\u98DE\u4E66\u7528\u6237 id \u586B\u8FDB\u300C\u5141\u8BB8\u7684\u4EBA\u300D\uFF08\u7ED9\u673A\u5668\u4EBA\u53D1\u4E00\u6761\u6D88\u606F\uFF0C\u5B83\u4F1A\u544A\u8BC9\u4F60\uFF09\uFF0C\u7136\u540E\u4FDD\u5B58\u3002"
137296
137394
  }
137297
137395
  },
137298
137396
  status: {
@@ -137313,8 +137411,22 @@ var zh_CN_default = {
137313
137411
  publish: "\u53D1\u5E03\u7248\u672C",
137314
137412
  secret: "\u8BFB\u53D6 App Secret"
137315
137413
  },
137316
- done: "\u5B8C\u6210\u3002App ID \u4E0E App Secret \u5DF2\u586B\u597D\u3002\u70B9\u4FDD\u5B58\u540E\u8FDE\u63A5\u624D\u4F1A\u5F00\u59CB\uFF0C\u63A5\u7740\u7ED9\u673A\u5668\u4EBA\u53D1\u4E00\u53E5\u8BDD\uFF0C\u5728\u804A\u5929\u91CC\u9009\u9879\u76EE\u3002",
137414
+ progress: {
137415
+ login: "\u6B63\u5728\u767B\u5F55\uFF08{{n}}/{{total}}\uFF09",
137416
+ identity: "\u6B63\u5728\u8BFB\u53D6\u8D26\u53F7\u4FE1\u606F\uFF08{{n}}/{{total}}\uFF09",
137417
+ findApp: "\u6B63\u5728\u67E5\u627E\u4E4B\u524D\u5C1D\u8BD5\u65F6\u5EFA\u7684\u5E94\u7528\uFF08{{n}}/{{total}}\uFF09",
137418
+ createApp: "\u6B63\u5728\u521B\u5EFA\u5E94\u7528\uFF08{{n}}/{{total}}\uFF09",
137419
+ enableBot: "\u6B63\u5728\u5F00\u542F\u673A\u5668\u4EBA\uFF08{{n}}/{{total}}\uFF09",
137420
+ longConnection: "\u6B63\u5728\u628A\u4E8B\u4EF6\u4E0E\u56DE\u8C03\u5207\u6362\u4E3A\u957F\u8FDE\u63A5\uFF08{{n}}/{{total}}\uFF09",
137421
+ scopes: "\u6B63\u5728\u6DFB\u52A0\u6743\u9650\uFF08{{n}}/{{total}}\uFF09",
137422
+ events: "\u6B63\u5728\u8BA2\u9605\u4E8B\u4EF6\uFF08{{n}}/{{total}}\uFF09",
137423
+ callbacks: "\u6B63\u5728\u8BA2\u9605\u5361\u7247\u56DE\u8C03\uFF08{{n}}/{{total}}\uFF09",
137424
+ publish: "\u6B63\u5728\u53D1\u5E03\u7248\u672C\uFF08{{n}}/{{total}}\uFF09",
137425
+ secret: "\u6B63\u5728\u8BFB\u53D6 App Secret\uFF08{{n}}/{{total}}\uFF09"
137426
+ },
137427
+ done: "\u5DF2\u8FDE\u63A5\u5E76\u4FDD\u5B58\u3002\u53BB\u98DE\u4E66\u91CC\u7ED9\u673A\u5668\u4EBA\u53D1\u4E00\u6761\u6D88\u606F\u8BD5\u8BD5\uFF0C\u518D\u5728\u804A\u5929\u91CC\u9009\u9879\u76EE\u3002",
137317
137428
  warn: {
137429
+ senderUnknown: "\u6CA1\u80FD\u8BFB\u5230\u4F60\u7684\u98DE\u4E66\u7528\u6237 id\uFF0C\u6240\u4EE5\u8FD9\u4E2A\u673A\u5668\u4EBA\u7684\u300C\u5141\u8BB8\u7684\u4EBA\u300D\u662F\u7A7A\u7684\uFF0C\u6682\u65F6\u8C01\u4E5F\u7528\u4E0D\u4E86\u3002\u7ED9\u673A\u5668\u4EBA\u53D1\u4E00\u6761\u6D88\u606F\uFF0C\u5B83\u4F1A\u56DE\u4F60\u7684 id\uFF1B\u628A\u5B83\u586B\u8FDB\u8FD9\u4E2A\u673A\u5668\u4EBA\u90A3\u4E00\u884C\u7684\u300C\u5141\u8BB8\u7684\u4EBA\u300D\uFF0C\u518D\u4FDD\u5B58\u3002",
137318
137430
  scopesMissing: "\u8FD9\u4E9B\u6743\u9650\u6CA1\u80FD\u81EA\u52A8\u6DFB\u52A0\uFF1A{{names}}\u3002\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u624B\u52A8\u6DFB\u52A0\u3002"
137319
137431
  },
137320
137432
  failure: {
@@ -137326,12 +137438,13 @@ var zh_CN_default = {
137326
137438
  consoleRejected: "\u5F00\u53D1\u8005\u540E\u53F0\u62D2\u7EDD\u4E86\u8FD9\u6B21\u8BF7\u6C42\u3002\u8BF7\u6309\u624B\u52A8\u6B65\u9AA4\u914D\u7F6E\uFF0C\u6216\u7A0D\u540E\u518D\u8BD5\u3002",
137327
137439
  ownerDenied: "\u8FD9\u4E2A\u8D26\u53F7\u4E0D\u662F\u8BE5\u5E94\u7528\u7684\u6240\u6709\u8005\uFF0C\u65E0\u6CD5\u4FEE\u6539\u5B83\u3002\u8BF7\u7528\u521B\u5EFA\u8BE5\u5E94\u7528\u7684\u8D26\u53F7\u626B\u7801\uFF0C\u6216\u6309\u624B\u52A8\u6B65\u9AA4\u914D\u7F6E\u3002",
137328
137440
  verificationFailed: "\u540E\u53F0\u6CA1\u6709\u4FDD\u5B58\u4E8B\u4EF6\u914D\u7F6E\uFF0C\u673A\u5668\u4EBA\u4F1A\u6536\u4E0D\u5230\u4EFB\u4F55\u6D88\u606F\uFF0C\u6240\u4EE5\u6CA1\u6709\u53D1\u5E03\u3002\u8BF7\u6309\u624B\u52A8\u6B65\u9AA4\u914D\u7F6E\u3002",
137329
- publishNeedsManual: "\u5E94\u7528\u5DF2\u914D\u7F6E\u597D\uFF0C\u4F46\u7248\u672C\u6CA1\u80FD\u53D1\u5E03\u3002\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u624B\u52A8\u53D1\u5E03\uFF0C\u518D\u628A App ID \u4E0E App Secret \u586B\u5230\u8FD9\u91CC\u3002",
137441
+ publishNeedsManual: "\u5E94\u7528\u5DF2\u914D\u7F6E\u597D\uFF0C\u4F46\u7248\u672C\u6CA1\u80FD\u53D1\u5E03\u3002\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u624B\u52A8\u53D1\u5E03\uFF0C\u518D\u5728\u8FD9\u91CC\u624B\u52A8\u6DFB\u52A0\u8FD9\u4E2A\u673A\u5668\u4EBA\uFF0C\u586B\u5165 App ID \u4E0E App Secret\u3002",
137330
137442
  busy: "\u8FD9\u53F0\u673A\u5668\u4E0A\u5DF2\u7ECF\u6709\u4E00\u6B21\u914D\u7F6E\u5728\u8FDB\u884C\u3002",
137331
137443
  unknown: "\u914D\u7F6E\u56E0\u4E3A\u610F\u5916\u9519\u8BEF\u4E2D\u65AD\u3002\u8BF7\u91CD\u8BD5\uFF0C\u6216\u6309\u624B\u52A8\u6B65\u9AA4\u914D\u7F6E\u3002",
137332
137444
  createUnknown: "\u540E\u53F0\u6CA1\u6709\u786E\u8BA4\u5E94\u7528\u662F\u5426\u5DF2\u521B\u5EFA\u3002\u8BF7\u91CD\u8BD5\uFF1A\u4E4B\u524D\u90A3\u6B21\u5EFA\u51FA\u7684\u5E94\u7528\u4F1A\u88AB\u627E\u56DE\u5E76\u590D\u7528\u3002",
137333
137445
  secretMissing: "\u5E94\u7528 {{appId}} \u5DF2\u53D1\u5E03\uFF0C\u4F46\u8BFB\u4E0D\u5230\u5B83\u7684 App Secret\u3002\u8BF7\u5230\u5F00\u53D1\u8005\u540E\u53F0\u300C\u51ED\u8BC1\u4E0E\u57FA\u7840\u4FE1\u606F\u300D\u91CC\u590D\u5236\u3002",
137334
- stopped: "\u914D\u7F6E\u88AB\u4E2D\u6B62\u4E86\u3002"
137446
+ stopped: "\u914D\u7F6E\u88AB\u4E2D\u6B62\u4E86\u3002",
137447
+ saveFailed: "\u5E94\u7528 {{appId}} \u5DF2\u914D\u7F6E\u5E76\u53D1\u5E03\uFF0C\u4F46\u673A\u5668\u4EBA\u6CA1\u80FD\u5B58\u5230\u8FD9\u91CC\u3002\u8BF7\u624B\u52A8\u6DFB\u52A0\uFF1A\u5E73\u53F0\u9009\u98DE\u4E66\uFF0C\u586B\u5165 App ID \u4E0E\u5F00\u53D1\u8005\u540E\u53F0\u300C\u51ED\u8BC1\u4E0E\u57FA\u7840\u4FE1\u606F\u300D\u91CC\u7684 App Secret\uFF0C\u518D\u586B\u300C\u5141\u8BB8\u7684\u4EBA\u300D\u3002"
137335
137448
  }
137336
137449
  },
137337
137450
  repo: {
@@ -137374,8 +137487,8 @@ var interpolate = (template, params) => params === void 0 ? template : template.
137374
137487
  var makeTranslate = (language) => {
137375
137488
  const catalog = CATALOGS[language];
137376
137489
  const optional = (key, params) => {
137377
- const text2 = lookup(catalog, key);
137378
- return text2 === void 0 ? void 0 : interpolate(text2, params);
137490
+ const text3 = lookup(catalog, key);
137491
+ return text3 === void 0 ? void 0 : interpolate(text3, params);
137379
137492
  };
137380
137493
  return Object.assign(
137381
137494
  (key, params) => optional(key, params) ?? key,
@@ -137511,10 +137624,10 @@ var makeNotifications = (core, deps) => {
137511
137624
  const final = thread?.messages.toReversed().find((message) => message.role === "assistant" && message.text.trim() !== "");
137512
137625
  if (thread !== null && final !== void 0) {
137513
137626
  for (const binding of reporters) {
137514
- const text2 = streamsTo(binding, threadId) ? "" : `${thread.title}
137627
+ const text3 = streamsTo(binding, threadId) ? "" : `${thread.title}
137515
137628
 
137516
137629
  ${final.text}`;
137517
- await deliver(binding, text2, final.attachments);
137630
+ await deliver(binding, text3, final.attachments);
137518
137631
  }
137519
137632
  }
137520
137633
  }
@@ -137728,10 +137841,10 @@ var makePanelController = (deps) => {
137728
137841
  action: { op, arg },
137729
137842
  ...danger === true ? { danger } : {}
137730
137843
  });
137731
- const busyCard = (title, text2) => ({
137844
+ const busyCard = (title, text3) => ({
137732
137845
  title,
137733
137846
  tone: "busy",
137734
- text: text2,
137847
+ text: text3,
137735
137848
  groups: [],
137736
137849
  nav: []
137737
137850
  });
@@ -137868,9 +137981,9 @@ ${t("panel.projects.hint")}`;
137868
137981
  }
137869
137982
  }
137870
137983
  });
137871
- const placeholder = (entry, title, text2) => {
137984
+ const placeholder = (entry, title, text3) => {
137872
137985
  void post(entry.cardId, async () => {
137873
- await deps.surface(entry.chatKey)?.update(entry.cardId, busyCard(title, text2));
137986
+ await deps.surface(entry.chatKey)?.update(entry.cardId, busyCard(title, text3));
137874
137987
  });
137875
137988
  };
137876
137989
  const loadView = async (chatKey, kind) => {
@@ -138156,8 +138269,8 @@ var STEP_KIND_BY_ITEM_TYPE = {
138156
138269
  };
138157
138270
  var stepKindOf = (itemType) => STEP_KIND_BY_ITEM_TYPE[itemType] ?? "tool";
138158
138271
  var TURN_TITLE_MAX_CHARS = 40;
138159
- var turnTitleOf = (text2) => {
138160
- const oneLine = text2.replace(/\s+/g, " ").trim();
138272
+ var turnTitleOf = (text3) => {
138273
+ const oneLine = text3.replace(/\s+/g, " ").trim();
138161
138274
  return oneLine.length <= TURN_TITLE_MAX_CHARS ? oneLine : `${oneLine.slice(0, TURN_TITLE_MAX_CHARS)}\u2026`;
138162
138275
  };
138163
138276
  var buildTurnView = (input) => {
@@ -138165,7 +138278,7 @@ var buildTurnView = (input) => {
138165
138278
  const steps = [];
138166
138279
  if (progress.thinking.active || progress.thinking.chars > 0) steps.push("think");
138167
138280
  for (const tool of progress.tools) steps.push(stepKindOf(tool.itemType));
138168
- const body = progress.segments.map((segment) => input.texts.get(segment.messageId) ?? "").filter((text2) => text2.trim() !== "").join("\n\n");
138281
+ const body = progress.segments.map((segment) => input.texts.get(segment.messageId) ?? "").filter((text3) => text3.trim() !== "").join("\n\n");
138169
138282
  const runningTool = progress.tools.findLast((tool) => tool.status === "running");
138170
138283
  const running = input.status === "working" && runningTool !== void 0 && runningTool.label !== "" ? runningTool.label : null;
138171
138284
  return {
@@ -138216,9 +138329,9 @@ var makeTurnCards = (deps) => {
138216
138329
  texts.set(segment.messageId, known);
138217
138330
  continue;
138218
138331
  }
138219
- const text2 = await deps.readText(segment.messageId) ?? "";
138220
- texts.set(segment.messageId, text2);
138221
- if (!segment.streaming) live?.settledTexts.set(segment.messageId, text2);
138332
+ const text3 = await deps.readText(segment.messageId) ?? "";
138333
+ texts.set(segment.messageId, text3);
138334
+ if (!segment.streaming) live?.settledTexts.set(segment.messageId, text3);
138222
138335
  }
138223
138336
  return texts;
138224
138337
  };
@@ -138413,8 +138526,8 @@ var makeReplyCards = (core) => {
138413
138526
  fallback: async (_threadId, chatKey, view) => {
138414
138527
  const binding = bindingForChatKey(chatKey);
138415
138528
  if (binding === void 0) return;
138416
- const text2 = [view.body, view.errorText ?? ""].filter((part) => part !== "").join("\n\n");
138417
- await deliver(binding, text2);
138529
+ const text3 = [view.body, view.errorText ?? ""].filter((part) => part !== "").join("\n\n");
138530
+ await deliver(binding, text3);
138418
138531
  },
138419
138532
  schedule: (run, delayMs) => {
138420
138533
  const timer = setTimeout(run, delayMs);
@@ -138458,8 +138571,8 @@ var makeReplyCards = (core) => {
138458
138571
  };
138459
138572
 
138460
138573
  // src/sendFile.ts
138461
- var failure = (code2, text2) => ({
138462
- text: text2,
138574
+ var failure = (code2, text3) => ({
138575
+ text: text3,
138463
138576
  isError: true,
138464
138577
  errorCode: code2
138465
138578
  });
@@ -138677,7 +138790,7 @@ var makeTeamRuns = (core, deps) => {
138677
138790
  (row) => typeof row === "object" && row !== null && typeof row.teamId === "string" && typeof row.title === "string" ? [{ teamId: row.teamId, title: row.title }] : []
138678
138791
  ) : null
138679
138792
  ).catch(() => null);
138680
- const startTeamRun = async (binding, teamId, text2) => {
138793
+ const startTeamRun = async (binding, teamId, text3) => {
138681
138794
  const commandId = crypto.randomUUID();
138682
138795
  const runId = `run:${commandId}`;
138683
138796
  chatByRun.set(runId, binding);
@@ -138689,7 +138802,7 @@ var makeTeamRuns = (core, deps) => {
138689
138802
  commandId,
138690
138803
  teamId,
138691
138804
  projectId: binding.projectId,
138692
- goal: text2
138805
+ goal: text3
138693
138806
  }
138694
138807
  });
138695
138808
  } catch (error) {
@@ -138781,19 +138894,19 @@ var unsupportedTypeOf = (message) => {
138781
138894
  return null;
138782
138895
  };
138783
138896
  var TELEGRAM_DOWNLOAD_LIMIT_BYTES = 20 * 1024 * 1024;
138784
- var splitForTelegram = (text2, limit = TELEGRAM_TEXT_MAX_CHARS) => splitMessage(text2, limit);
138897
+ var splitForTelegram = (text3, limit = TELEGRAM_TEXT_MAX_CHARS) => splitMessage(text3, limit);
138785
138898
  var nextOffset = (updates, current) => updates.reduce((offset, update) => Math.max(offset, update.update_id + 1), current);
138786
- var commandForBot = (text2, botUsername) => {
138787
- const match = text2.match(/^(\/[A-Za-z0-9_]+)@([A-Za-z0-9_]+)(?=\s|$)/);
138788
- if (match === null) return text2;
138899
+ var commandForBot = (text3, botUsername) => {
138900
+ const match = text3.match(/^(\/[A-Za-z0-9_]+)@([A-Za-z0-9_]+)(?=\s|$)/);
138901
+ if (match === null) return text3;
138789
138902
  const [whole, command = "", addressee = ""] = match;
138790
138903
  if (botUsername !== null && addressee.toLowerCase() !== botUsername.toLowerCase()) {
138791
138904
  return null;
138792
138905
  }
138793
- return command + text2.slice(whole.length);
138906
+ return command + text3.slice(whole.length);
138794
138907
  };
138795
- var mentionedNames = (text2) => Array.from(
138796
- text2.matchAll(/(?<![\w@])@([A-Za-z0-9_]{3,})/g),
138908
+ var mentionedNames = (text3) => Array.from(
138909
+ text3.matchAll(/(?<![\w@])@([A-Za-z0-9_]{3,})/g),
138797
138910
  (match) => (match[1] ?? "").toLowerCase()
138798
138911
  );
138799
138912
  var passesGroupGate2 = (input) => {
@@ -138864,8 +138977,8 @@ var makeTelegramApi = (input) => {
138864
138977
  timeout: POLL_TIMEOUT_SECONDS,
138865
138978
  allowed_updates: ["message", "callback_query"]
138866
138979
  }),
138867
- sendMessage: async (chatId, text2) => {
138868
- for (const chunk of splitForTelegram(text2)) {
138980
+ sendMessage: async (chatId, text3) => {
138981
+ for (const chunk of splitForTelegram(text3)) {
138869
138982
  await call("sendMessage", { chat_id: chatId, text: chunk });
138870
138983
  }
138871
138984
  },
@@ -138873,10 +138986,10 @@ var makeTelegramApi = (input) => {
138873
138986
  * 发一条消息,回它的 id。调用方保证 `text` 不超过单条上限(边写边更新的回复要自己
138874
138987
  * 在上限处翻篇,这里不替它切)。带 `rows` 就挂一块内联键盘。
138875
138988
  */
138876
- sendOne: async (chatId, text2, rows) => {
138989
+ sendOne: async (chatId, text3, rows) => {
138877
138990
  const sent = await call("sendMessage", {
138878
138991
  chat_id: chatId,
138879
- text: text2,
138992
+ text: text3,
138880
138993
  ...rows === void 0 ? {} : { reply_markup: keyboard(rows) }
138881
138994
  });
138882
138995
  return sent?.message_id === void 0 ? null : String(sent.message_id);
@@ -138885,12 +138998,12 @@ var makeTelegramApi = (input) => {
138885
138998
  * 改一条已发出的消息。内容没变(`message is not modified`)当成功。`rows` 不给就是
138886
138999
  * 去掉按钮:改了文字又要保留按钮的调用方得自己再传一次。
138887
139000
  */
138888
- editMessage: async (chatId, messageId, text2, rows = []) => {
139001
+ editMessage: async (chatId, messageId, text3, rows = []) => {
138889
139002
  try {
138890
139003
  await call("editMessageText", {
138891
139004
  chat_id: chatId,
138892
139005
  message_id: Number(messageId),
138893
- text: text2,
139006
+ text: text3,
138894
139007
  reply_markup: keyboard(rows)
138895
139008
  });
138896
139009
  } catch (error) {
@@ -138898,10 +139011,10 @@ var makeTelegramApi = (input) => {
138898
139011
  }
138899
139012
  },
138900
139013
  /** 带按钮的审批消息,一行一个按钮;回消息 id,之后才改得了它(平台没给就是 null)。 */
138901
- sendButtons: async (chatId, text2, buttons) => {
139014
+ sendButtons: async (chatId, text3, buttons) => {
138902
139015
  const sent = await call("sendMessage", {
138903
139016
  chat_id: chatId,
138904
- text: text2,
139017
+ text: text3,
138905
139018
  reply_markup: keyboard(
138906
139019
  buttons.map((button) => [{ text: button.label, data: button.token }])
138907
139020
  )
@@ -138909,9 +139022,9 @@ var makeTelegramApi = (input) => {
138909
139022
  return sent?.message_id === void 0 ? null : String(sent.message_id);
138910
139023
  },
138911
139024
  /** 答完点击,不然客户端上那个按钮一直转圈。带 `text` 时点击者会看到一句提示。 */
138912
- answerCallback: (callbackQueryId, text2) => call("answerCallbackQuery", {
139025
+ answerCallback: (callbackQueryId, text3) => call("answerCallbackQuery", {
138913
139026
  callback_query_id: callbackQueryId,
138914
- ...text2 === void 0 ? {} : { text: text2 }
139027
+ ...text3 === void 0 ? {} : { text: text3 }
138915
139028
  }),
138916
139029
  sendPhoto: (chatId, photo) => upload("sendPhoto", "photo", chatId, photo),
138917
139030
  /** 以文件形式发(不压缩、不限尺寸比例):什么类型都行,音频与视频也走这条。 */
@@ -138975,9 +139088,9 @@ var parsePanelData = (data) => {
138975
139088
 
138976
139089
  // src/plainTurnText.ts
138977
139090
  var RUNNING_LABEL_MAX_CHARS = 200;
138978
- var clip3 = (text2, max) => {
138979
- const chars = Array.from(text2);
138980
- return chars.length <= max ? text2 : `${chars.slice(0, max - 1).join("")}\u2026`;
139091
+ var clip3 = (text3, max) => {
139092
+ const chars = Array.from(text3);
139093
+ return chars.length <= max ? text3 : `${chars.slice(0, max - 1).join("")}\u2026`;
138981
139094
  };
138982
139095
  var turnTextParts = (view, t) => {
138983
139096
  const names = view.steps.map((kind) => t(`card.step.${kind}`));
@@ -139004,8 +139117,8 @@ var makeTurnWriter = (deps) => {
139004
139117
  let liveText = null;
139005
139118
  let frozen = 0;
139006
139119
  let consumed = 0;
139007
- const put = async (text2) => {
139008
- const bounded = text2.length <= deps.limit ? text2 : text2.slice(0, deps.limit);
139120
+ const put = async (text3) => {
139121
+ const bounded = text3.length <= deps.limit ? text3 : text3.slice(0, deps.limit);
139009
139122
  if (live === null) {
139010
139123
  const id = await deps.messages.send(bounded);
139011
139124
  if (id === null) throw new Error("telegram sent a message without an id");
@@ -139120,8 +139233,8 @@ var makeTelegramAdapter = (deps) => {
139120
139233
  limit: TELEGRAM_TEXT_MAX_CHARS,
139121
139234
  ...resume === void 0 ? {} : { resume },
139122
139235
  messages: {
139123
- send: (text2) => withFloodWait(() => api.sendOne(chatId, text2)),
139124
- edit: (messageId, text2) => withFloodWait(() => api.editMessage(chatId, messageId, text2))
139236
+ send: (text3) => withFloodWait(() => api.sendOne(chatId, text3)),
139237
+ edit: (messageId, text3) => withFloodWait(() => api.editMessage(chatId, messageId, text3))
139125
139238
  }
139126
139239
  });
139127
139240
  return {
@@ -139163,14 +139276,14 @@ var makeTelegramAdapter = (deps) => {
139163
139276
  const message = update.message;
139164
139277
  if (message === void 0) continue;
139165
139278
  const resource = resourceOf2(message);
139166
- const text2 = commandForBot(
139279
+ const text3 = commandForBot(
139167
139280
  (message.text ?? message.caption ?? "").trim(),
139168
139281
  botUsername
139169
139282
  );
139170
- if (text2 === null) continue;
139283
+ if (text3 === null) continue;
139171
139284
  const gated = !passesGroupGate2({
139172
139285
  message,
139173
- text: text2,
139286
+ text: text3,
139174
139287
  hasResource: resource !== null,
139175
139288
  botUsername: botUsername ?? null,
139176
139289
  groupMention: binding.groupMention
@@ -139178,7 +139291,7 @@ var makeTelegramAdapter = (deps) => {
139178
139291
  if (gated && !(binding.groupMention === "always" && await isSoloGroup(String(message.chat.id)))) {
139179
139292
  continue;
139180
139293
  }
139181
- if (text2 === "" && resource === null) {
139294
+ if (text3 === "" && resource === null) {
139182
139295
  const unsupported = unsupportedTypeOf(message);
139183
139296
  if (unsupported === null) continue;
139184
139297
  handlers.onMessage({
@@ -139195,7 +139308,7 @@ var makeTelegramAdapter = (deps) => {
139195
139308
  messageId: String(message.message_id),
139196
139309
  chatId: String(message.chat.id),
139197
139310
  senderId: message.from === void 0 ? null : String(message.from.id),
139198
- text: text2,
139311
+ text: text3,
139199
139312
  resources: resource === null ? [] : [
139200
139313
  {
139201
139314
  key: resource.fileId,
@@ -139225,9 +139338,9 @@ var makeTelegramAdapter = (deps) => {
139225
139338
  }
139226
139339
  };
139227
139340
  },
139228
- sendText: async (binding, text2) => {
139341
+ sendText: async (binding, text3) => {
139229
139342
  const api = await apiFor(binding);
139230
- await api.sendMessage(binding.chatId, text2);
139343
+ await api.sendMessage(binding.chatId, text3);
139231
139344
  },
139232
139345
  sendImage: async (binding, image2) => {
139233
139346
  const api = await apiFor(binding);
@@ -139341,7 +139454,7 @@ ${line}`
139341
139454
 
139342
139455
  // src/turns.ts
139343
139456
  var TITLE_MAX_CHARS = 72;
139344
- var titleFrom = (text2) => text2.replace(/\s+/g, " ").slice(0, TITLE_MAX_CHARS) || "Chat thread";
139457
+ var titleFrom = (text3) => text3.replace(/\s+/g, " ").slice(0, TITLE_MAX_CHARS) || "Chat thread";
139345
139458
  var makeTurns = (core, deps) => {
139346
139459
  const { host, t, commit, bindChat, deliver } = core;
139347
139460
  const { queueFlow, rememberThreadProject } = deps;
@@ -139410,8 +139523,8 @@ var makeTurns = (core, deps) => {
139410
139523
  };
139411
139524
  const startTurn = async (binding, message) => {
139412
139525
  const chatKey = chatKeyOf(binding);
139413
- const text2 = message.text;
139414
- const threadId = await ensureThread(binding, text2 || message.resources[0]?.name || "Chat");
139526
+ const text3 = message.text;
139527
+ const threadId = await ensureThread(binding, text3 || message.resources[0]?.name || "Chat");
139415
139528
  if (threadId === null) return null;
139416
139529
  const waiting = pendingByChat.get(chatKey);
139417
139530
  pendingByChat.delete(chatKey);
@@ -139434,10 +139547,10 @@ var makeTurns = (core, deps) => {
139434
139547
  message: {
139435
139548
  messageId: userMessageId,
139436
139549
  role: "user",
139437
- text: notes.length === 0 ? text2 : [text2, ...notes].join("\n"),
139550
+ text: notes.length === 0 ? text3 : [text3, ...notes].join("\n"),
139438
139551
  attachments
139439
139552
  },
139440
- titleSeed: titleFrom(text2 || attachments[0]?.name || "Chat"),
139553
+ titleSeed: titleFrom(text3 || attachments[0]?.name || "Chat"),
139441
139554
  runtimeMode: binding.runtimeMode,
139442
139555
  interactionMode: interactionModeOf(chatKey),
139443
139556
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -139455,7 +139568,7 @@ var makeTurns = (core, deps) => {
139455
139568
  chatKey,
139456
139569
  threadId,
139457
139570
  userMessageId,
139458
- text2.trim() || attachments[0]?.name || message.resources[0]?.name || ""
139571
+ text3.trim() || attachments[0]?.name || message.resources[0]?.name || ""
139459
139572
  );
139460
139573
  return threadId;
139461
139574
  };
@@ -139590,21 +139703,21 @@ var parseWecomMessage = (frame, botId) => {
139590
139703
  const ownIds = [...new Set([body.aibotid, botId].filter((id) => Boolean(id)))];
139591
139704
  const stripOwn = (value) => ownIds.reduce((rest, id) => rest.replaceAll(`@${id}`, ""), value);
139592
139705
  let mentionSource = "";
139593
- let text2 = "";
139706
+ let text3 = "";
139594
139707
  const resources = [];
139595
139708
  switch (body.msgtype) {
139596
139709
  case "text": {
139597
139710
  const raw = body.text?.content;
139598
139711
  if (typeof raw !== "string") return null;
139599
139712
  mentionSource = raw;
139600
- text2 = stripOwn(raw).trim();
139713
+ text3 = stripOwn(raw).trim();
139601
139714
  break;
139602
139715
  }
139603
139716
  case "voice": {
139604
139717
  const transcript = body.voice?.content;
139605
139718
  if (typeof transcript !== "string" || transcript.trim() === "") return null;
139606
139719
  mentionSource = transcript;
139607
- text2 = stripOwn(transcript).trim();
139720
+ text3 = stripOwn(transcript).trim();
139608
139721
  break;
139609
139722
  }
139610
139723
  case "image":
@@ -139638,7 +139751,7 @@ var parseWecomMessage = (frame, botId) => {
139638
139751
  }
139639
139752
  }
139640
139753
  if (parts.length === 0) return null;
139641
- text2 = parts.join("\n");
139754
+ text3 = parts.join("\n");
139642
139755
  break;
139643
139756
  }
139644
139757
  default:
@@ -139650,14 +139763,14 @@ var parseWecomMessage = (frame, botId) => {
139650
139763
  messageId,
139651
139764
  chatId,
139652
139765
  senderUserId: body.from?.userid ?? null,
139653
- text: text2,
139766
+ text: text3,
139654
139767
  resources,
139655
139768
  requestId: frame.headers?.req_id ?? null,
139656
139769
  chatType: mentioned ? "single" : chatType,
139657
139770
  conversation: chatType === "group" ? "group" : "single"
139658
139771
  };
139659
139772
  };
139660
- var splitForWecom = (text2, limit = WECOM_TEXT_MAX_CHARS) => splitMessage(text2, limit);
139773
+ var splitForWecom = (text3, limit = WECOM_TEXT_MAX_CHARS) => splitMessage(text3, limit);
139661
139774
  var decoder = new TextDecoder();
139662
139775
  var runWecomClient = (input) => {
139663
139776
  let sequence = 0;
@@ -139759,8 +139872,8 @@ var runWecomClient = (input) => {
139759
139872
  return false;
139760
139873
  }
139761
139874
  );
139762
- const sendText = async (chatId, text2) => {
139763
- for (const [index, content] of splitForWecom(text2).entries()) {
139875
+ const sendText = async (chatId, text3) => {
139876
+ for (const [index, content] of splitForWecom(text3).entries()) {
139764
139877
  const inboundRequestId = index === 0 ? pendingRequests.get(chatId) : void 0;
139765
139878
  if (inboundRequestId !== void 0) {
139766
139879
  pendingRequests.delete(chatId);
@@ -139981,8 +140094,8 @@ var credentials2 = (binding) => ({
139981
140094
  botSecret: binding.values["wecomBotSecret"] ?? "",
139982
140095
  endpoint: normalizeWecomEndpoint(binding.values["wecomEndpoint"] || DEFAULT_WECOM_ENDPOINT)
139983
140096
  });
139984
- var optionIndexFrom = (text2, count) => {
139985
- const trimmed = text2.trim();
140097
+ var optionIndexFrom = (text3, count) => {
140098
+ const trimmed = text3.trim();
139986
140099
  if (!/^\d+$/.test(trimmed)) return null;
139987
140100
  const index = Number.parseInt(trimmed, 10);
139988
140101
  return Number.isInteger(index) && index >= 1 && index <= count ? index : null;
@@ -140110,13 +140223,13 @@ ${kept}`;
140110
140223
  }
140111
140224
  };
140112
140225
  },
140113
- sendText: async (binding, text2) => {
140226
+ sendText: async (binding, text3) => {
140114
140227
  const client = clients.get(binding.rowId);
140115
140228
  if (client === void 0) {
140116
140229
  deps.log.warn("wecom cannot send without a connection", { bot: binding.displayName });
140117
140230
  return;
140118
140231
  }
140119
- await client.sendText(binding.chatId, text2);
140232
+ await client.sendText(binding.chatId, text3);
140120
140233
  },
140121
140234
  askApproval: async (binding, request) => {
140122
140235
  const lines = [
@@ -140153,8 +140266,8 @@ ${kept}`;
140153
140266
  // 图 10 MB(只认 png / jpg / jpeg / gif)、文件 20 MB,来自企微官方文档「智能机器人长连接」。
140154
140267
  outboundLimits: { imageBytes: 10 * 1024 * 1024, fileBytes: 20 * 1024 * 1024, minBytes: 5 },
140155
140268
  imageMimeTypes: /* @__PURE__ */ new Set(["image/png", "image/jpeg", "image/gif"]),
140156
- answerByText: (_binding, text2, options) => {
140157
- const index = optionIndexFrom(text2, options.length);
140269
+ answerByText: (_binding, text3, options) => {
140270
+ const index = optionIndexFrom(text3, options.length);
140158
140271
  return index === null ? null : options[index - 1]?.token ?? null;
140159
140272
  },
140160
140273
  fetchResource: async (binding, input) => {
@@ -140220,7 +140333,7 @@ var imPlugin = definePlugin({
140220
140333
  }
140221
140334
  })
140222
140335
  ];
140223
- ctx.settingsCard(buildSettingsCard(adapters));
140336
+ ctx.settingsCard({ ...buildSettingsCard(adapters), actions: [LARK_SETUP_CARD_ACTION] });
140224
140337
  registerLarkSetup(ctx);
140225
140338
  const core = makeImCore({
140226
140339
  host: {
@@ -140265,7 +140378,7 @@ var imPlugin = definePlugin({
140265
140378
  teams,
140266
140379
  modelPlan,
140267
140380
  rows: projectRows,
140268
- handleCommand: (binding, text2, teamChoices) => commands.handleCommand(binding, text2, teamChoices)
140381
+ handleCommand: (binding, text3, teamChoices) => commands.handleCommand(binding, text3, teamChoices)
140269
140382
  });
140270
140383
  const chatSetup = makeChatSetup(core, {
140271
140384
  rows: projectRows,