From d3701730d4b9dff4f6c91628fc7a2af9958178c3 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Oct 2026 09:03:32 +0000 Subject: [PATCH 1/2] fix(messaging): ship the QQ and Lark Provider fixes in the bundled IM Provider Pin the dsh-im fork at 7505ce6f (DoodleBears/dsh-im#33 and #34) and move the bundled Provider to 4.32.0-botharness.23 so the release carries the QQ fixes (#2868, #2895, #2896, #2897, private messages for #2900) and Lark Markdown replies (#2792). Runtime files and digest are recomputed from the new source; manifest and lock are unchanged. The published Provider record still names .22 until the release publishes .23, so its test now requires the pin to equal or supersede it. Closes #2918 Refs #2792 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Lpx6qnuRKPyBQWbwohCfMZ --- changes/2918-im-provider-qq-lark.md | 13 +++++++++++++ docs/client-bridge.md | 2 +- docs/product-im-installation.md | 2 +- scripts/dev-im-provider.mjs | 8 ++++---- scripts/product-artifacts.mjs | 8 ++++---- scripts/test/npm-prerelease.test.mjs | 6 ++++-- scripts/test/product-artifacts.test.mjs | 4 ++-- 7 files changed, 29 insertions(+), 14 deletions(-) create mode 100644 changes/2918-im-provider-qq-lark.md diff --git a/changes/2918-im-provider-qq-lark.md b/changes/2918-im-provider-qq-lark.md new file mode 100644 index 0000000000..1376fa01a1 --- /dev/null +++ b/changes/2918-im-provider-qq-lark.md @@ -0,0 +1,13 @@ +--- +section: Fixed +--- + +## en + +- The bundled IM Provider moves to `4.32.0-botharness.23` and ships the QQ fixes. Bots on DSH 0.2.1 can create sessions again instead of failing with `INTERNAL_UNKNOWN` ([#2896](https://github.com/BotHarness/DeepSeekBot/issues/2896)). Quoted, image and mixed QQ messages are no longer dropped ([#2895](https://github.com/BotHarness/DeepSeekBot/issues/2895)). Concurrent QQ group replies retry on 429 ([#2897](https://github.com/BotHarness/DeepSeekBot/issues/2897)). Late QQ results are delivered as passive replies ([#2868](https://github.com/BotHarness/DeepSeekBot/issues/2868)). QQ private messages arrive in Bot mode ([#2918](https://github.com/BotHarness/DeepSeekBot/issues/2918)). +- Lark Bot mode replies that use Markdown are sent as a native Markdown card, so bold text, headings, lists and tables no longer show raw symbols. Plain replies and replies that @ someone stay text ([#2792](https://github.com/BotHarness/DeepSeekBot/issues/2792)). + +## zh + +- 内置 IM Provider 升级到 `4.32.0-botharness.23`,包含 QQ 修复。DSH 0.2.1 上的 Bot 可以重新创建会话,不再报 `INTERNAL_UNKNOWN`([#2896](https://github.com/BotHarness/DeepSeekBot/issues/2896))。QQ 的引用、图片和图文混合消息不再丢失([#2895](https://github.com/BotHarness/DeepSeekBot/issues/2895))。QQ 群内并发回复遇到 429 会重试([#2897](https://github.com/BotHarness/DeepSeekBot/issues/2897))。迟到的 QQ 结果会以被动回复送达([#2868](https://github.com/BotHarness/DeepSeekBot/issues/2868))。Bot 模式可以收到 QQ 私聊([#2918](https://github.com/BotHarness/DeepSeekBot/issues/2918))。 +- 飞书 Bot 模式中使用 Markdown 的回复改为原生 Markdown 卡片发送,加粗、标题、列表和表格不再显示原始符号。纯文本回复和 @ 他人的回复仍按文本发送([#2792](https://github.com/BotHarness/DeepSeekBot/issues/2792))。 diff --git a/docs/client-bridge.md b/docs/client-bridge.md index 380081b390..ad10477d5b 100644 --- a/docs/client-bridge.md +++ b/docs/client-bridge.md @@ -144,7 +144,7 @@ resolver cannot substitute workspace-linked Core/Client for the tarballs. node scripts/dev-instance.mjs --home /tmp/bh-im-qa --port 31968 --im-provider --json ``` -仅对已停止的隔离 Profile 执行;重启同一 Profile 时仍传入 `--im-provider`,以重复校验。当前 Provider 来源记录为 Git 完整提交 `beaed4a6dabb583654d28fb09298716267039b4a`,开发资格记录为 DSH `0.2.1-rc.2`,这些来源记录不限制实际启动的 DSH 版本;校验 Bundle、入口及运行时代码 digest 后才启动 Host;不依赖另一份 provider 本地源码。安装摘要明确标注 `upstreamReleased: false`。此完整 fork 保留附件、回显与独立回复身份契约;群/话题上下文读取绑定当前独占 Consumer 生命周期,释放或替换后拒绝返回正在读取的结果;上游 PR 是否合并不阻挡此固定提交使用([#789](https://github.com/BotHarness/BotHarness/issues/789))。默认启动不安装它,原 npm `4.32.0` 仍不满足账号校验和条件发送契约。此入口不会发布包,也不是生产启用许可([ADR-0104](adr/0104-isolated-im-profiles-pin-a-qualified-temporary-provider-fork.md))。 +仅对已停止的隔离 Profile 执行;重启同一 Profile 时仍传入 `--im-provider`,以重复校验。当前 Provider 来源记录为 Git 完整提交 `7505ce6fcda26c02810781fde9d4da81dab28a68`,开发资格记录为 DSH `0.2.1-rc.2`,这些来源记录不限制实际启动的 DSH 版本;校验 Bundle、入口及运行时代码 digest 后才启动 Host;不依赖另一份 provider 本地源码。安装摘要明确标注 `upstreamReleased: false`。此完整 fork 保留附件、回显与独立回复身份契约;群/话题上下文读取绑定当前独占 Consumer 生命周期,释放或替换后拒绝返回正在读取的结果;上游 PR 是否合并不阻挡此固定提交使用([#789](https://github.com/BotHarness/BotHarness/issues/789))。默认启动不安装它,原 npm `4.32.0` 仍不满足账号校验和条件发送契约。此入口不会发布包,也不是生产启用许可([ADR-0104](adr/0104-isolated-im-profiles-pin-a-qualified-temporary-provider-fork.md))。 在 dsh-im 原设置中配置测试应用,并保存、测试仅含测试者与 Bot 的目标群;凭据交由 DSH credentials service,不复制到 BotHarness。打开 PersonaBot Profile → IM connection,选择已认证账号与已测试目标,显式授权后发送一条唯一测试文本。预期 Recent sends 显示 Platform accepted,并在目标群核对同一文本;这不代表送达或已读。停止本次启动摘要中的确切 PID,再以相同参数启动:绑定与发送历史应保留,不自动重发。 diff --git a/docs/product-im-installation.md b/docs/product-im-installation.md index 40670488ac..7dd22d7a75 100644 --- a/docs/product-im-installation.md +++ b/docs/product-im-installation.md @@ -35,7 +35,7 @@ fails before packing. ```bash git clone https://github.com/DoodleBears/dsh-im.git /tmp/bh-im-source -git -C /tmp/bh-im-source checkout beaed4a6dabb583654d28fb09298716267039b4a +git -C /tmp/bh-im-source checkout 7505ce6fcda26c02810781fde9d4da81dab28a68 npm ci --prefix /tmp/bh-im-source --ignore-scripts --no-audit --no-fund pnpm install --frozen-lockfile pnpm build diff --git a/scripts/dev-im-provider.mjs b/scripts/dev-im-provider.mjs index ae99f30a47..ee3fa2b6f4 100644 --- a/scripts/dev-im-provider.mjs +++ b/scripts/dev-im-provider.mjs @@ -5,11 +5,11 @@ import { join } from 'node:path'; export const qualifiedImProvider = Object.freeze({ package: '@xmanrui/dsh-im', packageVersion: '4.32.0', - source: 'beaed4a6dabb583654d28fb09298716267039b4a', - spec: 'github:DoodleBears/dsh-im#beaed4a6dabb583654d28fb09298716267039b4a', + source: '7505ce6fcda26c02810781fde9d4da81dab28a68', + spec: 'github:DoodleBears/dsh-im#7505ce6fcda26c02810781fde9d4da81dab28a68', dsh: '0.2.1-rc.2', - runtimeFiles: 421, - runtimeSha256: '42e1140e67ba2f74122db3d49bb2c8aece239b7d75f9564ce713a8a491902706', + runtimeFiles: 424, + runtimeSha256: 'a4429580ebf70b08e19394cea97d7d0db9b86b06e1c92f294a28144378537d46', }); export function withQualifiedImProvider(manifest) { diff --git a/scripts/product-artifacts.mjs b/scripts/product-artifacts.mjs index 45e4ab930e..33683ac7d3 100644 --- a/scripts/product-artifacts.mjs +++ b/scripts/product-artifacts.mjs @@ -20,16 +20,16 @@ export const productDshVersions = Object.freeze(['0.2.0-rc.2', '0.2.1-rc.2', pro export const productImProvider = Object.freeze({ name: '@botharness/im-provider', - version: '4.32.0-botharness.22', + version: '4.32.0-botharness.23', sourceManifestSha256: '3331e8f771a91abf396eb4e7ed5c0acc4c3b504cdccc7d715e37062708384cc2', sourceLockSha256: '3476c34c7d4515000d2617beaf2568b2a794b60de9b350cd8eafb7a2bf21adef', upstream: Object.freeze({ package: '@xmanrui/dsh-im', packageVersion: '4.32.0', - source: 'beaed4a6dabb583654d28fb09298716267039b4a', + source: '7505ce6fcda26c02810781fde9d4da81dab28a68', dsh: '0.2.0-rc.2', - runtimeFiles: 421, - runtimeSha256: '42e1140e67ba2f74122db3d49bb2c8aece239b7d75f9564ce713a8a491902706', + runtimeFiles: 424, + runtimeSha256: 'a4429580ebf70b08e19394cea97d7d0db9b86b06e1c92f294a28144378537d46', }), }); diff --git a/scripts/test/npm-prerelease.test.mjs b/scripts/test/npm-prerelease.test.mjs index 14d8f8f7f8..59e63b5922 100644 --- a/scripts/test/npm-prerelease.test.mjs +++ b/scripts/test/npm-prerelease.test.mjs @@ -4,6 +4,7 @@ import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'nod import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterEach, describe, expect, it, vi } from 'vitest'; +import semver from 'semver'; import { awaitPublished, assertCleanReleaseSource, @@ -144,10 +145,11 @@ describe('reviewed npm prerelease', () => { it('pins the published product Provider separately from historical standalone publication', () => { expect(publishedProductProvider).toMatchObject({ name: productImProvider.name, - version: productImProvider.version, - providerSource: productImProvider.upstream.source, distTag: 'latest', }); + if (publishedProductProvider.version === productImProvider.version) + expect(publishedProductProvider.providerSource).toBe(productImProvider.upstream.source); + else expect(semver.gt(productImProvider.version, publishedProductProvider.version)).toBe(true); expect(publishedProductProvider.version).toMatch(/^\d+\.\d+\.\d+-botharness\.\d+$/); expect(publishedProductProvider.providerSource).toMatch(/^[a-f0-9]{40}$/); expect(publishedProductProvider.productSource).toMatch(/^[a-f0-9]{40}$/); diff --git a/scripts/test/product-artifacts.test.mjs b/scripts/test/product-artifacts.test.mjs index 24b1306787..83c5906d11 100644 --- a/scripts/test/product-artifacts.test.mjs +++ b/scripts/test/product-artifacts.test.mjs @@ -324,7 +324,7 @@ describe('release composition', () => { expect(() => verifyProductComposition(entries)).toThrow('conflicts'); }); it('keeps product provenance independent when the development Provider selection changes', () => { - expect(productImProvider.upstream.source).toBe('beaed4a6dabb583654d28fb09298716267039b4a'); + expect(productImProvider.upstream.source).toBe('7505ce6fcda26c02810781fde9d4da81dab28a68'); expect(productImProvider.upstream.dsh).toBe('0.2.0-rc.2'); }); @@ -339,7 +339,7 @@ describe('release composition', () => { '@botharness/computer': '0.0.0-test.823', '@botharness/core': '0.0.0-test.823', '@botharness/ui': '0.0.0-test.823', - '@botharness/im-provider': '4.32.0-botharness.22', + '@botharness/im-provider': '4.32.0-botharness.23', }); expect(release.optionalDependencies).toEqual( Object.fromEntries(cloudflaredPackageNames.map((name) => [name, '0.0.0-test.823'])), From ae569b9b6ce7f25c7a6465b4c57d95d73573f953 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 27 Oct 2026 09:23:32 +0000 Subject: [PATCH 2/2] fix(deps): make the react-native-view-shot patch apply on Windows qualify-commands (windows-latest) failed installing dependencies with ERR_PNPM_INVALID_PATCH at byte 0 of patches/react-native-view-shot@6.1.1.patch. The patch opened with an empty deletion of example-expo/package-lock.json, which the published package does not need. Drop that section, keep the exports reorder unchanged, and check patches out with LF so pnpm parses the same bytes on every platform. The lockfile patch hash is regenerated by pnpm. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Lpx6qnuRKPyBQWbwohCfMZ --- .gitattributes | 2 ++ patches/react-native-view-shot@6.1.1.patch | 3 --- pnpm-lock.yaml | 6 +++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.gitattributes b/.gitattributes index cb7d7f2c2e..e4dc913758 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,3 +4,5 @@ apps/docs/public/guides/vps-source/terminal/*.typescript -text -diff apps/docs/public/guides/vps-source/terminal/*.timing -text -diff # Preserve the pinned upstream WebRTC notice material verbatim. apps/mobile/modules/local-computer-video/android/src/main/assets/local-computer-video/THIRD-PARTY-NOTICES.md -whitespace +# pnpm parses patches byte for byte; keep them LF on Windows checkouts. +patches/*.patch text eol=lf diff --git a/patches/react-native-view-shot@6.1.1.patch b/patches/react-native-view-shot@6.1.1.patch index 1647d14586..3e3202fb0a 100644 --- a/patches/react-native-view-shot@6.1.1.patch +++ b/patches/react-native-view-shot@6.1.1.patch @@ -1,6 +1,3 @@ -diff --git a/example-expo/package-lock.json b/example-expo/package-lock.json -deleted file mode 100644 -index bd111b097ef17c42d7651e3dff1bda899e6cbeac..0000000000000000000000000000000000000000 diff --git a/package.json b/package.json index e42f799471b5a811919f936a5d4fda7b5df5cc9b..4d7a7bc5ae90d2745bbfe4bb94795dc2e5e1a6b3 100644 --- a/package.json diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e7c46f39c2..8e323beb2a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -173,7 +173,7 @@ patchedDependencies: '@deepseek-ai/dsh-tool-fs@0.2.1-rc.3': 4b2e510cb0df4904b95b99936edd4cdaec5b19438561254906b3abf0d2c3b204 dockview-core@8.4.1: 6d5f9165424be95472edbb4e667b16cf9abd150f139d3524cc1ca9a6b7863b86 expo-quick-actions@6.0.2: 2d9cefa269045271145e1989e004232aac3c206249494311d39f49c13293dddb - react-native-view-shot@6.1.1: 1a309afc15955797ee9174234ae2514e981ea99e97527650b1d0ed0ebe6ee9ca + react-native-view-shot@6.1.1: a288c04a105e6e1b53da39a97f1b500ae8375b9967c3fc6cbac861efc0b9a5b2 importers: @@ -482,7 +482,7 @@ importers: version: 4.3.4(react-native-pager-view@9.0.7(react-native@0.88.0(@babel/core@7.29.7(supports-color@10.2.2))(@react-native/metro-config@0.87.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0))(react-native@0.88.0(@babel/core@7.29.7(supports-color@10.2.2))(@react-native/metro-config@0.87.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0) react-native-view-shot: specifier: 6.1.1 - version: 6.1.1(patch_hash=1a309afc15955797ee9174234ae2514e981ea99e97527650b1d0ed0ebe6ee9ca)(react-native@0.88.0(@babel/core@7.29.7(supports-color@10.2.2))(@react-native/metro-config@0.87.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0) + version: 6.1.1(patch_hash=a288c04a105e6e1b53da39a97f1b500ae8375b9967c3fc6cbac861efc0b9a5b2)(react-native@0.88.0(@babel/core@7.29.7(supports-color@10.2.2))(@react-native/metro-config@0.87.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0) react-native-web: specifier: ~0.21.4 version: 0.21.4(react-dom@19.3.0(react@19.3.0))(react@19.3.0) @@ -25706,7 +25706,7 @@ snapshots: react-native-pager-view: 9.0.7(react-native@0.88.0(@babel/core@7.29.7(supports-color@10.2.2))(@react-native/metro-config@0.87.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0) use-latest-callback: 0.2.6(react@19.3.0) - react-native-view-shot@6.1.1(patch_hash=1a309afc15955797ee9174234ae2514e981ea99e97527650b1d0ed0ebe6ee9ca)(react-native@0.88.0(@babel/core@7.29.7(supports-color@10.2.2))(@react-native/metro-config@0.87.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0): + react-native-view-shot@6.1.1(patch_hash=a288c04a105e6e1b53da39a97f1b500ae8375b9967c3fc6cbac861efc0b9a5b2)(react-native@0.88.0(@babel/core@7.29.7(supports-color@10.2.2))(@react-native/metro-config@0.87.1(@babel/core@7.29.7(supports-color@10.2.2))(supports-color@10.2.2))(@types/react@19.3.0)(react@19.3.0)(supports-color@10.2.2))(react@19.3.0): dependencies: react: 19.3.0 optionalDependencies: