程序员阿江(Relakkes) ddcfa5faae feat(adapters): add WhatsApp linked-device support (#573)
Add a WhatsApp adapter backed by Baileys linked-device auth, plus desktop QR binding UI, server config endpoints, sidecar startup wiring, tests, and documentation.

Constraint: Uses WhatsApp Web linked-device auth, not Meta WhatsApp Business Cloud API.

Tested:
- cd adapters && bun run check:adapters
- bun test src/server/__tests__/adapters.test.ts
- cd desktop && bun run check:desktop
- bun run check:native
- bun run check:persistence-upgrade
- bun run check:docs

Not-tested:
- Live WhatsApp QR pairing, because no WhatsApp account/device was exercised here.
- bun run check:server, because the existing src/server/__tests__/conversations.test.ts timeout still fails independently.

Confidence: medium
Scope-risk: moderate
2026-06-09 21:31:46 +08:00

37 lines
1.1 KiB
TypeScript

import { describe, expect, it } from 'bun:test'
import {
buildWhatsAppThinkingPreview,
formatWhatsAppOutboundText,
splitWhatsAppText,
} from '../format.js'
describe('WhatsApp message formatting', () => {
it('converts markdown tables to mobile-friendly bullets', () => {
const markdown = [
'| Feature | Status |',
'| --- | --- |',
'| WhatsApp | Ready |',
].join('\n')
expect(formatWhatsAppOutboundText(markdown)).toBe([
'WhatsApp',
'• Status: Ready',
].join('\n'))
})
it('splits long text within the WhatsApp chunk limit', () => {
const chunks = splitWhatsAppText('a'.repeat(8100), 4000)
expect(chunks).toHaveLength(3)
expect(chunks.every((chunk) => chunk.length <= 4000)).toBe(true)
})
it('accumulates thinking preview text without losing the full value', () => {
const first = buildWhatsAppThinkingPreview('', 'The user')
const second = buildWhatsAppThinkingPreview(first.fullText, ' asks for WhatsApp')
expect(second.fullText).toBe('The user asks for WhatsApp')
expect(second.messageText).toContain('The user asks for WhatsApp')
})
})