The work behind the reply.
Catalog answers from approved records,
with a durable path to human takeover.
Crisp or Chatwoot owns the conversation inbox.
Replywork owns the checked decisions and business integration.
Ask “What is the price and availability of the canvas tote?” The worker can interpret the request, look up the approved synthetic product and reply with PKR 1,800.00; listed as available. The model extracts a bounded request; local code renders stored facts from PostgreSQL. It cannot invent a price, change stock or place an order.
The local test page lists these questions with their expected replies, the seed catalog and copyable takeover commands. It opens a Crisp test chat only when you ask. It is a localhost test surface, not a shop or a second inbox.
Use Node.js 24 and the repository-pinned pnpm through Corepack:
corepack pnpm install --frozen-lockfile
corepack pnpm verify
corepack pnpm demo:crispOpen http://127.0.0.1:3001. The page renders without a database or credentials. An empty
CRISP_WEBSITE_ID leaves chat disabled; Crisp loads only after you open it. No question is sent
automatically. For a real inbox roundtrip, follow the start-to-stop workflow: local
PostgreSQL, a synthetic seed, dedicated Crisp development workspace, API, worker and temporary
tunnel. Nothing needs to be installed on your live portfolio or permanently deployed.
The repository implements and tests a durable delivery path for Chatwoot and Crisp:
- HMAC verification over the original request body;
- replay-window checks;
- message validation and normalization;
- filtering for private, outgoing, and unsupported messages;
- atomic receipt and queue admission in PostgreSQL;
- a queue worker with visibility timeout, audit records, and archive-on-success behavior;
- outgoing replies through the configured provider API;
- provider-appropriate human handoff with durable local automation pause and trusted resume controls.
The default test suite remains offline. Database tests exercise the complete signed webhook to outgoing API-request path against local PostgreSQL and a controlled HTTP boundary. A Crisp development workspace has also completed the live Free-plan reference path: inbound delivery, reply, retry, takeover suppression, resume, and a grounded catalog reply. This is development evidence, not a production hosting or uptime claim.
flowchart LR
Inbox[Conversation inbox] -->|Signed customer event| API[Fastify API]
API -->|Atomic receipt + admission| Queue[(PostgreSQL queue)]
Queue --> Worker[Sequential worker]
Worker --> Request[Validated catalog request]
Request --> Catalog[(Approved catalog)]
Catalog --> Reply[Stored-fact reply]
Worker --> Handoff[Human handoff + durable pause]
Reply --> Inbox
Handoff --> Inbox
Worker --> Audit[(Attempt audit)]
The API and worker live in one service application. Shared packages hold contracts, business rules, provider adapters, and test fixtures. This keeps deployment simple while preserving the boundaries that later integrations need.
corepack pnpm verify runs formatting, lint, source/test type checks and offline tests. Individual
commands are available when working on one layer:
corepack pnpm format:check
corepack pnpm lint
corepack pnpm typecheck
corepack pnpm test
corepack pnpm buildcorepack pnpm worker:once processes at most one admitted delivery and then exits. Opt-in
corepack pnpm worker:run processes sequentially until stopped, waiting between idle reads. Ctrl+C
lets the current delivery finish and closes the connection. A processing failure stops the loop with
a redacted error; correct the problem before deliberately restarting. Run one worker, not concurrent
copies. The recorded live Crisp check used the one-shot worker; the retained page and polling loop
have separate offline and browser checks, not an unattended deployment claim.
Copy .env.example to .env only when running an integration locally. Unit and contract tests do
not read local credentials or make network requests.
For an existing instance or the optional self-hosted example, see the Chatwoot integration guide. The example follows upstream documentation but has not been booted or verified against a live instance. Chatwoot is not required for offline development.
For the permanent Free-plan development path, see the Crisp integration guide. Its signed webhook, API reply, retry and handoff boundaries are covered by offline tests and a controlled live development-workspace check.
The read-only PostgreSQL catalog lookup returns approved product records with stored prices,
availability and descriptions. It supports bounded text search and exact product IDs, without
inventing missing products or changing business data. A local command and synthetic examples are
available in the catalog guide. Set REPLYWORK_RESPONDER=catalog to let the
worker answer explicit /catalog requests from recorded facts and hand off other requests. Fixed
replies remain the default. Opt-in catalog-natural mode uses Gemini to extract a bounded catalog
request, then builds the answer from stored facts. Evaluate the selected model with synthetic
questions before using it with customer messages. The
terminal question command checks interpretation and factual replies
without a conversation provider. Handoff pauses automation until an operator explicitly resumes it.
See the conversation control guide for behavior and limits.
This is a read-only catalog vertical slice, not a commerce dashboard. Products are synthetic seed data and availability is a recorded value, not a stock reservation. Orders, payments, refunds, policy automation, memory, automatic operator detection and multi-tenant catalogs are not implemented. Unsupported work goes to a human. Natural mode is opt-in and sends the current question to Google's API; offline checks do not read keys or contact model providers.
If transactional actions are introduced later, deterministic validation, identity checks and explicit confirmation or operator approval must guard them. A model cannot grant its own permission.
Please report security problems privately as described in SECURITY.md.
Inspection and non-commercial use are covered by LICENSE.md. Commercial use and competing hosted copies require prior written permission. The original Replywork SVG mark is maintained in this repository.
