@wenbin_wb/dsh-bridge 2.2.8 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/qq/node.js CHANGED
@@ -18,8 +18,7 @@ const STREAM_CHUNK_SIZE = 400
18
18
  /**
19
19
  * 将文本转成 QQ 安全 Markdown:
20
20
  * - 标题降级:QQ 仅标准支持 # 与 ##,超出(###、####)降级为 ## 或加粗
21
- * - 列表前空行:QQ 规定列表前若为普通文本必须有空行隔开,自动补齐空行
22
- * - 表格(| a | b | / |---|)降级为纯文本(QQ Markdown 不支持表格,会截断/报错)
21
+ * - 列表/表格前空行:QQ 规定列表前若为普通文本必须有空行隔开,自动补齐空行
23
22
  * - markdown 图片语法 ![alt](url) 转为链接 [alt](url)(避免图片转存失败导致整条失败)
24
23
  * - 代码块内容原样保留
25
24
  */
@@ -28,10 +27,7 @@ function sanitizeQQMarkdown(text) {
28
27
  const lines = String(text).split('\n')
29
28
  const out = []
30
29
  let inFence = false
31
- let inTable = false
32
- const isSep = (l) => /^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$/.test(l) && l.includes('-')
33
- const isTableRow = (l) => /^\s*\|.*\|\s*$/.test(l)
34
- const isListLine = (l) => /^\s*(-|\*|\d+\.)\s+/.test(l)
30
+ const isListOrTable = (l) => /^\s*(-|\*|\d+\.|\/|\|)\s+/.test(l) || /^\s*\|.*\|\s*$/.test(l)
35
31
  const isHeading = (l) => /^\s*#{1,6}\s+/.test(l)
36
32
 
37
33
  for (let i = 0; i < lines.length; i++) {
@@ -43,18 +39,6 @@ function sanitizeQQMarkdown(text) {
43
39
  }
44
40
  if (inFence) { out.push(line); continue }
45
41
 
46
- // 表格处理
47
- const nextIsSep = i + 1 < lines.length && isSep(lines[i + 1])
48
- if (isTableRow(line) && (inTable || nextIsSep)) {
49
- inTable = true
50
- if (!isSep(line)) {
51
- // 去掉首尾 |,内部 | 转空格
52
- out.push(line.replace(/^\s*\|\s*/, '').replace(/\s*\|\s*$/, '').replace(/\s*\|\s*/g, ' '))
53
- }
54
- continue
55
- }
56
- inTable = false
57
-
58
42
  // 标题级别规范化:QQ 标准支持 # 和 ##,超出(###+)统一转为 ##
59
43
  if (isHeading(line)) {
60
44
  line = line.replace(/^\s*#{3,}\s+/, '## ')
@@ -63,10 +47,10 @@ function sanitizeQQMarkdown(text) {
63
47
  // 图片语法转为链接
64
48
  line = line.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '[$1]($2)')
65
49
 
66
- // 列表前空行保障:若前一行是非空普通文本且不是标题/列表/引用,则插入空行保证 QQ 正确解析列表
67
- if (isListLine(line) && out.length > 0) {
50
+ // 列表/表格前空行保障:若前一行是非空普通文本且不是标题/列表/引用/表格,则插入空行保证 QQ 正确解析
51
+ if (isListOrTable(line) && out.length > 0) {
68
52
  const prev = out[out.length - 1]
69
- if (prev && prev.trim() && !isListLine(prev) && !isHeading(prev) && !prev.startsWith('>')) {
53
+ if (prev && prev.trim() && !isListOrTable(prev) && !isHeading(prev) && !prev.startsWith('>')) {
70
54
  out.push('')
71
55
  }
72
56
  }
@@ -736,6 +736,9 @@ export class WechatGateway extends Service {
736
736
 
737
737
  consecutiveFailures = 0
738
738
  if (batch.syncBuf) this.syncBuf = batch.syncBuf
739
+ if (this.statusValue !== 'connected') {
740
+ this.logger?.info?.('[dsh-bridge wechat] connected to iLink platform')
741
+ }
739
742
  this.setStatus('connected')
740
743
  for (const message of batch.messages) {
741
744
  this.dispatchInbound(message)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@wenbin_wb/dsh-bridge",
3
- "version": "2.2.8",
4
- "description": "手机扫码即可在移动端/公网继续用 DeepSeek Harness,人不在电脑前也能接着干。一键局域网二维码、Cloudflare 公网隧道、自建隧道与微信 Bot(多工作区/会话持久化/媒体/审批),无需自己搭公网服务器。",
3
+ "version": "2.3.0",
4
+ "description": "手机扫码即可在移动端/公网继续用 DeepSeek Harness,人不在电脑前也能接着干。一键局域网二维码、Cloudflare 公网隧道、自建隧道与微信 / QQ / 飞书 Bot(多工作区/会话持久化/媒体/卡片审批/流式输出),无需自己搭公网服务器。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -21,13 +21,15 @@
21
21
  "docs/banner.jpg",
22
22
  "docs/custom-tunnel.md",
23
23
  "docs/wechat-usage.md",
24
- "docs/qq-usage.md"
24
+ "docs/qq-usage.md",
25
+ "docs/feishu-usage.md"
25
26
  ],
26
27
  "scripts": {
27
28
  "build:client": "node client/build.mjs",
28
29
  "test": "node --test test/*.test.mjs"
29
30
  },
30
31
  "dependencies": {
32
+ "@larksuiteoapi/node-sdk": "^1.73.0",
31
33
  "qrcode": "^1.5.3",
32
34
  "ws": "^8.18.0",
33
35
  "@deepseek-ai/dsh-llm": "0.1.0-rc.6"