@bd7pil/ocrc 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. package/LICENSE +34 -0
  2. package/README.md +330 -0
  3. package/dist/cli/host-backends.js +216 -0
  4. package/dist/cli/host-backends.js.map +1 -0
  5. package/dist/cli/host.js +185 -0
  6. package/dist/cli/host.js.map +1 -0
  7. package/dist/cli/index.js +67 -0
  8. package/dist/cli/index.js.map +1 -0
  9. package/dist/cli/init.js +68 -0
  10. package/dist/cli/init.js.map +1 -0
  11. package/dist/cli/install.js +220 -0
  12. package/dist/cli/install.js.map +1 -0
  13. package/dist/cli/pair.js +11 -0
  14. package/dist/cli/pair.js.map +1 -0
  15. package/dist/cli/uninstall.js +75 -0
  16. package/dist/cli/uninstall.js.map +1 -0
  17. package/dist/connectivity/auth/cf-access.js +20 -0
  18. package/dist/connectivity/auth/cf-access.js.map +1 -0
  19. package/dist/connectivity/auth/index.js +2 -0
  20. package/dist/connectivity/auth/index.js.map +1 -0
  21. package/dist/connectivity/auth/select.js +19 -0
  22. package/dist/connectivity/auth/select.js.map +1 -0
  23. package/dist/connectivity/auth/token.js +157 -0
  24. package/dist/connectivity/auth/token.js.map +1 -0
  25. package/dist/connectivity/exposure/cloudflared.js +77 -0
  26. package/dist/connectivity/exposure/cloudflared.js.map +1 -0
  27. package/dist/connectivity/exposure/index.js +2 -0
  28. package/dist/connectivity/exposure/index.js.map +1 -0
  29. package/dist/connectivity/exposure/providers.js +49 -0
  30. package/dist/connectivity/exposure/providers.js.map +1 -0
  31. package/dist/connectivity/pairing.js +29 -0
  32. package/dist/connectivity/pairing.js.map +1 -0
  33. package/dist/core/agent/acp-backend.js +539 -0
  34. package/dist/core/agent/acp-backend.js.map +1 -0
  35. package/dist/core/agent/acp-connect.js +92 -0
  36. package/dist/core/agent/acp-connect.js.map +1 -0
  37. package/dist/core/agent/acp-normalizer.js +81 -0
  38. package/dist/core/agent/acp-normalizer.js.map +1 -0
  39. package/dist/core/agent/acp-replay.js +89 -0
  40. package/dist/core/agent/acp-replay.js.map +1 -0
  41. package/dist/core/agent/acp-store.js +129 -0
  42. package/dist/core/agent/acp-store.js.map +1 -0
  43. package/dist/core/agent/backend.js +2 -0
  44. package/dist/core/agent/backend.js.map +1 -0
  45. package/dist/core/agent/diff-util.js +70 -0
  46. package/dist/core/agent/diff-util.js.map +1 -0
  47. package/dist/core/agent/event.js +12 -0
  48. package/dist/core/agent/event.js.map +1 -0
  49. package/dist/core/agent/opencode-backend.js +598 -0
  50. package/dist/core/agent/opencode-backend.js.map +1 -0
  51. package/dist/core/agent/opencode-normalizer.js +69 -0
  52. package/dist/core/agent/opencode-normalizer.js.map +1 -0
  53. package/dist/core/agent/registry.js +55 -0
  54. package/dist/core/agent/registry.js.map +1 -0
  55. package/dist/core/agent/v2-backend.js +176 -0
  56. package/dist/core/agent/v2-backend.js.map +1 -0
  57. package/dist/core/card-bus.js +74 -0
  58. package/dist/core/card-bus.js.map +1 -0
  59. package/dist/core/channels.js +95 -0
  60. package/dist/core/channels.js.map +1 -0
  61. package/dist/core/history.js +91 -0
  62. package/dist/core/history.js.map +1 -0
  63. package/dist/core/list-files.js +50 -0
  64. package/dist/core/list-files.js.map +1 -0
  65. package/dist/core/opencode-events.js +29 -0
  66. package/dist/core/opencode-events.js.map +1 -0
  67. package/dist/core/primary-election.js +91 -0
  68. package/dist/core/primary-election.js.map +1 -0
  69. package/dist/core/push.js +152 -0
  70. package/dist/core/push.js.map +1 -0
  71. package/dist/core/relay.js +400 -0
  72. package/dist/core/relay.js.map +1 -0
  73. package/dist/core/scheduler.js +150 -0
  74. package/dist/core/scheduler.js.map +1 -0
  75. package/dist/core/state.js +222 -0
  76. package/dist/core/state.js.map +1 -0
  77. package/dist/core/stream-accumulator.js +76 -0
  78. package/dist/core/stream-accumulator.js.map +1 -0
  79. package/dist/core/structured-card.js +2 -0
  80. package/dist/core/structured-card.js.map +1 -0
  81. package/dist/core/types.js +2 -0
  82. package/dist/core/types.js.map +1 -0
  83. package/dist/index.js +3 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/opencode/global-events.js +57 -0
  86. package/dist/opencode/global-events.js.map +1 -0
  87. package/dist/opencode/list-sessions.js +122 -0
  88. package/dist/opencode/list-sessions.js.map +1 -0
  89. package/dist/opencode/submit.js +39 -0
  90. package/dist/opencode/submit.js.map +1 -0
  91. package/dist/opencode/workspaces.js +51 -0
  92. package/dist/opencode/workspaces.js.map +1 -0
  93. package/dist/plugin/config.js +128 -0
  94. package/dist/plugin/config.js.map +1 -0
  95. package/dist/plugin/control-plane.js +133 -0
  96. package/dist/plugin/control-plane.js.map +1 -0
  97. package/dist/plugin/entry.js +409 -0
  98. package/dist/plugin/entry.js.map +1 -0
  99. package/dist/plugin/v2/event-map.js +193 -0
  100. package/dist/plugin/v2/event-map.js.map +1 -0
  101. package/dist/plugin/v2/types.js +15 -0
  102. package/dist/plugin/v2/types.js.map +1 -0
  103. package/dist/transport/interface.js +2 -0
  104. package/dist/transport/interface.js.map +1 -0
  105. package/dist/transport/telegram/esc.js +9 -0
  106. package/dist/transport/telegram/esc.js.map +1 -0
  107. package/dist/transport/telegram/handlers/info-commands.js +101 -0
  108. package/dist/transport/telegram/handlers/info-commands.js.map +1 -0
  109. package/dist/transport/telegram/handlers.js +1348 -0
  110. package/dist/transport/telegram/handlers.js.map +1 -0
  111. package/dist/transport/telegram/i18n/en.js +538 -0
  112. package/dist/transport/telegram/i18n/en.js.map +1 -0
  113. package/dist/transport/telegram/i18n/index.js +83 -0
  114. package/dist/transport/telegram/i18n/index.js.map +1 -0
  115. package/dist/transport/telegram/i18n/zh.js +538 -0
  116. package/dist/transport/telegram/i18n/zh.js.map +1 -0
  117. package/dist/transport/telegram/index.js +792 -0
  118. package/dist/transport/telegram/index.js.map +1 -0
  119. package/dist/transport/telegram/main-keyboard.js +36 -0
  120. package/dist/transport/telegram/main-keyboard.js.map +1 -0
  121. package/dist/transport/telegram/managers/abort-suppression-manager.js +33 -0
  122. package/dist/transport/telegram/managers/abort-suppression-manager.js.map +1 -0
  123. package/dist/transport/telegram/managers/external-input-suppression-manager.js +51 -0
  124. package/dist/transport/telegram/managers/external-input-suppression-manager.js.map +1 -0
  125. package/dist/transport/telegram/managers/interaction-manager.js +254 -0
  126. package/dist/transport/telegram/managers/interaction-manager.js.map +1 -0
  127. package/dist/transport/telegram/managers/permission-manager.js +242 -0
  128. package/dist/transport/telegram/managers/permission-manager.js.map +1 -0
  129. package/dist/transport/telegram/managers/question-manager.js +191 -0
  130. package/dist/transport/telegram/managers/question-manager.js.map +1 -0
  131. package/dist/transport/telegram/managers/rename-manager.js +56 -0
  132. package/dist/transport/telegram/managers/rename-manager.js.map +1 -0
  133. package/dist/transport/telegram/menus.js +77 -0
  134. package/dist/transport/telegram/menus.js.map +1 -0
  135. package/dist/transport/telegram/permission-flow.js +156 -0
  136. package/dist/transport/telegram/permission-flow.js.map +1 -0
  137. package/dist/transport/telegram/question-flow.js +224 -0
  138. package/dist/transport/telegram/question-flow.js.map +1 -0
  139. package/dist/transport/telegram/render/block-parser.js +365 -0
  140. package/dist/transport/telegram/render/block-parser.js.map +1 -0
  141. package/dist/transport/telegram/render/block-plain-text.js +87 -0
  142. package/dist/transport/telegram/render/block-plain-text.js.map +1 -0
  143. package/dist/transport/telegram/render/block-splitter.js +152 -0
  144. package/dist/transport/telegram/render/block-splitter.js.map +1 -0
  145. package/dist/transport/telegram/render/chunker.js +71 -0
  146. package/dist/transport/telegram/render/chunker.js.map +1 -0
  147. package/dist/transport/telegram/render/limits.js +13 -0
  148. package/dist/transport/telegram/render/limits.js.map +1 -0
  149. package/dist/transport/telegram/render/markdown-normalizer.js +102 -0
  150. package/dist/transport/telegram/render/markdown-normalizer.js.map +1 -0
  151. package/dist/transport/telegram/render/markdown-to-telegram-v2.js +116 -0
  152. package/dist/transport/telegram/render/markdown-to-telegram-v2.js.map +1 -0
  153. package/dist/transport/telegram/render/part-signature.js +14 -0
  154. package/dist/transport/telegram/render/part-signature.js.map +1 -0
  155. package/dist/transport/telegram/render/pipeline.js +23 -0
  156. package/dist/transport/telegram/render/pipeline.js.map +1 -0
  157. package/dist/transport/telegram/render/rich-blocks.js +311 -0
  158. package/dist/transport/telegram/render/rich-blocks.js.map +1 -0
  159. package/dist/transport/telegram/render/text-splitter.js +64 -0
  160. package/dist/transport/telegram/render/text-splitter.js.map +1 -0
  161. package/dist/transport/telegram/render/types.js +2 -0
  162. package/dist/transport/telegram/render/types.js.map +1 -0
  163. package/dist/transport/telegram/renderer.js +305 -0
  164. package/dist/transport/telegram/renderer.js.map +1 -0
  165. package/dist/transport/telegram/streaming/duration-formatter.js +68 -0
  166. package/dist/transport/telegram/streaming/duration-formatter.js.map +1 -0
  167. package/dist/transport/telegram/streaming/finalize-assistant-response.js +37 -0
  168. package/dist/transport/telegram/streaming/finalize-assistant-response.js.map +1 -0
  169. package/dist/transport/telegram/streaming/response-streamer.js +400 -0
  170. package/dist/transport/telegram/streaming/response-streamer.js.map +1 -0
  171. package/dist/transport/telegram/streaming/running-tool-tracker.js +150 -0
  172. package/dist/transport/telegram/streaming/running-tool-tracker.js.map +1 -0
  173. package/dist/transport/telegram/streaming/stream-throttle.js +57 -0
  174. package/dist/transport/telegram/streaming/stream-throttle.js.map +1 -0
  175. package/dist/transport/telegram/streaming/tool-call-streamer.js +390 -0
  176. package/dist/transport/telegram/streaming/tool-call-streamer.js.map +1 -0
  177. package/dist/transport/telegram/streaming-render.js +182 -0
  178. package/dist/transport/telegram/streaming-render.js.map +1 -0
  179. package/dist/transport/telegram/types/interaction.js +2 -0
  180. package/dist/transport/telegram/types/interaction.js.map +1 -0
  181. package/dist/transport/telegram/types/model.js +25 -0
  182. package/dist/transport/telegram/types/model.js.map +1 -0
  183. package/dist/transport/telegram/types/permission.js +2 -0
  184. package/dist/transport/telegram/types/permission.js.map +1 -0
  185. package/dist/transport/telegram/types/question.js +2 -0
  186. package/dist/transport/telegram/types/question.js.map +1 -0
  187. package/dist/transport/telegram/types/rename.js +2 -0
  188. package/dist/transport/telegram/types/rename.js.map +1 -0
  189. package/dist/transport/telegram/types/scheduled-task.js +23 -0
  190. package/dist/transport/telegram/types/scheduled-task.js.map +1 -0
  191. package/dist/transport/telegram/types/session.js +2 -0
  192. package/dist/transport/telegram/types/session.js.map +1 -0
  193. package/dist/transport/telegram/ui.js +28 -0
  194. package/dist/transport/telegram/ui.js.map +1 -0
  195. package/dist/transport/web/index.js +148 -0
  196. package/dist/transport/web/index.js.map +1 -0
  197. package/dist/transport/web/middleware/cf-access.js +104 -0
  198. package/dist/transport/web/middleware/cf-access.js.map +1 -0
  199. package/dist/transport/web/opencode-config.js +15 -0
  200. package/dist/transport/web/opencode-config.js.map +1 -0
  201. package/dist/transport/web/routes/abort.js +12 -0
  202. package/dist/transport/web/routes/abort.js.map +1 -0
  203. package/dist/transport/web/routes/approval.js +16 -0
  204. package/dist/transport/web/routes/approval.js.map +1 -0
  205. package/dist/transport/web/routes/catalog.js +11 -0
  206. package/dist/transport/web/routes/catalog.js.map +1 -0
  207. package/dist/transport/web/routes/channels.js +53 -0
  208. package/dist/transport/web/routes/channels.js.map +1 -0
  209. package/dist/transport/web/routes/commands.js +15 -0
  210. package/dist/transport/web/routes/commands.js.map +1 -0
  211. package/dist/transport/web/routes/context.js +17 -0
  212. package/dist/transport/web/routes/context.js.map +1 -0
  213. package/dist/transport/web/routes/controls.js +34 -0
  214. package/dist/transport/web/routes/controls.js.map +1 -0
  215. package/dist/transport/web/routes/create-session.js +21 -0
  216. package/dist/transport/web/routes/create-session.js.map +1 -0
  217. package/dist/transport/web/routes/diff.js +7 -0
  218. package/dist/transport/web/routes/diff.js.map +1 -0
  219. package/dist/transport/web/routes/files.js +22 -0
  220. package/dist/transport/web/routes/files.js.map +1 -0
  221. package/dist/transport/web/routes/logs.js +9 -0
  222. package/dist/transport/web/routes/logs.js.map +1 -0
  223. package/dist/transport/web/routes/m8.js +69 -0
  224. package/dist/transport/web/routes/m8.js.map +1 -0
  225. package/dist/transport/web/routes/mcp.js +7 -0
  226. package/dist/transport/web/routes/mcp.js.map +1 -0
  227. package/dist/transport/web/routes/message.js +32 -0
  228. package/dist/transport/web/routes/message.js.map +1 -0
  229. package/dist/transport/web/routes/overrides.js +20 -0
  230. package/dist/transport/web/routes/overrides.js.map +1 -0
  231. package/dist/transport/web/routes/question.js +32 -0
  232. package/dist/transport/web/routes/question.js.map +1 -0
  233. package/dist/transport/web/routes/rename.js +12 -0
  234. package/dist/transport/web/routes/rename.js.map +1 -0
  235. package/dist/transport/web/routes/schedules.js +28 -0
  236. package/dist/transport/web/routes/schedules.js.map +1 -0
  237. package/dist/transport/web/routes/session.js +20 -0
  238. package/dist/transport/web/routes/session.js.map +1 -0
  239. package/dist/transport/web/routes/sessions.js +25 -0
  240. package/dist/transport/web/routes/sessions.js.map +1 -0
  241. package/dist/transport/web/routes/subagents.js +11 -0
  242. package/dist/transport/web/routes/subagents.js.map +1 -0
  243. package/dist/transport/web/routes/suggestions.js +7 -0
  244. package/dist/transport/web/routes/suggestions.js.map +1 -0
  245. package/dist/transport/web/routes/todo.js +7 -0
  246. package/dist/transport/web/routes/todo.js.map +1 -0
  247. package/dist/transport/web/routes/version.js +5 -0
  248. package/dist/transport/web/routes/version.js.map +1 -0
  249. package/dist/transport/web/routes/workspaces.js +7 -0
  250. package/dist/transport/web/routes/workspaces.js.map +1 -0
  251. package/dist/transport/web/server.js +111 -0
  252. package/dist/transport/web/server.js.map +1 -0
  253. package/dist/transport/web/session-summary.js +46 -0
  254. package/dist/transport/web/session-summary.js.map +1 -0
  255. package/dist/transport/web/ws-hub.js +83 -0
  256. package/dist/transport/web/ws-hub.js.map +1 -0
  257. package/dist/utils/logger.js +105 -0
  258. package/dist/utils/logger.js.map +1 -0
  259. package/dist/utils/markdown.js +129 -0
  260. package/dist/utils/markdown.js.map +1 -0
  261. package/dist/utils/paths.js +18 -0
  262. package/dist/utils/paths.js.map +1 -0
  263. package/dist/utils/version.js +44 -0
  264. package/dist/utils/version.js.map +1 -0
  265. package/package.json +91 -0
  266. package/web/dist/_app/env.js +1 -0
  267. package/web/dist/_app/immutable/assets/0.DxN3RsuG.css +1 -0
  268. package/web/dist/_app/immutable/assets/2.BNuGfmZP.css +1 -0
  269. package/web/dist/_app/immutable/assets/3.CTDprntu.css +1 -0
  270. package/web/dist/_app/immutable/chunks/BUpwHpMJ.js +1 -0
  271. package/web/dist/_app/immutable/chunks/BjY4dxcB.js +2 -0
  272. package/web/dist/_app/immutable/chunks/C2FuqD3s.js +1 -0
  273. package/web/dist/_app/immutable/chunks/CUHGq08X.js +2 -0
  274. package/web/dist/_app/immutable/chunks/CWj6FrbW.js +1 -0
  275. package/web/dist/_app/immutable/chunks/ClvoqtGj.js +1 -0
  276. package/web/dist/_app/immutable/chunks/DIEDQ_hk.js +1 -0
  277. package/web/dist/_app/immutable/entry/app.BoRpcVMj.js +2 -0
  278. package/web/dist/_app/immutable/entry/start.Cj-PQNTq.js +1 -0
  279. package/web/dist/_app/immutable/nodes/0.y9YEms5p.js +3 -0
  280. package/web/dist/_app/immutable/nodes/1.CPhhiRM2.js +1 -0
  281. package/web/dist/_app/immutable/nodes/2.B_c84Mc9.js +1 -0
  282. package/web/dist/_app/immutable/nodes/3.ClTd0J3D.js +64 -0
  283. package/web/dist/_app/version.json +1 -0
  284. package/web/dist/apple-touch-icon.png +0 -0
  285. package/web/dist/favicon.png +0 -0
  286. package/web/dist/favicon.svg +17 -0
  287. package/web/dist/icon-192.png +0 -0
  288. package/web/dist/icon-512-maskable.png +0 -0
  289. package/web/dist/icon-512.png +0 -0
  290. package/web/dist/index.html +73 -0
  291. package/web/dist/manifest.webmanifest +28 -0
  292. package/web/dist/service-worker.js +1 -0
@@ -0,0 +1,365 @@
1
+ import { toString } from "mdast-util-to-string";
2
+ import { unified } from "unified";
3
+ import remarkGfm from "remark-gfm";
4
+ import remarkParse from "remark-parse";
5
+ import { extractInlinePlainText as extractInlineNodeText } from "./block-plain-text.js";
6
+ import { normalizeMarkdownForTelegramBlockParsing } from "./markdown-normalizer.js";
7
+ const markdownProcessor = unified().use(remarkParse).use(remarkGfm);
8
+ /** Rich messages allow 16 nesting levels; deeper quotes and lists degrade to plain text. */
9
+ const MAX_NESTING_DEPTH = 6;
10
+ function pushTextNode(nodes, text) {
11
+ if (!text) {
12
+ return;
13
+ }
14
+ const previous = nodes.at(-1);
15
+ if (previous?.type === "text") {
16
+ previous.text += text;
17
+ return;
18
+ }
19
+ nodes.push({ type: "text", text });
20
+ }
21
+ function prefixLines(text, prefix) {
22
+ return text
23
+ .split("\n")
24
+ .map((line) => `${prefix}${line}`)
25
+ .join("\n");
26
+ }
27
+ function createPlainBlock(text) {
28
+ const normalized = text.trim();
29
+ if (!normalized) {
30
+ return [];
31
+ }
32
+ return [{ type: "plain", text: normalized }];
33
+ }
34
+ function extractInlinePlainText(nodes) {
35
+ let result = "";
36
+ for (const node of nodes) {
37
+ switch (node.type) {
38
+ case "text":
39
+ result += node.value;
40
+ break;
41
+ case "strong":
42
+ case "emphasis":
43
+ case "delete":
44
+ case "link":
45
+ result += extractInlinePlainText(node.children);
46
+ break;
47
+ case "inlineCode":
48
+ result += node.value;
49
+ break;
50
+ case "break":
51
+ result += "\n";
52
+ break;
53
+ case "image":
54
+ result += node.alt ?? "";
55
+ break;
56
+ case "imageReference":
57
+ result += node.alt ?? "";
58
+ break;
59
+ case "linkReference":
60
+ result += extractInlinePlainText(node.children);
61
+ break;
62
+ case "html":
63
+ result += node.value;
64
+ break;
65
+ case "footnoteReference":
66
+ result += `[^${node.identifier}]`;
67
+ break;
68
+ default:
69
+ result += toString(node);
70
+ break;
71
+ }
72
+ }
73
+ return result;
74
+ }
75
+ function extractTableCellPlainText(cell) {
76
+ return extractInlinePlainText(cell.children);
77
+ }
78
+ function extractListItemPlainText(item, index, ordered) {
79
+ const prefix = item.checked === true ? "✅ " : item.checked === false ? "🔲 " : "";
80
+ const marker = ordered ? `${index + 1}. ` : "- ";
81
+ const body = item.children.map(extractBlockPlainText).filter(Boolean).join("\n");
82
+ return `${marker}${prefix}${body}`.trimEnd();
83
+ }
84
+ function extractBlockPlainText(node) {
85
+ switch (node.type) {
86
+ case "paragraph":
87
+ case "heading":
88
+ return extractInlinePlainText(node.children);
89
+ case "blockquote":
90
+ return node.children
91
+ .map(extractBlockPlainText)
92
+ .filter(Boolean)
93
+ .map((text) => prefixLines(text, "> "))
94
+ .join("\n");
95
+ case "list":
96
+ return node.children
97
+ .map((item, index) => extractListItemPlainText(item, index, Boolean(node.ordered)))
98
+ .filter(Boolean)
99
+ .join("\n");
100
+ case "listItem":
101
+ return node.children.map(extractBlockPlainText).filter(Boolean).join("\n");
102
+ case "code":
103
+ return node.value;
104
+ case "table":
105
+ return node.children
106
+ .map((row) => row.children.map(extractTableCellPlainText).join(" | "))
107
+ .join("\n");
108
+ case "thematicBreak":
109
+ return "──────────";
110
+ case "html":
111
+ return node.value;
112
+ default:
113
+ return toString(node);
114
+ }
115
+ }
116
+ /**
117
+ * Inline HTML tags Telegram can express, mapped to the node that carries them.
118
+ * A tag outside this table stays visible as written: the markup may carry
119
+ * meaning of its own, and dropping it would hide that from the reader.
120
+ */
121
+ const INLINE_HTML_WRAPPERS = new Map([
122
+ ["b", "bold"],
123
+ ["strong", "bold"],
124
+ ["i", "italic"],
125
+ ["em", "italic"],
126
+ ["s", "strike"],
127
+ ["del", "strike"],
128
+ ["strike", "strike"],
129
+ ["u", "underline"],
130
+ ["ins", "underline"],
131
+ ["tg-spoiler", "spoiler"],
132
+ ["sub", "subscript"],
133
+ ["sup", "superscript"],
134
+ ["mark", "marked"],
135
+ // Telegram has no keyboard tag; monowidth is the closest thing it draws.
136
+ ["kbd", "code"],
137
+ ["code", "code"],
138
+ ]);
139
+ const INLINE_HTML_TAG_PATTERN = /^<(\/?)([a-z][a-z0-9-]*)(?:\s[^>]*?)?\/?>$/i;
140
+ /** Telegram's rich markdown marks text with `==`; remark leaves it in the text. */
141
+ const MARKED_TEXT_PATTERN = /==(?=\S)([\s\S]*?\S)==/g;
142
+ function parseInlineHtmlTag(value) {
143
+ const match = INLINE_HTML_TAG_PATTERN.exec(value.trim());
144
+ const name = match?.[2];
145
+ if (!name) {
146
+ return null;
147
+ }
148
+ return { name: name.toLowerCase(), closing: match[1] === "/" };
149
+ }
150
+ function closeInlineHtmlFrame(frame, closed) {
151
+ if (!closed) {
152
+ return [{ type: "text", text: frame.raw }, ...frame.nodes];
153
+ }
154
+ return frame.wrapper === "code"
155
+ ? [{ type: "code", text: extractInlineNodeText(frame.nodes) }]
156
+ : [{ type: frame.wrapper, children: frame.nodes }];
157
+ }
158
+ /** Appends parsed nodes, merging text across the seam so runs stay in one node. */
159
+ function pushInlineNodes(target, nodes) {
160
+ for (const node of nodes) {
161
+ if (node.type === "text") {
162
+ pushTextNode(target, node.text);
163
+ continue;
164
+ }
165
+ target.push(node);
166
+ }
167
+ }
168
+ function pushTextValue(nodes, value) {
169
+ let lastIndex = 0;
170
+ for (const match of value.matchAll(MARKED_TEXT_PATTERN)) {
171
+ pushTextNode(nodes, value.slice(lastIndex, match.index));
172
+ nodes.push({ type: "marked", children: [{ type: "text", text: match[1] ?? "" }] });
173
+ lastIndex = match.index + match[0].length;
174
+ }
175
+ pushTextNode(nodes, value.slice(lastIndex));
176
+ }
177
+ function parseInlineNodes(nodes) {
178
+ const result = [];
179
+ /** Tags opened but not yet closed; the innermost one collects what follows. */
180
+ const open = [];
181
+ const target = () => open.at(-1)?.nodes ?? result;
182
+ for (const node of nodes) {
183
+ switch (node.type) {
184
+ case "text":
185
+ pushTextValue(target(), node.value);
186
+ break;
187
+ case "strong": {
188
+ const children = parseInlineNodes(node.children);
189
+ if (!children) {
190
+ return null;
191
+ }
192
+ target().push({ type: "bold", children });
193
+ break;
194
+ }
195
+ case "emphasis": {
196
+ const children = parseInlineNodes(node.children);
197
+ if (!children) {
198
+ return null;
199
+ }
200
+ target().push({ type: "italic", children });
201
+ break;
202
+ }
203
+ case "delete": {
204
+ const children = parseInlineNodes(node.children);
205
+ if (!children) {
206
+ return null;
207
+ }
208
+ target().push({ type: "strike", children });
209
+ break;
210
+ }
211
+ case "inlineCode":
212
+ target().push({ type: "code", text: node.value });
213
+ break;
214
+ case "link": {
215
+ const children = parseInlineNodes(node.children);
216
+ if (!children) {
217
+ return null;
218
+ }
219
+ target().push({ type: "link", text: children, url: node.url });
220
+ break;
221
+ }
222
+ case "break":
223
+ pushTextNode(target(), "\n");
224
+ break;
225
+ case "html": {
226
+ const tag = parseInlineHtmlTag(node.value);
227
+ if (!tag) {
228
+ return null;
229
+ }
230
+ if (tag.name === "br") {
231
+ pushTextNode(target(), "\n");
232
+ break;
233
+ }
234
+ if (!tag.closing) {
235
+ const wrapper = INLINE_HTML_WRAPPERS.get(tag.name);
236
+ if (wrapper) {
237
+ open.push({ name: tag.name, wrapper, raw: node.value, nodes: [] });
238
+ }
239
+ else {
240
+ pushTextNode(target(), node.value);
241
+ }
242
+ break;
243
+ }
244
+ const index = open.map((frame) => frame.name).lastIndexOf(tag.name);
245
+ if (index === -1) {
246
+ pushTextNode(target(), node.value);
247
+ break;
248
+ }
249
+ // Tags opened inside the one being closed never closed themselves:
250
+ // they keep their markup visible along with their content.
251
+ while (open.length > index) {
252
+ const frame = open.pop();
253
+ if (!frame) {
254
+ break;
255
+ }
256
+ pushInlineNodes(target(), closeInlineHtmlFrame(frame, open.length === index));
257
+ }
258
+ break;
259
+ }
260
+ default:
261
+ return null;
262
+ }
263
+ }
264
+ while (open.length > 0) {
265
+ const frame = open.pop();
266
+ if (!frame) {
267
+ break;
268
+ }
269
+ pushInlineNodes(target(), closeInlineHtmlFrame(frame, false));
270
+ }
271
+ return result;
272
+ }
273
+ function parseParagraphBlock(node) {
274
+ const inlines = parseInlineNodes(node.children);
275
+ if (!inlines) {
276
+ return createPlainBlock(extractBlockPlainText(node));
277
+ }
278
+ return [{ type: "paragraph", inlines }];
279
+ }
280
+ function parseHeadingBlock(node) {
281
+ const inlines = parseInlineNodes(node.children);
282
+ if (!inlines) {
283
+ return createPlainBlock(extractBlockPlainText(node));
284
+ }
285
+ return [
286
+ {
287
+ type: "heading",
288
+ level: Math.min(6, Math.max(1, Math.floor(node.depth))),
289
+ inlines,
290
+ },
291
+ ];
292
+ }
293
+ function parseBlockquoteBlock(node, depth) {
294
+ if (depth >= MAX_NESTING_DEPTH) {
295
+ return createPlainBlock(extractBlockPlainText(node));
296
+ }
297
+ const blocks = node.children.flatMap((child) => parseRootContent(child, depth + 1));
298
+ if (blocks.length === 0) {
299
+ return [];
300
+ }
301
+ return [{ type: "blockquote", blocks }];
302
+ }
303
+ function parseListItem(item, depth) {
304
+ return {
305
+ blocks: item.children.flatMap((child) => parseRootContent(child, depth)),
306
+ ...(typeof item.checked === "boolean" ? { checked: item.checked } : {}),
307
+ };
308
+ }
309
+ function parseListBlock(node, depth) {
310
+ if (depth >= MAX_NESTING_DEPTH) {
311
+ return createPlainBlock(extractBlockPlainText(node));
312
+ }
313
+ const items = node.children.map((item) => parseListItem(item, depth + 1));
314
+ if (items.length === 0) {
315
+ return [];
316
+ }
317
+ return [{ type: "list", ordered: Boolean(node.ordered), items }];
318
+ }
319
+ function parseCodeBlock(node) {
320
+ return [{ type: "code", language: node.lang ?? undefined, text: node.value }];
321
+ }
322
+ /** Markdown declares column alignment in the delimiter row; unset columns stay left. */
323
+ function parseColumnAlign(align) {
324
+ if (!align || align.every((value) => value === null)) {
325
+ return undefined;
326
+ }
327
+ return align.map((value) => value ?? "left");
328
+ }
329
+ function parseTableBlock(node) {
330
+ const rows = node.children.map((row) => row.children.map(extractTableCellPlainText));
331
+ if (rows.length === 0) {
332
+ return [];
333
+ }
334
+ const align = parseColumnAlign(node.align);
335
+ return [{ type: "table", rows, ...(align ? { align } : {}) }];
336
+ }
337
+ function parseRootContent(node, depth = 0) {
338
+ switch (node.type) {
339
+ case "paragraph":
340
+ return parseParagraphBlock(node);
341
+ case "heading":
342
+ return parseHeadingBlock(node);
343
+ case "blockquote":
344
+ return parseBlockquoteBlock(node, depth);
345
+ case "list":
346
+ return parseListBlock(node, depth);
347
+ case "code":
348
+ return parseCodeBlock(node);
349
+ case "table":
350
+ return parseTableBlock(node);
351
+ case "thematicBreak":
352
+ return [{ type: "rule" }];
353
+ default:
354
+ return createPlainBlock(extractBlockPlainText(node));
355
+ }
356
+ }
357
+ export function parseTelegramBlocks(markdown) {
358
+ const normalized = normalizeMarkdownForTelegramBlockParsing(markdown).trim();
359
+ if (!normalized) {
360
+ return [];
361
+ }
362
+ const tree = markdownProcessor.parse(normalized);
363
+ return tree.children.flatMap((node) => parseRootContent(node));
364
+ }
365
+ //# sourceMappingURL=block-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-parser.js","sourceRoot":"","sources":["../../../../src/transport/telegram/render/block-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ export function extractInlinePlainText(nodes) {
2
+ let result = "";
3
+ for (const node of nodes) {
4
+ switch (node.type) {
5
+ case "text":
6
+ result += node.text;
7
+ break;
8
+ case "bold":
9
+ case "italic":
10
+ case "strike":
11
+ case "underline":
12
+ case "spoiler":
13
+ case "subscript":
14
+ case "superscript":
15
+ case "marked":
16
+ result += extractInlinePlainText(node.children);
17
+ break;
18
+ case "code":
19
+ result += node.text;
20
+ break;
21
+ case "link":
22
+ result += extractInlinePlainText(node.text);
23
+ break;
24
+ default: {
25
+ const exhaustiveCheck = node;
26
+ throw new Error(`Unsupported inline node: ${JSON.stringify(exhaustiveCheck)}`);
27
+ }
28
+ }
29
+ }
30
+ return result;
31
+ }
32
+ export function buildAlignedTableText(rows) {
33
+ const columnCount = Math.max(...rows.map((row) => row.length));
34
+ const normalizedRows = rows.map((row) => Array.from({ length: columnCount }, (_, index) => row[index] ?? ""));
35
+ const columnWidths = Array.from({ length: columnCount }, (_, index) => Math.max(...normalizedRows.map((row) => row[index]?.length ?? 0)));
36
+ const formatRow = (row) => row.map((cell, index) => cell.padEnd(columnWidths[index] ?? 0, " ")).join(" | ");
37
+ const divider = columnWidths.map((width) => "-".repeat(width)).join("-|-");
38
+ const formattedRows = normalizedRows.map(formatRow);
39
+ if (formattedRows.length <= 1) {
40
+ return formattedRows.join("\n");
41
+ }
42
+ return [formattedRows[0], divider, ...formattedRows.slice(1)].join("\n");
43
+ }
44
+ function buildListItemText(item, index, ordered, start) {
45
+ // A task item states its state in the marker; a bullet in front reads as a second one.
46
+ const taskPrefix = item.checked === true ? "✅ " : item.checked === false ? "🔲 " : "";
47
+ const marker = ordered ? `${start + index}. ${taskPrefix}` : taskPrefix || "- ";
48
+ const continuationPrefix = " ".repeat(marker.length);
49
+ const body = item.blocks.map(toBlockPlainText).filter(Boolean).join("\n");
50
+ return body
51
+ .split("\n")
52
+ .map((line, lineIndex) => `${lineIndex === 0 ? marker : continuationPrefix}${line}`)
53
+ .join("\n");
54
+ }
55
+ export function toBlockPlainText(block) {
56
+ switch (block.type) {
57
+ case "paragraph":
58
+ case "heading":
59
+ return extractInlinePlainText(block.inlines);
60
+ case "blockquote":
61
+ return block.blocks
62
+ .map(toBlockPlainText)
63
+ .filter(Boolean)
64
+ .map((text) => text
65
+ .split("\n")
66
+ .map((line) => `> ${line}`)
67
+ .join("\n"))
68
+ .join("\n");
69
+ case "list":
70
+ return block.items
71
+ .map((item, index) => buildListItemText(item, index, block.ordered, block.start ?? 1))
72
+ .join("\n");
73
+ case "code":
74
+ return block.text;
75
+ case "table":
76
+ return buildAlignedTableText(block.rows);
77
+ case "rule":
78
+ return "──────────";
79
+ case "plain":
80
+ return block.text;
81
+ default: {
82
+ const exhaustiveCheck = block;
83
+ throw new Error(`Unsupported Telegram block: ${JSON.stringify(exhaustiveCheck)}`);
84
+ }
85
+ }
86
+ }
87
+ //# sourceMappingURL=block-plain-text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-plain-text.js","sourceRoot":"","sources":["../../../../src/transport/telegram/render/block-plain-text.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,152 @@
1
+ import { createLogger } from "../../../utils/logger.js";
2
+ const logger = createLogger("render");
3
+ import { toBlockPlainText } from "./block-plain-text.js";
4
+ import { DEFAULT_MAX_PART_BLOCKS, DEFAULT_MAX_PART_CHARS } from "./limits.js";
5
+ import { countRichBlocks, countRichChars, isTextRenderedList, textListMarker, toRichBlock, } from "./rich-blocks.js";
6
+ import { splitTextIntoChunks } from "./text-splitter.js";
7
+ export function normalizeBlockSplitLimits(limits) {
8
+ return {
9
+ maxChars: Math.max(1, Math.floor(limits?.maxChars ?? DEFAULT_MAX_PART_CHARS)),
10
+ maxBlocks: Math.max(1, Math.floor(limits?.maxBlocks ?? DEFAULT_MAX_PART_BLOCKS)),
11
+ };
12
+ }
13
+ function fitsLimits(block, limits) {
14
+ const richBlock = toRichBlock(block);
15
+ return (countRichChars(richBlock) <= limits.maxChars && countRichBlocks(richBlock) <= limits.maxBlocks);
16
+ }
17
+ /**
18
+ * Splits items into groups so that every group stays within `maxChars` and
19
+ * contains at most `maxItems` entries. A single oversize item still lands in a
20
+ * group of its own; the caller degrades it afterwards.
21
+ */
22
+ function groupItems(items, maxChars, maxItems, measureChars) {
23
+ const itemLimit = Math.max(1, maxItems);
24
+ const groups = [];
25
+ let current = [];
26
+ let currentChars = 0;
27
+ for (const item of items) {
28
+ const itemChars = measureChars(item);
29
+ if (current.length > 0 &&
30
+ (current.length >= itemLimit || currentChars + itemChars > maxChars)) {
31
+ groups.push(current);
32
+ current = [];
33
+ currentChars = 0;
34
+ }
35
+ current.push(item);
36
+ currentChars += itemChars;
37
+ }
38
+ if (current.length > 0) {
39
+ groups.push(current);
40
+ }
41
+ return groups;
42
+ }
43
+ function measureItem(item) {
44
+ return item.blocks.reduce((total, block) => total + toBlockPlainText(block).length + 1, 0);
45
+ }
46
+ /** Block units a native list item costs: the item itself plus its content. */
47
+ function measureItemUnits(item) {
48
+ return item.blocks.reduce((total, block) => total + countRichBlocks(toRichBlock(block)), 1);
49
+ }
50
+ /** A code block is one or two rich blocks regardless of line count, so only characters matter. */
51
+ function splitCodeBlock(text, language, limits) {
52
+ const lines = text.split("\n");
53
+ const groups = groupItems(lines, limits.maxChars, Number.MAX_SAFE_INTEGER, (line) => line.length + 1);
54
+ return groups.flatMap((group) => {
55
+ const groupText = group.join("\n");
56
+ return splitTextIntoChunks(groupText, limits.maxChars).map((chunk) => ({
57
+ type: "code",
58
+ language,
59
+ text: chunk,
60
+ }));
61
+ });
62
+ }
63
+ /** Rich table units: the table block itself plus one per row, header included. */
64
+ function splitTableBlock(rows, align, limits) {
65
+ const [header, ...bodyRows] = rows;
66
+ if (!header) {
67
+ return [];
68
+ }
69
+ const measureRow = (row) => row.reduce((total, cell) => total + cell.length, 0);
70
+ const groups = groupItems(bodyRows, Math.max(1, limits.maxChars - measureRow(header)), limits.maxBlocks - 2, measureRow);
71
+ const alignment = align ? { align } : {};
72
+ if (groups.length === 0) {
73
+ return [{ type: "table", rows: [header], ...alignment }];
74
+ }
75
+ return groups.map((group) => ({
76
+ type: "table",
77
+ rows: [header, ...group],
78
+ ...alignment,
79
+ }));
80
+ }
81
+ /** Rich quote units: the quote block itself plus whatever its content costs. */
82
+ function splitBlockquoteBlock(blocks, limits) {
83
+ const innerLimits = { maxChars: limits.maxChars, maxBlocks: Math.max(1, limits.maxBlocks - 1) };
84
+ const innerBlocks = blocks.flatMap((inner) => splitOversizeTelegramBlock(inner, innerLimits));
85
+ return groupItems(innerBlocks, innerLimits.maxChars, innerLimits.maxBlocks, (inner) => countRichChars(toRichBlock(inner))).map((group) => ({ type: "blockquote", blocks: group }));
86
+ }
87
+ function splitToPlainBlocks(block, limits) {
88
+ return splitTextIntoChunks(toBlockPlainText(block), limits.maxChars).map((text) => ({
89
+ type: "plain",
90
+ text,
91
+ }));
92
+ }
93
+ function splitByType(block, limits) {
94
+ switch (block.type) {
95
+ case "code":
96
+ return splitCodeBlock(block.text, block.language, limits);
97
+ case "table":
98
+ return block.rows.length > 1
99
+ ? splitTableBlock(block.rows, block.align, limits)
100
+ : splitToPlainBlocks(block, limits);
101
+ case "list":
102
+ if (isTextRenderedList(block)) {
103
+ // Written out as one paragraph, so only characters matter — including
104
+ // the marker and the line break each item adds.
105
+ const start = block.start ?? 1;
106
+ const measured = block.items.map((item, index) => ({
107
+ item,
108
+ chars: measureItem(item) + textListMarker(item, index, block.ordered, start).length + 1,
109
+ }));
110
+ let pieceStart = start;
111
+ return groupItems(measured, limits.maxChars, block.items.length, (entry) => entry.chars).map((group) => {
112
+ const piece = {
113
+ type: "list",
114
+ ordered: block.ordered,
115
+ items: group.map((entry) => entry.item),
116
+ start: pieceStart,
117
+ };
118
+ pieceStart += group.length;
119
+ return piece;
120
+ });
121
+ }
122
+ // Rich list units: the list block plus whatever each item costs. Items can
123
+ // hold nested lists, so the cap comes from the most expensive one.
124
+ return groupItems(block.items, limits.maxChars, Math.floor((limits.maxBlocks - 1) / Math.max(...block.items.map(measureItemUnits))), measureItem).map((items) => ({ type: "list", ordered: false, items }));
125
+ case "blockquote":
126
+ return splitBlockquoteBlock(block.blocks, limits);
127
+ default:
128
+ return splitToPlainBlocks(block, limits);
129
+ }
130
+ }
131
+ /**
132
+ * Breaks a block that exceeds the per-message budgets into blocks that fit.
133
+ * Structured blocks keep their type (code by lines, tables by rows with the
134
+ * header repeated, lists by items, quotes by lines); anything that still does
135
+ * not fit degrades to plain text.
136
+ */
137
+ export function splitOversizeTelegramBlock(block, limits) {
138
+ if (fitsLimits(block, limits)) {
139
+ return [block];
140
+ }
141
+ logger.debug("[TelegramRender] Splitting oversize block", {
142
+ blockType: block.type,
143
+ maxChars: limits.maxChars,
144
+ maxBlocks: limits.maxBlocks,
145
+ });
146
+ return splitByType(block, limits).flatMap((piece) => fitsLimits(piece, limits) ? [piece] : splitToPlainBlocks(piece, limits));
147
+ }
148
+ export function splitOversizeTelegramBlocks(blocks, limits) {
149
+ const normalizedLimits = normalizeBlockSplitLimits(limits);
150
+ return blocks.flatMap((block) => splitOversizeTelegramBlock(block, normalizedLimits));
151
+ }
152
+ //# sourceMappingURL=block-splitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-splitter.js","sourceRoot":"","sources":["../../../../src/transport/telegram/render/block-splitter.ts"],"names":[],"mappings":"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"}