fix(feishu): unregister the default card handler before replacing it (node-sdk 1.74) - #231
Merged
Merged
Conversation
eddiearc
requested changes
Sep 14, 2026
eddiearc
left a comment
Owner
There was a problem hiding this comment.
Fable 5.1 review(head 9bf6507)
Verdict: REQUEST_CHANGES
阻塞
- 测试断言空转:node-sdk 1.74 重复注册文案是
… handle is already registered and has been replaced…,PR 正则/handle is registered/匹配不到。变异验证(去掉unregister)仍 pass。请改为例如:(或至少assert.deepEqual(dispatchLogs, [], JSON.stringify(dispatchLogs));
/handle is (already )?registered/,且确认缺 unregister 时失败。) - AGENTS.md:每次交付需 bump
package.jsonpatch。本 PR 仍为0.5.9。与 #230(已占0.5.10)协调:先合者 0.5.10,后者 rebase 到 0.5.11。
代码本身 ✅
unregister?.("card.action.trigger")再register:与原先 Map 覆盖语义等价,只消噪音overrides锁^1.74.0形态合理(避免幻影 direct dep)- 卡片幂等 / InteractionStateMachine 无语义风险
- CI 绿;unit host-channel-business 8/8
Nits(非阻塞)
bun.lock里 node-sdk 条目 registry URL 为空,与仓库其余 npmmirror 不一致,建议一致 registry 重生成Dispatcher注释可改为「channel 未公开 dispatcher 类型,Larkin 本地结构类型描述运行时 node-sdk」;可考虑与host-shell.ts内联类型合并
合入仍等 idan 明确 yes。
itswl
force-pushed
the
fix/card-handler-unregister
branch
from
September 14, 2026 14:12
9bf6507 to
2e88956
Compare
Contributor
Author
复审项更新(head
|
eddiearc
approved these changes
Sep 14, 2026
eddiearc
left a comment
Owner
There was a problem hiding this comment.
Fable 5.1 re-review(head 2e88956)
Verdict: APPROVE_WITH_NITS
上轮阻塞均已解决:
- ✅
assert.deepEqual(dispatchLogs, [])— 变异验证:去掉unregister后捕获 node-sdk 1.74 的already registered … replacedwarn 并失败;恢复后通过 - ✅
package.json0.5.9 → 0.5.10
overrides + unregister→register 语义 OK;CI 绿。
Nits:bun.lock node-sdk registry URL 为空;与 #230/#224/#226/#222/#233 版本号撞车,先合者占 0.5.10,其余 rebase。
合入仍等 idan 明确 yes。
Replacing the channel package's card.action.trigger handler was a second registration, which node-sdk logged at error level on every connect and reconnect (eddiearc#220) with no supported way to replace a handler. Upstream now provides EventDispatcher.unregister and demotes the duplicate log to warn (larksuite/node-sdk#225, @larksuiteoapi/node-sdk@1.74.0): pin that version through an overrides entry and unregister before registering, so the deliberate replacement produces no log line at all. The card-registration test asserts the SDK logger stays empty: node-sdk 1.74 warns "… handle is already registered and has been replaced …", which the previous /handle is registered/ regex could never match; dropping the unregister call now fails the assertion (mutation-checked). Bumps the package patch version (0.5.9 -> 0.5.10) per the Owner policy. Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-authored-by: idan <eddiearc6@gmail.com>
cursor
Bot
force-pushed
the
fix/card-handler-unregister
branch
from
September 14, 2026 14:54
2e88956 to
76e3f50
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
host-channel-business.tsreplaces the channel package's defaultcard.action.triggerhandler afterconnect(). Until now that second registration tripped the SDK's duplicate-registration path, which logged at error level on every connect/reconnect (filed as #220), and there was no supported way to replace a handler at all.Upstream fixed the vendor side (#224 → larksuite/node-sdk#225):
EventDispatcher.unregister(...keys)was added, the duplicate-registration log demoted to warn, and the replacement pattern documented — and@larksuiteoapi/node-sdk@1.74.0carries it.Change
package.json/bun.lock: anoverridesentry pins the transitive@larksuiteoapi/node-sdkto^1.74.0. The channel package's declared range (^1.67.0) already allows it; an override is used because Larkin imports nothing from node-sdk directly — a direct dependency would be a phantom declaration. This is the only manifest change.src/feishu/host-channel-business.ts:registerCardActionsnow callsdispatcher.unregister?.("card.action.trigger")before installing its handler, so the deliberate replacement is no longer a duplicate registration (no line at all, not even a warn). The localDispatcherinterface gains that method as optional, with a comment on why: the channel package's published dispatcher type is narrower than the runtime dispatcher it hands over.test/unit/feishu/host-channel-business.test.mjs: the real-dispatcher test now records the SDK logger and asserts nohandle is registeredline — which also pins the assumption that the runtime dispatcher is node-sdk >= 1.74.Validation
bun test test/unit/feishu/host-channel-business.test.mjs→ 8 pass / 0 fail (including the new no-duplicate-log assertion)bun test test/unit/feishu/→ 138 pass / 0 failbun run build✅ ·bun run typecheck✅ ·bun run licenses:check✅ ·bun run publication:check:tree✅bun run test:unit→ 896 pass / 1 skip / 7 fail on a machine with three agents' daemons running. All seven are load/timeout flakes, each re-checked in isolation: four files pass standalone, andAgent CLI process consumes native-shaped …, the live-acceptance harness and the stale-lock reclaim guard also fail on unmodifiedmainin this environment (verified before this change). None of them touch the SDK dispatcher or the card handler.Shape note: the
overridespin is the one dependency-manifest change (no new dependency, no code importing node-sdk). Happy to re-shape per maintainer direction — e.g. drop the override once@larksuite/channeldeclares the newer range itself, or keep the plain replacement with only the lockfile bumped ifoverridesis not wanted.Fixes #220
🤖 Generated with Claude Code