WeChat needs a QR-paired path instead of bot-token setup, so the adapter layer now includes the iLink protocol calls, desktop pairing UI, server-side bind/unbind APIs, and shared IM command behavior. Empty project history falls back to the user's default work directory so mobile /new works without pre-opening a desktop project.
Constraint: Tencent iLink login returns a URL that the desktop UI must render as a QR image locally
Constraint: IM adapters should keep /new, /projects, status, permission, and default workdir behavior consistent across WeChat, Feishu, and Telegram
Rejected: Require users to paste absolute project paths for first WeChat sessions | mobile onboarding should work from the default user working directory
Confidence: high
Scope-risk: moderate
Directive: Do not change WeChat polling back to overlapping intervals; getupdates is a long-poll endpoint and must remain serialized
Tested: Real WeChat QR scan, inbound /status, outbound reply, and unbind E2E
Tested: bun run check:adapters
Tested: bun run quality:pr
Not-tested: Re-scan live WeChat after the default-workdir fallback tweak; covered by adapter config tests and PR gate
- attachment-store.ts: pin Dirent<string>[] and pass `encoding: 'utf8'`
so newer @types/node doesn't infer Dirent<NonSharedBuffer>
- feishu/media.ts: drop Readable.from(buffer) and pass Buffer directly
to im.image.create / im.file.create — Lark SDK already accepts Buffer
and the stream wrapper trips the stricter Buffer | ReadStream union
used on the main branch's tsconfig
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Address two production issues in the AttachmentStore:
1. TOCTOU race in resolvePath() — concurrent downloads with same filename in
the same millisecond could collide. Fixed by appending a 6-char random suffix
to the timestamp-based path, ensuring millisecond-level collisions never occur.
2. Orphan .part files from crashed writes never cleaned up. Fixed by extending
gc() to recognize .part files and clean them with a shorter grace period
(10 minutes by default) rather than the normal retention window.
Added two test cases covering heavy collision pressure and .part cleanup.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>