Repository navigation
docs: add Signal community adapter - #1118
dVelopment wants to merge 1 commit into
Conversation
Signed-off-by: Daniel Holzmann <daniel@danielholzmann.com>
|
@dVelopment is attempting to deploy a commit to the Vercel Team on Vercel. A member of the Team first needs to authorize it. |
bensabic
left a comment
There was a problem hiding this comment.
Thanks for the thorough listing. I checked the catalog entry and page against the adapter source at the pinned commit (c85ae16) and the Chat core, and the claims I spot-checked hold up (Node >= 24, chat ^4.43, signal-cli 0.14.9 minimum, 64 KiB text limit, 150 MiB attachments, 2-minute typing timeout). The structure follows the add-adapter skill and the frontmatter description matches the catalog entry.
A few small, non-blocking suggestions inline:
imagesInCardsis"no", but the adapter renders card images as links, the same way it handles link buttons (which arepartial, "Sent as URLs").- The Docker Compose example links point at
mainwhile every other adapter-repo link is pinned to the commit. - The
chat.openDM()/chat.getUser()note could warn that an ACI matches the UUID format Chat routes to Linear, so it misroutes instead of throwing when Linear is also registered.
I didn't run the test suite locally, and CI on this fork PR hasn't run beyond the security and Socket checks.
| tables: { status: "partial", label: "Monospace text" }, | ||
| charts: { status: "partial", label: "Monospace text" }, | ||
| fields: { status: "partial", label: "Formatted text" }, | ||
| imagesInCards: "no", |
There was a problem hiding this comment.
The adapter does render card images, as links: cardToAst turns card.imageUrl and image children into link paragraphs (src/format.ts at the pinned commit), and the page itself says cards render "images, links, and link buttons as URLs". Matching linkButtons keeps the matrix consistent with the page:
| imagesInCards: "no", | |
| imagesInCards: { status: "partial", label: "Sent as URLs" }, |
|
|
||
| ## Platform setup | ||
|
|
||
| 1. Install signal-cli 0.14.9 or newer and provision the bot's Signal account with signal-cli's own CLI, using the data directory the daemon will use. In the [Docker Compose example](https://github.com/stibbons-ai/chat-adapter-signal/tree/main/examples/echo-bot), that means a one-off container on the daemon's volume: `docker compose run --rm signal-cli <arguments>`. The daemon loads accounts only when it starts, so stop a running daemon first and start it again afterwards. |
There was a problem hiding this comment.
Nit: pin the Docker Compose example to the same commit as the other adapter-repo links, so the setup steps can't drift from what this page describes:
| 1. Install signal-cli 0.14.9 or newer and provision the bot's Signal account with signal-cli's own CLI, using the data directory the daemon will use. In the [Docker Compose example](https://github.com/stibbons-ai/chat-adapter-signal/tree/main/examples/echo-bot), that means a one-off container on the daemon's volume: `docker compose run --rm signal-cli <arguments>`. The daemon loads accounts only when it starts, so stop a running daemon first and start it again afterwards. | |
| 1. Install signal-cli 0.14.9 or newer and provision the bot's Signal account with signal-cli's own CLI, using the data directory the daemon will use. In the [Docker Compose example](https://github.com/stibbons-ai/chat-adapter-signal/tree/c85ae16eb4392f4b0cac81ef04ca8a0c31a4ea2c/examples/echo-bot), that means a one-off container on the daemon's volume: `docker compose run --rm signal-cli <arguments>`. The daemon loads accounts only when it starts, so stop a running daemon first and start it again afterwards. |
|
|
||
| ## Direct messages | ||
|
|
||
| `adapter.openDM()` takes an ACI, a phone number such as `+15550001111`, or `u:<username>`, and returns the 1:1 thread ID. signal-cli looks numbers and usernames up on the Signal server, and `openDM()` throws `ResourceNotFoundError` when it finds no ACI for the user. `chat.openDM()` and `chat.getUser()` can't route Signal user IDs to this adapter, so call the adapter directly and open the thread yourself: |
There was a problem hiding this comment.
Worth spelling out why, because there's a sharp edge: Chat.inferAdapterFromUserId matches any UUID to Linear (LINEAR_UUID_REGEX in packages/chat/src/chat.ts), and ACIs are UUIDs. Without Linear registered it throws; with Linear registered, chat.openDM(aci) silently goes to the Linear adapter.
| `adapter.openDM()` takes an ACI, a phone number such as `+15550001111`, or `u:<username>`, and returns the 1:1 thread ID. signal-cli looks numbers and usernames up on the Signal server, and `openDM()` throws `ResourceNotFoundError` when it finds no ACI for the user. `chat.openDM()` and `chat.getUser()` can't route Signal user IDs to this adapter, so call the adapter directly and open the thread yourself: | |
| `adapter.openDM()` takes an ACI, a phone number such as `+15550001111`, or `u:<username>`, and returns the 1:1 thread ID. signal-cli looks numbers and usernames up on the Signal server, and `openDM()` throws `ResourceNotFoundError` when it finds no ACI for the user. `chat.openDM()` and `chat.getUser()` can't route Signal user IDs to this adapter. Chat picks the adapter from the user ID's format, and an ACI has the UUID format Chat assigns to Linear, so with the Linear adapter also registered these calls go to Linear instead of failing. Call the adapter directly and open the thread yourself: |
| ## Resources | ||
|
|
||
| - [Adapter source](https://github.com/stibbons-ai/chat-adapter-signal) | ||
| - [Docker Compose example](https://github.com/stibbons-ai/chat-adapter-signal/tree/main/examples/echo-bot) |
There was a problem hiding this comment.
Same pin as above:
| - [Docker Compose example](https://github.com/stibbons-ai/chat-adapter-signal/tree/main/examples/echo-bot) | |
| - [Docker Compose example](https://github.com/stibbons-ai/chat-adapter-signal/tree/c85ae16eb4392f4b0cac81ef04ca8a0c31a4ea2c/examples/echo-bot) |
Summary
Adds the independently maintained
@stibbons/chat-adapter-signalpackage to the community adapter catalog and chat-sdk.dev.signalinCOMMUNITY_ADAPTERSwith its npm package, source repository pinned to a commit, and platform feature matrix.@chat-adapter/catalogchangeset, as theadd-adapterskill asks for community listings.The adapter talks to signal-cli, which you install and run yourself, over its JSON-RPC interface: an HTTP daemon, a Unix socket, TCP, or a signal-cli process the adapter spawns. It receives messages over signal-cli's event stream instead of webhooks, so the bot runs as a long-running process. It supports 1:1 and group messages, mentions, attachments in both directions, edits and remote deletes of its own messages, reactions, typing indicators, and read receipts. Streaming is buffered: the adapter shows the typing indicator while the stream runs and posts the answer once. Cards render as formatted text without buttons or select menus, and message history is what Chat records in its state adapter.
#169 proposed a first-party Signal adapter and was closed until Signal offers official support. This PR adds no package to the monorepo. It lists an adapter maintained outside it in the community group, the way Baileys and Zaileys are listed for WhatsApp, and the page opens with a callout that the adapter depends on signal-cli rather than an official Signal API.
The Quick start is a standalone
bot.tswithoutexport const bot, because no webhook route imports it (as on the Zaileys page).Test plan
pnpm validate: passes (knip, check, typecheck, all package tests, andbuild:validateincluding the docsnext build).pnpm --filter @chat-adapter/catalog buildandpnpm --filter @chat-adapter/catalog test(53 passed).pnpm --filter @chat-adapter/integration-tests exec vitest run src/docs-adapters.test.ts src/docs-llms.test.ts src/docs-skills.test.ts --coverage=false(662 passed).pnpm --filter create-chat-sdk test(223 passed) andpnpm konsistent(no violations)./adapters/community/signalwithpnpm --filter docs dev: the navigation entry, callout, configuration table, and feature matrix render, and/adapterslists Signal.openDMsnippets with strict TypeScript against the adapter's build at the pinned commit (0.1.0) andchat4.43.0.Checklist
git commit -s)pnpm validatepasses