@songsid/agend 2.2.0-beta.1 → 2.2.0-beta.3

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.
Files changed (197) hide show
  1. package/README.md +1 -1
  2. package/README.zh-TW.md +1 -1
  3. package/dist/agent-cli-instructions.md +10 -7
  4. package/dist/agent-endpoint.js +21 -9
  5. package/dist/agent-endpoint.js.map +1 -1
  6. package/dist/agent-whats-new.d.ts +47 -0
  7. package/dist/agent-whats-new.js +141 -0
  8. package/dist/agent-whats-new.js.map +1 -0
  9. package/dist/auth-api.d.ts +2 -2
  10. package/dist/auth-api.js +4 -2
  11. package/dist/auth-api.js.map +1 -1
  12. package/dist/backend/kiro-engine-ledger.d.ts +5 -0
  13. package/dist/backend/kiro-engine-ledger.js +20 -0
  14. package/dist/backend/kiro-engine-ledger.js.map +1 -1
  15. package/dist/backend/kiro-identity.d.ts +6 -0
  16. package/dist/backend/kiro-identity.js +19 -5
  17. package/dist/backend/kiro-identity.js.map +1 -1
  18. package/dist/backend/kiro.d.ts +14 -2
  19. package/dist/backend/kiro.js +84 -9
  20. package/dist/backend/kiro.js.map +1 -1
  21. package/dist/backend/types.d.ts +4 -2
  22. package/dist/backend/types.js.map +1 -1
  23. package/dist/channel/adapters/discord.d.ts +11 -1
  24. package/dist/channel/adapters/discord.js +23 -1
  25. package/dist/channel/adapters/discord.js.map +1 -1
  26. package/dist/channel/adapters/telegram.d.ts +19 -1
  27. package/dist/channel/adapters/telegram.js +60 -9
  28. package/dist/channel/adapters/telegram.js.map +1 -1
  29. package/dist/channel/mcp-server.js +9 -1
  30. package/dist/channel/mcp-server.js.map +1 -1
  31. package/dist/channel/mcp-tools.d.ts +11 -0
  32. package/dist/channel/mcp-tools.js +23 -12
  33. package/dist/channel/mcp-tools.js.map +1 -1
  34. package/dist/channel/telegram-markdown.d.ts +6 -0
  35. package/dist/channel/telegram-markdown.js +104 -0
  36. package/dist/channel/telegram-markdown.js.map +1 -0
  37. package/dist/channel/tool-router.js +9 -3
  38. package/dist/channel/tool-router.js.map +1 -1
  39. package/dist/channel/types.d.ts +14 -2
  40. package/dist/cli.js +55 -16
  41. package/dist/cli.js.map +1 -1
  42. package/dist/command-table.js +1 -1
  43. package/dist/command-table.js.map +1 -1
  44. package/dist/config-validator.js +49 -0
  45. package/dist/config-validator.js.map +1 -1
  46. package/dist/cross-instance-envelope.d.ts +15 -2
  47. package/dist/cross-instance-envelope.js +27 -5
  48. package/dist/cross-instance-envelope.js.map +1 -1
  49. package/dist/daemon.d.ts +48 -0
  50. package/dist/daemon.js +250 -22
  51. package/dist/daemon.js.map +1 -1
  52. package/dist/delivery-outbox.d.ts +17 -2
  53. package/dist/delivery-outbox.js +13 -2
  54. package/dist/delivery-outbox.js.map +1 -1
  55. package/dist/delivery-reconciliation.d.ts +18 -1
  56. package/dist/delivery-reconciliation.js +67 -2
  57. package/dist/delivery-reconciliation.js.map +1 -1
  58. package/dist/fleet-manager.d.ts +63 -1
  59. package/dist/fleet-manager.js +314 -20
  60. package/dist/fleet-manager.js.map +1 -1
  61. package/dist/general-knowledge/skills/backend-providers/SKILL.md +1 -1
  62. package/dist/general-knowledge/skills/credential-profiles/SKILL.md +9 -6
  63. package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +11 -2
  64. package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +8 -8
  65. package/dist/general-knowledge/skills/fleet-config/SKILL.md +5 -5
  66. package/dist/general-knowledge/skills/fleet-health/SKILL.md +4 -4
  67. package/dist/general-knowledge/skills/fleet-restart/SKILL.md +13 -13
  68. package/dist/general-knowledge/skills/instance-lifecycle/SKILL.md +3 -2
  69. package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +6 -0
  70. package/dist/general-knowledge/skills/model-discovery/SKILL.md +9 -9
  71. package/dist/general-knowledge/skills/multi-channel/SKILL.md +8 -2
  72. package/dist/general-knowledge/skills/scheduling/SKILL.md +5 -3
  73. package/dist/general-knowledge/skills/session-management/SKILL.md +6 -5
  74. package/dist/general-knowledge/skills/tui-effort/SKILL.md +2 -2
  75. package/dist/general-knowledge/skills/worker-collaboration/SKILL.md +4 -3
  76. package/dist/general-knowledge/steering/core-rules.md +8 -7
  77. package/dist/instance-avatar.d.ts +36 -0
  78. package/dist/instance-avatar.js +57 -0
  79. package/dist/instance-avatar.js.map +1 -0
  80. package/dist/instance-config-impact.js +5 -0
  81. package/dist/instance-config-impact.js.map +1 -1
  82. package/dist/instance-lifecycle.d.ts +4 -0
  83. package/dist/instance-lifecycle.js +3 -1
  84. package/dist/instance-lifecycle.js.map +1 -1
  85. package/dist/instructions.d.ts +2 -0
  86. package/dist/instructions.js +10 -7
  87. package/dist/instructions.js.map +1 -1
  88. package/dist/locale.js +36 -26
  89. package/dist/locale.js.map +1 -1
  90. package/dist/next-steps.js +1 -1
  91. package/dist/next-steps.js.map +1 -1
  92. package/dist/outbound-handlers.d.ts +2 -0
  93. package/dist/outbound-handlers.js +28 -15
  94. package/dist/outbound-handlers.js.map +1 -1
  95. package/dist/outbound-schemas.d.ts +10 -2
  96. package/dist/outbound-schemas.js +15 -5
  97. package/dist/outbound-schemas.js.map +1 -1
  98. package/dist/public-web-gateway.js +7 -2
  99. package/dist/public-web-gateway.js.map +1 -1
  100. package/dist/service-activation.js +4 -3
  101. package/dist/service-activation.js.map +1 -1
  102. package/dist/settings-api.js +71 -21
  103. package/dist/settings-api.js.map +1 -1
  104. package/dist/settings-change.js +70 -1
  105. package/dist/settings-change.js.map +1 -1
  106. package/dist/settings-effect.js +26 -4
  107. package/dist/settings-effect.js.map +1 -1
  108. package/dist/settings-http-confirmation.js +7 -0
  109. package/dist/settings-http-confirmation.js.map +1 -1
  110. package/dist/setup-form.d.ts +1 -1
  111. package/dist/setup-form.js +1 -1
  112. package/dist/status-emojis.d.ts +10 -3
  113. package/dist/status-emojis.js +11 -2
  114. package/dist/status-emojis.js.map +1 -1
  115. package/dist/tips.js +4 -4
  116. package/dist/tips.js.map +1 -1
  117. package/dist/transcript-delta-reader.d.ts +3 -3
  118. package/dist/transcript-delta-reader.js +8 -8
  119. package/dist/transcript-delta-reader.js.map +1 -1
  120. package/dist/transcript-monitor.d.ts +8 -0
  121. package/dist/transcript-monitor.js +26 -2
  122. package/dist/transcript-monitor.js.map +1 -1
  123. package/dist/transcript-sources.d.ts +54 -0
  124. package/dist/transcript-sources.js +188 -27
  125. package/dist/transcript-sources.js.map +1 -1
  126. package/dist/transcript-turns.d.ts +15 -2
  127. package/dist/transcript-turns.js +15 -2
  128. package/dist/transcript-turns.js.map +1 -1
  129. package/dist/types.d.ts +11 -0
  130. package/dist/ui/chat-emojis.js +33 -0
  131. package/dist/ui/chat-render.js +12 -0
  132. package/dist/ui/chat-store.js +1 -1
  133. package/dist/ui/chat-strings.js +12 -12
  134. package/dist/ui/chat-thread.js +23 -4
  135. package/dist/ui/panel-chat.js +16 -3
  136. package/dist/ui/panel-needs.js +5 -2
  137. package/dist/ui/panel-settings.js +129 -31
  138. package/dist/ui/settings-dialogs.js +7 -2
  139. package/dist/ui/settings-model.js +2 -1
  140. package/dist/ui/settings-strings.js +44 -4
  141. package/dist/ui/shared/app-i18n.js +37 -15
  142. package/dist/ui/shared/app-prefs.js +249 -0
  143. package/dist/ui/shared/app-route.js +1 -1
  144. package/dist/ui/shared/app-shell.js +17 -4
  145. package/dist/ui/shared/app-store.js +3 -1
  146. package/dist/ui/shared/app.css +55 -0
  147. package/dist/ui/shared/app.js +6 -1
  148. package/dist/ui/shared/header-tools.js +55 -5
  149. package/dist/ui/shared/instance-nav.js +169 -32
  150. package/dist/ui/shared/panel-view.js +6 -0
  151. package/dist/ui/shared/signin.js +7 -7
  152. package/dist/ui/shared/theme.js +39 -7
  153. package/dist/ui/shared/ui-icons.js +1 -0
  154. package/dist/ui/shared/usage-dialog.js +13 -4
  155. package/dist/ui/shared/view-strings.js +22 -4
  156. package/dist/ui/signin.html +1 -1
  157. package/dist/update-install.d.ts +15 -1
  158. package/dist/update-install.js +6 -0
  159. package/dist/update-install.js.map +1 -1
  160. package/dist/update-preflight.d.ts +100 -0
  161. package/dist/update-preflight.js +264 -0
  162. package/dist/update-preflight.js.map +1 -0
  163. package/dist/updater-caller.d.ts +31 -0
  164. package/dist/updater-caller.js +109 -0
  165. package/dist/updater-caller.js.map +1 -0
  166. package/dist/view-api.d.ts +1 -1
  167. package/dist/view-api.js +38 -8
  168. package/dist/view-api.js.map +1 -1
  169. package/dist/wake-coordinator.d.ts +11 -0
  170. package/dist/wake-coordinator.js +38 -4
  171. package/dist/wake-coordinator.js.map +1 -1
  172. package/dist/web-api.d.ts +21 -1
  173. package/dist/web-api.js +157 -1
  174. package/dist/web-api.js.map +1 -1
  175. package/dist/web-auth.d.ts +2 -2
  176. package/dist/web-auth.js +7 -4
  177. package/dist/web-auth.js.map +1 -1
  178. package/dist/web-host-guard.d.ts +3 -11
  179. package/dist/web-host-guard.js +3 -12
  180. package/dist/web-host-guard.js.map +1 -1
  181. package/dist/web-images.d.ts +47 -0
  182. package/dist/web-images.js +169 -0
  183. package/dist/web-images.js.map +1 -0
  184. package/dist/web-prefs.d.ts +63 -0
  185. package/dist/web-prefs.js +263 -0
  186. package/dist/web-prefs.js.map +1 -0
  187. package/dist/web-session.d.ts +36 -1
  188. package/dist/web-session.js +53 -6
  189. package/dist/web-session.js.map +1 -1
  190. package/dist/web-settings-patch.d.ts +21 -0
  191. package/dist/web-settings-patch.js +74 -0
  192. package/dist/web-settings-patch.js.map +1 -0
  193. package/dist/web-shell-routes.d.ts +1 -1
  194. package/dist/web-shell-routes.js +1 -1
  195. package/dist/web-shell-routes.js.map +1 -1
  196. package/dist/workflow-templates/default.md +1 -1
  197. package/package.json +1 -1
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Markdown → Telegram HTML (parse_mode "HTML") for text an agent wrote as markdown.
3
+ *
4
+ * Escape first, by construction: every character of the input is escaped (`&`, `<`, `>`) before any tag is added, and
5
+ * the only tags in the output are the ones this file writes — so `a<b`, `&` or a literal `<b>` in the input are shown
6
+ * as text, never parsed. A fixed set of inline forms becomes tags: `code`, **bold**, ~~strike~~, *italic* / _italic_
7
+ * and [text](http(s) URL). Each tag pair wraps text that contains no tag yet (code spans, fences and link targets are
8
+ * cut out before emphasis runs; emphasis content excludes `<` `>`), so the output is always well-formed. A fence or
9
+ * any other run of two or more backticks keeps its text exactly — escaped, backticks and all, never formatted.
10
+ * Tables and headings stay as their literal characters.
11
+ *
12
+ * Linear time: the text can be as long as a tool argument allows (far beyond Telegram's 4096), and this runs on the
13
+ * fleet's event loop before any API call. One left-to-right pass; each scan stops at the next character that could
14
+ * start another token, and the emphasis patterns stop at their own next delimiter.
15
+ */
16
+ import { GrammyError } from "grammy";
17
+ const escapeHtml = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
18
+ /** Emphasis on already-escaped text. Bold first; strike and italic never span a tag (their content excludes < >). */
19
+ function emphasis(escaped) {
20
+ return escaped
21
+ .replace(/\*\*([^*\n]+?)\*\*/g, "<b>$1</b>")
22
+ .replace(/~~([^~\n<>]+?)~~/g, "<s>$1</s>")
23
+ .replace(/(^|[^\w*])\*([^*\s<>](?:[^*\n<>]*?[^*\s<>])?)\*(?![\w*])/g, "$1<i>$2</i>")
24
+ // `_` only at word edges, so snake_case stays as it is.
25
+ .replace(/(^|[^\w])_([^_\s<>](?:[^_\n<>]*?[^_\s<>])?)_(?!\w)/g, "$1<i>$2</i>");
26
+ }
27
+ /** `(http(s)://target)` right after a link's `]`; the target stops at whitespace, parentheses, quotes and < >. */
28
+ const LINK_TARGET = /\((https?:\/\/[^\s()<>"]+)\)/y;
29
+ /** Every maximal run of 2+ backticks, by length — so finding a fence's closing run never rescans the text. */
30
+ function backtickRuns(text) {
31
+ const runs = new Map();
32
+ for (let i = text.indexOf("`"); i >= 0; i = text.indexOf("`", i)) {
33
+ let n = 1;
34
+ while (text[i + n] === "`")
35
+ n++;
36
+ if (n >= 2)
37
+ (runs.get(n) ?? runs.set(n, []).get(n)).push(i);
38
+ i += n;
39
+ }
40
+ return runs;
41
+ }
42
+ export function markdownToTelegramHtml(text) {
43
+ const runs = backtickRuns(text);
44
+ const cursor = new Map();
45
+ /** The first run of exactly `n` backticks starting at or after `from` (callers ask with a rising `from`). */
46
+ const nextRun = (n, from) => {
47
+ const list = runs.get(n) ?? [];
48
+ let k = cursor.get(n) ?? 0;
49
+ while (k < list.length && list[k] < from)
50
+ k++;
51
+ cursor.set(n, k);
52
+ return k < list.length ? list[k] : -1;
53
+ };
54
+ let out = "", from = 0, i = 0;
55
+ const token = (start, end, html) => {
56
+ if (start > from)
57
+ out += emphasis(escapeHtml(text.slice(from, start)));
58
+ out += html;
59
+ from = i = end;
60
+ };
61
+ while (i < text.length) {
62
+ const c = text[i];
63
+ if (c === "`") {
64
+ let n = 1;
65
+ while (text[i + n] === "`")
66
+ n++;
67
+ if (n >= 2) {
68
+ // A fence or a multi-backtick span: literal through its closing run of the same length (or just the run).
69
+ const close = nextRun(n, i + n);
70
+ const end = close < 0 ? i + n : close + n;
71
+ token(i, end, escapeHtml(text.slice(i, end)));
72
+ continue;
73
+ }
74
+ const j = text.indexOf("`", i + 1);
75
+ if (j > i + 1 && text[j + 1] !== "`" && !text.slice(i + 1, j).includes("\n")) {
76
+ token(i, j + 1, `<code>${escapeHtml(text.slice(i + 1, j))}</code>`);
77
+ continue;
78
+ }
79
+ }
80
+ else if (c === "[") {
81
+ let k = i + 1;
82
+ while (k < text.length && text[k] !== "]" && text[k] !== "[" && text[k] !== "\n")
83
+ k++;
84
+ if (text[k] === "]" && k > i + 1) {
85
+ LINK_TARGET.lastIndex = k + 1;
86
+ const m = LINK_TARGET.exec(text);
87
+ if (m) {
88
+ token(i, k + 1 + m[0].length, `<a href="${escapeHtml(m[1])}">${emphasis(escapeHtml(text.slice(i + 1, k)))}</a>`);
89
+ continue;
90
+ }
91
+ }
92
+ }
93
+ i++;
94
+ }
95
+ return out + emphasis(escapeHtml(text.slice(from)));
96
+ }
97
+ /**
98
+ * Telegram refused the text's markup itself ("Bad Request: can't parse entities: …"): a definite 400 before anything
99
+ * changed, so sending the same text again without a parse mode is safe and cannot double-apply.
100
+ */
101
+ export function isTelegramParseRefusal(err) {
102
+ return err instanceof GrammyError && err.error_code === 400 && /can't parse entities/i.test(err.description);
103
+ }
104
+ //# sourceMappingURL=telegram-markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram-markdown.js","sourceRoot":"","sources":["../../src/channel/telegram-markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,UAAU,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAE/G,qHAAqH;AACrH,SAAS,QAAQ,CAAC,OAAe;IAC/B,OAAO,OAAO;SACX,OAAO,CAAC,qBAAqB,EAAE,WAAW,CAAC;SAC3C,OAAO,CAAC,mBAAmB,EAAE,WAAW,CAAC;SACzC,OAAO,CAAC,2DAA2D,EAAE,aAAa,CAAC;QACpF,wDAAwD;SACvD,OAAO,CAAC,qDAAqD,EAAE,aAAa,CAAC,CAAC;AACnF,CAAC;AAED,kHAAkH;AAClH,MAAM,WAAW,GAAG,+BAA+B,CAAC;AAEpD,8GAA8G;AAC9G,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAoB,CAAC;IACzC,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QACjE,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG;YAAE,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC;YAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7D,CAAC,IAAI,CAAC,CAAC;IACT,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,6GAA6G;IAC7G,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,IAAY,EAAU,EAAE;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAE,GAAG,IAAI;YAAE,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC;IACF,IAAI,GAAG,GAAG,EAAE,EAAE,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,IAAY,EAAE,EAAE;QACzD,IAAI,KAAK,GAAG,IAAI;YAAE,GAAG,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QACvE,GAAG,IAAI,IAAI,CAAC;QACZ,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC;IACjB,CAAC,CAAC;IACF,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG;gBAAE,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACX,0GAA0G;gBAC1G,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChC,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;gBAC1C,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC9C,SAAS;YACX,CAAC;YACD,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7E,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,SAAS,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;gBACpE,SAAS;YACX,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;YACtF,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjC,WAAW,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC9B,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACjC,IAAI,CAAC,EAAE,CAAC;oBACN,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,YAAY,UAAU,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,KAAK,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBAClH,SAAS;gBACX,CAAC;YACH,CAAC;QACH,CAAC;QACD,CAAC,EAAE,CAAC;IACN,CAAC;IACD,OAAO,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,OAAO,GAAG,YAAY,WAAW,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,IAAI,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;AAC/G,CAAC"}
@@ -63,7 +63,8 @@ extra = {}) {
63
63
  return true;
64
64
  }
65
65
  const replyThreadId = args.thread_id ?? threadId;
66
- const format = args.format === "markdown" ? "html" : undefined;
66
+ // #1658: markdown reaches the adapter as markdown — Telegram converts it escape-first (its rich path is unchanged).
67
+ const format = args.format === "markdown" ? "markdown" : undefined;
67
68
  // Stickers (#1226) go with the text, as the platform does it — and were checked by the fleet before this
68
69
  // call; an adapter that cannot send them says so rather than dropping them.
69
70
  const stickers = Array.isArray(args.stickers) ? args.stickers.filter((x) => typeof x === "string") : [];
@@ -100,11 +101,16 @@ extra = {}) {
100
101
  .then(() => respond("ok"))
101
102
  .catch(e => respond(null, e.message));
102
103
  return true;
103
- case "edit_message":
104
- adapter.editMessage(chatId, args.message_id ?? "", args.text ?? "", threadId)
104
+ case "edit_message": {
105
+ // #1651: "markdown" reaches the adapter as markdown — Telegram converts it escape-first, so a `<` or `&` in the
106
+ // text is shown, not refused. A text edit is the call it always was — no options argument at all.
107
+ const format = args.format === "markdown" ? "markdown" : undefined;
108
+ const messageId = args.message_id ?? "", text = args.text ?? "";
109
+ (format ? adapter.editMessage(chatId, messageId, text, threadId, { format }) : adapter.editMessage(chatId, messageId, text, threadId))
105
110
  .then(() => respond("ok"))
106
111
  .catch(e => respond(null, e.message));
107
112
  return true;
113
+ }
108
114
  case "download_attachment":
109
115
  adapter.downloadAttachment(args.file_id ?? "")
110
116
  .then(path => respond(path))
@@ -1 +1 @@
1
- {"version":3,"file":"tool-router.js","sourceRoot":"","sources":["../../src/channel/tool-router.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-router.js","sourceRoot":"","sources":["../../src/channel/tool-router.ts"],"names":[],"mappings":"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"}
@@ -102,7 +102,11 @@ export interface ChannelAdapter extends EventEmitter {
102
102
  sendFile(chatId: string, filePath: string, opts?: SendOpts): Promise<SentMessage>;
103
103
  /** threadId locates the message when it lives in a topic/thread (Discord forum
104
104
  * topics are their own channel and won't be found by a guild text-channel scan). */
105
- editMessage(chatId: string, messageId: string, text: string, threadId?: string): Promise<void>;
105
+ /** #1651: "html" is the platform's parse mode, as on sendText; "markdown" is an agent's markdown (Telegram converts it
106
+ * escape-first to HTML). Discord always renders Markdown. */
107
+ editMessage(chatId: string, messageId: string, text: string, threadId?: string, opts?: {
108
+ format?: "html" | "markdown";
109
+ }): Promise<void>;
106
110
  /** Edit a message's text AND remove any inline buttons/components. Used to
107
111
  * retire a Cancel button after the agent replies or a timeout elapses.
108
112
  * threadId locates the message when it lives in a topic/thread (Discord
@@ -142,6 +146,13 @@ export interface ChannelAdapter extends EventEmitter {
142
146
  * Lottie sticker, or an animated Telegram sticker without a thumbnail.
143
147
  */
144
148
  fetchStickerPreview?(sticker: StickerInfo): Promise<StickerPreview | null>;
149
+ /**
150
+ * #1630: this bot's own avatar, downloaded here (a Telegram file URL carries the token, which must not leave the
151
+ * adapter). null when the bot has none set — a platform default says nothing about which bot it is.
152
+ */
153
+ fetchBotAvatar?(): Promise<StickerPreview | null>;
154
+ /** #1630: this bot's colour (its highest coloured role) in the server `channelId` belongs to, or null for none. */
155
+ botAccentColor?(channelId?: string): Promise<string | null>;
145
156
  /**
146
157
  * Send stickers, after `text` when there is any (#1226). Discord: on the same
147
158
  * message as the text's last chunk (`sticker_ids`); Telegram: the text, then
@@ -233,7 +244,8 @@ export interface SendOpts {
233
244
  };
234
245
  threadId?: string;
235
246
  replyTo?: string;
236
- format?: "text" | "html";
247
+ /** "html": the caller's own platform HTML. "markdown": an agent's markdown (#1658 — Telegram converts it escape-first). */
248
+ format?: "text" | "html" | "markdown";
237
249
  chunkLimit?: number;
238
250
  /** Suppress the link/web-page preview for URLs in the message (Telegram). */
239
251
  disablePreview?: boolean;
package/dist/cli.js CHANGED
@@ -1546,7 +1546,8 @@ program
1546
1546
  catch {
1547
1547
  return false;
1548
1548
  } },
1549
- // `agend install` activates by default; the update owns stop/start, so only the file is refreshed here.
1549
+ // `agend install` activates by default; the update owns stop/start, so only the file is refreshed here. Only
1550
+ // an existing service is refreshed: a detached fleet's update never calls this (#1631).
1550
1551
  refresh: () => {
1551
1552
  const result = capture(newAgend.command, [...newAgend.args, "install", "--no-activate"]);
1552
1553
  if (result.status === 0)
@@ -1663,6 +1664,42 @@ program
1663
1664
  process.exitCode = 1;
1664
1665
  return;
1665
1666
  }
1667
+ // ── Check if npm global needs sudo (read-only; decides the nvm path the preflight judges) ──
1668
+ let needsSudo = false;
1669
+ try {
1670
+ const prefix = execSync("npm config get prefix", { encoding: "utf-8" }).trim();
1671
+ const { accessSync, constants } = await import("node:fs");
1672
+ try {
1673
+ accessSync(prefix, constants.W_OK);
1674
+ }
1675
+ catch {
1676
+ needsSudo = true;
1677
+ }
1678
+ }
1679
+ catch { /* assume no sudo needed */ }
1680
+ // ── #1441 B: can the target run here, on the Node it will actually run on? ──
1681
+ // Read where the install runs (#1623 review): a direct install runs `npm` and the release's `node` from this
1682
+ // environment, so it is decided now, before anything is touched. An nvm install runs nvm's npm and Node 22, which
1683
+ // exist only once nvm has selected them: runUpdateInstall decides it there, before the lock and npm.
1684
+ const preflight = targetVersion ? await import("./update-preflight.js") : null;
1685
+ if (preflight && targetVersion && !needsSudo) {
1686
+ const verdict = preflight.preflightUpdate({
1687
+ run: (argv, timeoutMs) => {
1688
+ const r = spawnSync(argv[0], argv.slice(1), { encoding: "utf-8", timeout: timeoutMs, stdio: ["ignore", "pipe", "ignore"] });
1689
+ return { status: r.status, stdout: r.stdout ?? "" };
1690
+ },
1691
+ npm: "npm",
1692
+ }, pkg, targetVersion, "the `node` on PATH");
1693
+ if (verdict.kind === "refuse") {
1694
+ console.error(`\n${verdict.message}\n`);
1695
+ // A chat-started /update (Discord, Telegram, an agent) is waiting on this: the reason is its outcome.
1696
+ setUpdateProgressStage(DATA_DIR, "failed", { error: `Not updated: ${verdict.summary}. Nothing was changed.` });
1697
+ process.exitCode = 1;
1698
+ return;
1699
+ }
1700
+ if (verdict.kind === "unknown")
1701
+ console.log(verdict.note);
1702
+ }
1666
1703
  if (targetVersion) {
1667
1704
  console.log(`\n Updating AgEnD v${pkgVersion} → v${targetVersion}...\n`);
1668
1705
  }
@@ -1684,19 +1721,6 @@ program
1684
1721
  process.exit(1);
1685
1722
  };
1686
1723
  setUpdateProgressStage(DATA_DIR, "downloading");
1687
- // ── Check if npm global needs sudo ──
1688
- let needsSudo = false;
1689
- try {
1690
- const prefix = execSync("npm config get prefix", { encoding: "utf-8" }).trim();
1691
- const { accessSync, constants } = await import("node:fs");
1692
- try {
1693
- accessSync(prefix, constants.W_OK);
1694
- }
1695
- catch {
1696
- needsSudo = true;
1697
- }
1698
- }
1699
- catch { /* assume no sudo needed */ }
1700
1724
  if (needsSudo) {
1701
1725
  // ── nvm path: install without sudo ──
1702
1726
  if (!existsSync(nvmSh)) {
@@ -1728,6 +1752,9 @@ program
1728
1752
  process.once("exit", () => releaseLock());
1729
1753
  const installed = runUpdateInstall({
1730
1754
  pkg, targetVersion, viaNvm: needsSudo, nvmSh, rollback: true,
1755
+ ...(preflight && targetVersion && needsSudo
1756
+ ? { preflight: preflight.installPreflight(pkg, targetVersion, "the Node 22 nvm selected", { log: m => console.log(m), error: m => console.error(m) }) }
1757
+ : {}),
1731
1758
  lock: prefix => {
1732
1759
  const lock = acquireInstallLock(prefix, { spec: pkg, agendHome: DATA_DIR }, {
1733
1760
  pid: process.pid, processStart: admission.processStart, newToken: () => randomBytes(16).toString("hex"),
@@ -1786,7 +1813,19 @@ program
1786
1813
  .option("--activate", "Deprecated; service activation is now the default")
1787
1814
  .option("--no-activate", "Write the service file without activating it")
1788
1815
  .action(async (opts) => {
1789
- const { installService, activateService, detectPlatform, renderLaunchdPlist, launchdPlistPath } = await import("./service-installer.js");
1816
+ const { installService, activateService, detectPlatform, renderLaunchdPlist, launchdPlistPath, getServicePath, getSystemServicePath } = await import("./service-installer.js");
1817
+ // #1631 B: an older updater (2.2.0-beta.1 and before) refreshes a hand-started fleet's service too, through this
1818
+ // command — which would CREATE a unit or plist, and every later update would then take a manager it may not reach
1819
+ // as the authority. When no service exists and it is certain this is that updater's refresh, write nothing. A
1820
+ // manual `agend install` (with or without --no-activate) creates the service as always.
1821
+ if (opts.activate === false && getServicePath() === null && getSystemServicePath() === null) {
1822
+ const { startedByUpdater, systemUpdaterCallerProbe } = await import("./updater-caller.js");
1823
+ const caller = startedByUpdater(systemUpdaterCallerProbe(DATA_DIR, pkgVersion));
1824
+ if (caller.updater) {
1825
+ console.log(" No service to refresh: this update runs a hand-started fleet, so none was created (`agend install` creates one).");
1826
+ return;
1827
+ }
1828
+ }
1790
1829
  const execPath = canonicalCliEntry();
1791
1830
  const serviceVars = {
1792
1831
  label: "com.agend.fleet",
@@ -2578,7 +2617,7 @@ program
2578
2617
  console.log("Web token rotated.");
2579
2618
  console.log("Every previously issued dashboard link and browser session is now rejected.");
2580
2619
  console.log("A running fleet picks this up immediately — no restart needed.");
2581
- console.log("Sign in again with `agend web` (prints a one-time code), or /dashboard in your chat channel.");
2620
+ console.log("Sign in again with `agend web` (prints a one-time code), or /web in your chat channel.");
2582
2621
  });
2583
2622
  program
2584
2623
  .command("view")