@chatlychat/cli 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/listen.d.ts +57 -0
- package/dist/commands/listen.d.ts.map +1 -0
- package/dist/commands/listen.js +490 -0
- package/dist/commands/listen.js.map +1 -0
- package/dist/help.d.ts +1 -1
- package/dist/help.d.ts.map +1 -1
- package/dist/help.js +11 -0
- package/dist/help.js.map +1 -1
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +11 -1
- package/dist/run.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type ParsedArgs } from '../args.js';
|
|
2
|
+
import type { ChatlyClient } from '@chatlychat/sdk-node';
|
|
3
|
+
export interface ListenOptions {
|
|
4
|
+
/** Where to POST each event. `null` prints without forwarding. */
|
|
5
|
+
readonly forwardTo: string | null;
|
|
6
|
+
readonly endpointId: string | null;
|
|
7
|
+
/** Client-side event filter. `null` means every event in the log. */
|
|
8
|
+
readonly events: ReadonlySet<string> | null;
|
|
9
|
+
readonly status: string | null;
|
|
10
|
+
/** The `whsec_…` to re-sign forwarded requests with. `null` sends unsigned. */
|
|
11
|
+
readonly secret: string | null;
|
|
12
|
+
readonly intervalMs: number;
|
|
13
|
+
/** How many deliveries already in the log to forward before tailing. */
|
|
14
|
+
readonly replay: number;
|
|
15
|
+
/** Rows per poll. Also the most this can see between two polls. */
|
|
16
|
+
readonly pageLimit: number;
|
|
17
|
+
readonly json: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface ListenDeps {
|
|
20
|
+
/** For the FORWARD leg only. API calls go through the SDK's own transport. */
|
|
21
|
+
readonly fetchFn: typeof fetch;
|
|
22
|
+
readonly now: () => number;
|
|
23
|
+
readonly sleep: (ms: number, signal: AbortSignal) => Promise<void>;
|
|
24
|
+
readonly signal: AbortSignal;
|
|
25
|
+
readonly out: (line: string) => void;
|
|
26
|
+
readonly err: (line: string) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Stop after this many polls. Test-only, and the reason it exists rather
|
|
29
|
+
* than a timer the test races: a tail loop with no bound is not a thing a
|
|
30
|
+
* unit test can assert the end of.
|
|
31
|
+
*/
|
|
32
|
+
readonly maxPolls?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ListenSummary {
|
|
35
|
+
readonly seen: number;
|
|
36
|
+
readonly forwarded: number;
|
|
37
|
+
readonly refused: number;
|
|
38
|
+
readonly polls: number;
|
|
39
|
+
}
|
|
40
|
+
/** Read the flags, refusing anything that cannot work, with the fix named. */
|
|
41
|
+
export declare function parseListenOptions(args: ParsedArgs): ListenOptions;
|
|
42
|
+
/**
|
|
43
|
+
* The tail loop, abortable, with the process boundary left to the caller.
|
|
44
|
+
*
|
|
45
|
+
* Exported so the spec can drive it with a bounded `maxPolls` and a scripted
|
|
46
|
+
* fetch, rather than racing a timer against a signal handler.
|
|
47
|
+
*/
|
|
48
|
+
export declare function tail(chatly: ChatlyClient, opts: ListenOptions, deps: ListenDeps): Promise<ListenSummary>;
|
|
49
|
+
/**
|
|
50
|
+
* The command entry point.
|
|
51
|
+
*
|
|
52
|
+
* SIGINT and SIGTERM abort the loop rather than killing the process, so the
|
|
53
|
+
* summary still prints and the exit code is 0 — a developer tool stopped on
|
|
54
|
+
* purpose did not fail.
|
|
55
|
+
*/
|
|
56
|
+
export declare function listen(chatly: ChatlyClient, args: ParsedArgs): Promise<number>;
|
|
57
|
+
//# sourceMappingURL=listen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listen.d.ts","sourceRoot":"","sources":["../../src/commands/listen.ts"],"names":[],"mappings":"AA6EA,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA4BzD,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mEAAmE;IACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,OAAO,KAAK,CAAC;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAyCD,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,aAAa,CAsElE;AAyLD;;;;;GAKG;AACH,wBAAsB,IAAI,CACxB,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,aAAa,EACnB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,aAAa,CAAC,CA2HxB;AAqBD;;;;;;GAMG;AACH,wBAAsB,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAmCpF"}
|
|
@@ -0,0 +1,490 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `chatly listen` — watch this workspace's webhook traffic and forward it to a
|
|
3
|
+
* local URL.
|
|
4
|
+
*
|
|
5
|
+
* ═══ HOW A LAPTOP RECEIVES EVENTS AT ALL ══════════════════════════════════
|
|
6
|
+
*
|
|
7
|
+
* Chatly delivers webhooks by POSTing to a URL, so a machine behind NAT cannot
|
|
8
|
+
* be a destination. Three ways out were considered and only one of them is
|
|
9
|
+
* real with a `ck_` workspace key:
|
|
10
|
+
*
|
|
11
|
+
* **(a) Poll the delivery log. This is what this command does.**
|
|
12
|
+
* `GET /v1/webhooks/deliveries` records one row per attempt — event type,
|
|
13
|
+
* payload, attempt number, HTTP status, latency, error, next retry — and is
|
|
14
|
+
* open to a `ck_` key (`@AllowApiKey()` on `WebhookDeliveriesController`,
|
|
15
|
+
* `integrations:read`), keyset-paginated newest-first on `created_at`, with
|
|
16
|
+
* `endpointId` and `status` filters. `GET /v1/webhooks/deliveries/{id}`
|
|
17
|
+
* returns the exact payload we POSTed. Both verified against their handlers,
|
|
18
|
+
* because a route list in this repo has been wrong in both directions.
|
|
19
|
+
*
|
|
20
|
+
* **(b) Subscribe over the realtime socket. Not possible.**
|
|
21
|
+
* `apps/realtime/src/gateway.ts` accepts exactly two credentials in its
|
|
22
|
+
* handshake: an agent RS256 access token or a visitor HS256 token. A
|
|
23
|
+
* workspace API key is neither, and there is no key-accessible route that
|
|
24
|
+
* mints either one. The realtime envelope vocabulary is also not the webhook
|
|
25
|
+
* catalogue — it is the dashboard's own event stream, with a different shape
|
|
26
|
+
* and a different subscription model.
|
|
27
|
+
*
|
|
28
|
+
* **(c) Register a temporary subscription and deregister on exit. Not
|
|
29
|
+
* possible either, and this is the finding worth writing down.**
|
|
30
|
+
* `POST /v1/webhooks` carries `@AllowApiKey()`. `DELETE /v1/webhooks/{id}`
|
|
31
|
+
* does **not** — it is the one route on that controller without it, so a key
|
|
32
|
+
* gets a 403. A CLI that registered an endpoint could therefore never remove
|
|
33
|
+
* it, and `listen` would leak a subscription into the customer's workspace on
|
|
34
|
+
* every run, with no key-accessible way to disable it either (there is no
|
|
35
|
+
* enable/disable route; the only PATCH moves the schema pin). So **this
|
|
36
|
+
* command registers nothing and has nothing to clean up** — stated in its own
|
|
37
|
+
* startup banner, because "what did that leave behind" is the first question
|
|
38
|
+
* a developer tool of this shape has to answer.
|
|
39
|
+
*
|
|
40
|
+
* ═══ WHAT THIS CANNOT DO, AND THE ROUTE THAT WOULD FIX IT ═════════════════
|
|
41
|
+
*
|
|
42
|
+
* It cannot relay Chatly's OWN signature, because the server does not keep
|
|
43
|
+
* it. `webhook_deliveries` stores `payload` as `jsonb` and that is all: the
|
|
44
|
+
* signature is computed per attempt from the endpoint's secret and never
|
|
45
|
+
* persisted, the secret is returned by exactly one route and never read back,
|
|
46
|
+
* `jsonb` does not preserve key order, and the signed envelope's `id` is the
|
|
47
|
+
* BullMQ-era `deliveryId` which is not the delivery row's `id`. So the exact
|
|
48
|
+
* signed bytes are unreconstructable by construction, not by omission.
|
|
49
|
+
*
|
|
50
|
+
* What this command forwards is therefore re-signed locally with `--secret`,
|
|
51
|
+
* using the same construction the worker uses (`t=<unix seconds>,v1=HMAC over
|
|
52
|
+
* <t>.<rawBody>`), and the header is **verified with the SDK's own
|
|
53
|
+
* `verifyChatlySignature` before the request goes out**. That self-check is
|
|
54
|
+
* not ceremony: it is the one thing that catches a signer and a verifier
|
|
55
|
+
* drifting on construction or on timestamp unit, which is a bug this product
|
|
56
|
+
* has actually shipped. If it ever fails, the forward is refused rather than
|
|
57
|
+
* sent.
|
|
58
|
+
*
|
|
59
|
+
* A true `stripe listen` — the developer's handler seeing byte-for-byte what
|
|
60
|
+
* production sends — needs a server-side surface, and there are two shapes:
|
|
61
|
+
*
|
|
62
|
+
* 1. `GET /v1/webhooks/tail` as Server-Sent Events: `@AllowApiKey()`,
|
|
63
|
+
* `integrations:read`, emitting `{ id, type, signedBody, signature }`
|
|
64
|
+
* from the same `signWebhookPayload` the dispatcher uses. Best for the
|
|
65
|
+
* use case; needs a streaming route and a fan-out off the webhook queue.
|
|
66
|
+
* 2. Cheaper: add `signed_body text` and `signature text` to
|
|
67
|
+
* `webhook_deliveries`, return them from
|
|
68
|
+
* `GET /v1/webhooks/deliveries/{id}`, and this poller relays them
|
|
69
|
+
* untouched. One migration, two columns, no new route shape.
|
|
70
|
+
*
|
|
71
|
+
* Both are in `apps/api`, `apps/worker` and `packages/db`, so neither is done
|
|
72
|
+
* here. Until one lands, this command is honest about what it mints.
|
|
73
|
+
*/
|
|
74
|
+
import { createHmac } from 'node:crypto';
|
|
75
|
+
import { verifyChatlySignature } from '@chatlychat/sdk-node';
|
|
76
|
+
import { bool, num, str } from '../args.js';
|
|
77
|
+
import { printJson } from '../output.js';
|
|
78
|
+
/** Deliveries remembered before the oldest id is dropped. */
|
|
79
|
+
const SEEN_CAP = 5_000;
|
|
80
|
+
const DEFAULT_INTERVAL_SECONDS = 2;
|
|
81
|
+
const MIN_INTERVAL_SECONDS = 1;
|
|
82
|
+
const DEFAULT_PAGE_LIMIT = 50;
|
|
83
|
+
/**
|
|
84
|
+
* Sign a forwarded body the way the worker signs a real delivery.
|
|
85
|
+
*
|
|
86
|
+
* Deliberately not imported from `@livechat/shared/webhook-signature`: this
|
|
87
|
+
* package is published and depends on `@chatlychat/sdk-node` alone, and
|
|
88
|
+
* `sync-sdk-repos.mjs` cannot mirror a private workspace import. `node:crypto`
|
|
89
|
+
* is the standard library, not a dependency.
|
|
90
|
+
*
|
|
91
|
+
* The construction is written out here so it reads beside the verification
|
|
92
|
+
* below, and the verification is what keeps the two honest — see this file's
|
|
93
|
+
* header.
|
|
94
|
+
*/
|
|
95
|
+
function signForForward(body, secret, nowMs) {
|
|
96
|
+
const t = Math.floor(nowMs / 1000).toString();
|
|
97
|
+
const v1 = createHmac('sha256', secret).update(`${t}.${body}`).digest('hex');
|
|
98
|
+
return `t=${t},v1=${v1}`;
|
|
99
|
+
}
|
|
100
|
+
function parseEventFilter(args) {
|
|
101
|
+
const raw = args.flags['event'];
|
|
102
|
+
if (raw === undefined) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const list = (Array.isArray(raw) ? raw : [String(raw)]).flatMap((v) => v
|
|
106
|
+
.split(',')
|
|
107
|
+
.map((s) => s.trim())
|
|
108
|
+
.filter((s) => s.length > 0));
|
|
109
|
+
return list.length === 0 ? null : new Set(list);
|
|
110
|
+
}
|
|
111
|
+
/** Read the flags, refusing anything that cannot work, with the fix named. */
|
|
112
|
+
export function parseListenOptions(args) {
|
|
113
|
+
const forwardTo = str(args.flags, 'forward-to') ?? null;
|
|
114
|
+
if (forwardTo !== null) {
|
|
115
|
+
let parsed = null;
|
|
116
|
+
try {
|
|
117
|
+
parsed = new URL(forwardTo);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
parsed = null;
|
|
121
|
+
}
|
|
122
|
+
/*
|
|
123
|
+
* One message for both failures, because `localhost:3000` — the mistake
|
|
124
|
+
* everyone makes — hits the SECOND branch, not the first: the WHATWG
|
|
125
|
+
* parser reads `localhost:` as a SCHEME and succeeds. A test caught this
|
|
126
|
+
* command telling a developer who typed `localhost:3000` that the scheme
|
|
127
|
+
* `"localhost:"` was unsupported, which is true and useless.
|
|
128
|
+
*/
|
|
129
|
+
if (parsed === null || (parsed.protocol !== 'http:' && parsed.protocol !== 'https:')) {
|
|
130
|
+
throw new Error(`--forward-to "${forwardTo}" is not an http(s) URL${parsed === null ? '' : ` (it parsed as the scheme "${parsed.protocol}")`}. Include the scheme:\n` + ' chatly listen --forward-to http://localhost:3000/webhooks');
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const intervalSeconds = num(args.flags, 'interval') ?? DEFAULT_INTERVAL_SECONDS;
|
|
134
|
+
if (intervalSeconds < MIN_INTERVAL_SECONDS) {
|
|
135
|
+
throw new Error(`--interval ${String(intervalSeconds)} is below the ${String(MIN_INTERVAL_SECONDS)}s floor. ` +
|
|
136
|
+
'This polls a real API on your own rate limit; a tighter loop buys nothing, because the ' +
|
|
137
|
+
'delivery row is written after the attempt completes.');
|
|
138
|
+
}
|
|
139
|
+
const pageLimit = num(args.flags, 'limit') ?? DEFAULT_PAGE_LIMIT;
|
|
140
|
+
if (pageLimit < 1) {
|
|
141
|
+
throw new Error(`--limit ${String(pageLimit)} must be at least 1.`);
|
|
142
|
+
}
|
|
143
|
+
const replay = num(args.flags, 'replay') ?? 0;
|
|
144
|
+
if (replay < 0) {
|
|
145
|
+
throw new Error(`--replay ${String(replay)} cannot be negative.`);
|
|
146
|
+
}
|
|
147
|
+
if (replay > pageLimit) {
|
|
148
|
+
throw new Error(`--replay ${String(replay)} is more than --limit ${String(pageLimit)}, and this command ` +
|
|
149
|
+
'only ever reads one page per poll. Raise --limit to match.');
|
|
150
|
+
}
|
|
151
|
+
const secret = str(args.flags, 'secret') ?? null;
|
|
152
|
+
if (secret !== null && !secret.startsWith('whsec_')) {
|
|
153
|
+
throw new Error(`--secret should be the endpoint's whsec_ signing secret (got "${secret.slice(0, 6)}…").\n` +
|
|
154
|
+
'It is returned exactly once, by `chatly webhooks create`, and by no other route — if ' +
|
|
155
|
+
'you no longer have it, create another endpoint.');
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
forwardTo,
|
|
159
|
+
endpointId: str(args.flags, 'endpoint') ?? null,
|
|
160
|
+
events: parseEventFilter(args),
|
|
161
|
+
status: str(args.flags, 'status') ?? null,
|
|
162
|
+
secret,
|
|
163
|
+
intervalMs: intervalSeconds * 1000,
|
|
164
|
+
replay,
|
|
165
|
+
pageLimit,
|
|
166
|
+
json: bool(args.flags, 'json'),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function asRows(value) {
|
|
170
|
+
const items = typeof value === 'object' && value !== null ? value.items : undefined;
|
|
171
|
+
if (!Array.isArray(items)) {
|
|
172
|
+
return [];
|
|
173
|
+
}
|
|
174
|
+
return items.filter((row) => {
|
|
175
|
+
if (typeof row !== 'object' || row === null) {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
const r = row;
|
|
179
|
+
return typeof r['id'] === 'string' && typeof r['eventType'] === 'string';
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Which endpoints this will see traffic from, and the refusal when there are
|
|
184
|
+
* none.
|
|
185
|
+
*
|
|
186
|
+
* The empty case is the one worth getting right: a developer running
|
|
187
|
+
* `chatly listen` with no subscription configured sees an empty tail forever
|
|
188
|
+
* and concludes the command is broken, when the real answer is that no event
|
|
189
|
+
* has ever been dispatched to this workspace. So it is an error naming the
|
|
190
|
+
* command that fixes it.
|
|
191
|
+
*/
|
|
192
|
+
async function resolveEndpoints(chatly, opts) {
|
|
193
|
+
const endpoints = await chatly.request('GET', '/v1/webhooks');
|
|
194
|
+
const rows = Array.isArray(endpoints) ? endpoints : [];
|
|
195
|
+
if (rows.length === 0) {
|
|
196
|
+
throw new Error('This workspace has no webhook subscriptions, so nothing is ever dispatched and the\n' +
|
|
197
|
+
'delivery log this command tails will stay empty.\n\n' +
|
|
198
|
+
'Create one first:\n' +
|
|
199
|
+
' chatly webhooks create --url https://example.test/hook --event conversation.created\n' +
|
|
200
|
+
'`chatly webhooks events` lists the subscribable names.\n\n' +
|
|
201
|
+
'The URL has to be one the platform can reach — it is the real destination, and this\n' +
|
|
202
|
+
'command tails what was attempted against it rather than replacing it.');
|
|
203
|
+
}
|
|
204
|
+
if (opts.endpointId !== null) {
|
|
205
|
+
const match = rows.find((r) => r.id === opts.endpointId);
|
|
206
|
+
if (match === undefined) {
|
|
207
|
+
throw new Error(`No webhook endpoint "${opts.endpointId}" in this workspace. The ids are:\n` +
|
|
208
|
+
rows.map((r) => ` ${String(r.id)} ${String(r.url)}`).join('\n'));
|
|
209
|
+
}
|
|
210
|
+
return [match];
|
|
211
|
+
}
|
|
212
|
+
return rows;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* The startup banner.
|
|
216
|
+
*
|
|
217
|
+
* It says what was registered (nothing) and what the signature is (minted
|
|
218
|
+
* here), because both are things a developer would otherwise have to read
|
|
219
|
+
* this file to find out — and the second one changes how they should read a
|
|
220
|
+
* passing verification in their own handler.
|
|
221
|
+
*/
|
|
222
|
+
function banner(opts, endpoints, deps) {
|
|
223
|
+
deps.out(`Tailing ${String(endpoints.length)} webhook endpoint(s) via the delivery log, ` +
|
|
224
|
+
`every ${String(opts.intervalMs / 1000)}s.`);
|
|
225
|
+
for (const e of endpoints) {
|
|
226
|
+
const types = Array.isArray(e.eventTypes) ? e.eventTypes.length : 0;
|
|
227
|
+
deps.out(` ${String(e.id)} ${String(e.url)} ${String(types)} event type(s)` +
|
|
228
|
+
(e.enabled === false ? ' [DISABLED — it receives nothing]' : ''));
|
|
229
|
+
}
|
|
230
|
+
if (opts.events !== null) {
|
|
231
|
+
deps.out(`Filtering to: ${[...opts.events].join(', ')} ` +
|
|
232
|
+
'(client-side — an event no endpoint subscribes to never reaches the log at all)');
|
|
233
|
+
}
|
|
234
|
+
deps.out(opts.forwardTo === null
|
|
235
|
+
? 'Printing only. Pass --forward-to http://localhost:PORT/path to POST each event on.'
|
|
236
|
+
: `Forwarding to ${opts.forwardTo}`);
|
|
237
|
+
if (opts.forwardTo !== null) {
|
|
238
|
+
deps.out(opts.secret === null
|
|
239
|
+
? 'UNSIGNED: no --secret, so forwarded requests carry no x-livechat-signature and your ' +
|
|
240
|
+
"handler's verifier will reject them. Pass the endpoint's whsec_ secret."
|
|
241
|
+
: 'Signed locally with --secret. This is NOT the signature Chatly sent — the delivery log ' +
|
|
242
|
+
'does not store one — so it proves nothing about the original request.');
|
|
243
|
+
}
|
|
244
|
+
deps.out('Registers nothing on the server; there is nothing to clean up. Ctrl-C to stop.\n');
|
|
245
|
+
}
|
|
246
|
+
/** Drop the oldest ids once the set is at its cap. Sets iterate in insertion order. */
|
|
247
|
+
function remember(seen, id) {
|
|
248
|
+
seen.add(id);
|
|
249
|
+
if (seen.size > SEEN_CAP) {
|
|
250
|
+
for (const old of seen) {
|
|
251
|
+
seen.delete(old);
|
|
252
|
+
if (seen.size <= SEEN_CAP) {
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
/** POST one event on, verifying the header we just minted before sending it. */
|
|
259
|
+
async function forward(opts, deps, envelope) {
|
|
260
|
+
if (opts.forwardTo === null) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
const body = JSON.stringify(envelope);
|
|
264
|
+
const headers = {
|
|
265
|
+
'content-type': 'application/json',
|
|
266
|
+
'x-livechat-event': envelope.type,
|
|
267
|
+
'x-livechat-delivery': envelope.id,
|
|
268
|
+
// Not a header Chatly sends. A handler that logs it can tell a replayed
|
|
269
|
+
// local forward from a real delivery, which matters the first time
|
|
270
|
+
// somebody points this at a staging environment.
|
|
271
|
+
'x-chatly-cli-forwarded': '1',
|
|
272
|
+
};
|
|
273
|
+
if (opts.secret !== null) {
|
|
274
|
+
const nowMs = deps.now();
|
|
275
|
+
const signature = signForForward(body, opts.secret, nowMs);
|
|
276
|
+
/*
|
|
277
|
+
* The self-check. `verifyChatlySignature` is the code a customer runs, so
|
|
278
|
+
* if it disagrees with the signer four lines up, the two have drifted on
|
|
279
|
+
* the construction or on the timestamp unit — and forwarding anyway would
|
|
280
|
+
* teach the developer that their correct handler is broken.
|
|
281
|
+
*/
|
|
282
|
+
const check = verifyChatlySignature({
|
|
283
|
+
surface: 'event_webhook',
|
|
284
|
+
body,
|
|
285
|
+
headers: { 'x-livechat-signature': signature },
|
|
286
|
+
secret: opts.secret,
|
|
287
|
+
nowMs,
|
|
288
|
+
});
|
|
289
|
+
if (!check.ok) {
|
|
290
|
+
deps.err(`refusing to forward ${envelope.id}: the signature this CLI minted does not verify ` +
|
|
291
|
+
`(${check.reason}: ${check.message}). This is a bug in chatly listen, not in your ` +
|
|
292
|
+
'handler — please report it.\n');
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
headers['x-livechat-signature'] = signature;
|
|
296
|
+
headers['x-livechat-timestamp'] = signature.slice('t='.length, signature.indexOf(','));
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
const res = await deps.fetchFn(opts.forwardTo, {
|
|
300
|
+
method: 'POST',
|
|
301
|
+
headers,
|
|
302
|
+
body,
|
|
303
|
+
signal: deps.signal,
|
|
304
|
+
});
|
|
305
|
+
if (!res.ok) {
|
|
306
|
+
deps.err(` ↳ ${opts.forwardTo} answered ${String(res.status)}. ` +
|
|
307
|
+
(res.status === 401 || res.status === 403
|
|
308
|
+
? 'That is usually signature verification — check --secret matches the endpoint.\n'
|
|
309
|
+
: '\n'));
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
deps.out(` ↳ ${String(res.status)} from ${opts.forwardTo}`);
|
|
313
|
+
return true;
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
317
|
+
deps.err(` ↳ ${opts.forwardTo} unreachable: ${reason}. Is your server running on that port?\n`);
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* The tail loop, abortable, with the process boundary left to the caller.
|
|
323
|
+
*
|
|
324
|
+
* Exported so the spec can drive it with a bounded `maxPolls` and a scripted
|
|
325
|
+
* fetch, rather than racing a timer against a signal handler.
|
|
326
|
+
*/
|
|
327
|
+
export async function tail(chatly, opts, deps) {
|
|
328
|
+
const endpoints = await resolveEndpoints(chatly, opts);
|
|
329
|
+
banner(opts, endpoints, deps);
|
|
330
|
+
const query = { limit: opts.pageLimit };
|
|
331
|
+
if (opts.endpointId !== null) {
|
|
332
|
+
query['endpointId'] = opts.endpointId;
|
|
333
|
+
}
|
|
334
|
+
if (opts.status !== null) {
|
|
335
|
+
query['status'] = opts.status;
|
|
336
|
+
}
|
|
337
|
+
const seen = new Set();
|
|
338
|
+
let seenCount = 0;
|
|
339
|
+
let forwarded = 0;
|
|
340
|
+
let refused = 0;
|
|
341
|
+
let polls = 0;
|
|
342
|
+
/*
|
|
343
|
+
* The baseline. Without it, the first poll replays everything already in
|
|
344
|
+
* the log — which for a busy workspace is `--limit` surprise POSTs at a
|
|
345
|
+
* handler the developer just started. `--replay N` deliberately leaves the
|
|
346
|
+
* newest N rows unseen, which is the "show me the last few" case.
|
|
347
|
+
*/
|
|
348
|
+
const firstPage = asRows(await chatly.request('GET', '/v1/webhooks/deliveries', { query }));
|
|
349
|
+
for (const row of firstPage.slice(opts.replay)) {
|
|
350
|
+
remember(seen, row.id);
|
|
351
|
+
}
|
|
352
|
+
if (opts.replay > 0) {
|
|
353
|
+
deps.out(`Replaying the ${String(Math.min(opts.replay, firstPage.length))} most recent.\n`);
|
|
354
|
+
}
|
|
355
|
+
const matches = (row) => opts.events === null || opts.events.has(row.eventType);
|
|
356
|
+
for (;;) {
|
|
357
|
+
if (deps.signal.aborted) {
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
if (deps.maxPolls !== undefined && polls >= deps.maxPolls) {
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
polls += 1;
|
|
364
|
+
/*
|
|
365
|
+
* The first poll REUSES the baseline page rather than asking again. Two
|
|
366
|
+
* identical requests back to back is one more than the rate limit needs
|
|
367
|
+
* to see, and with `--replay` the baseline page is exactly what has to be
|
|
368
|
+
* replayed — so there is no case where re-reading it is right.
|
|
369
|
+
*/
|
|
370
|
+
const page = polls === 1
|
|
371
|
+
? firstPage
|
|
372
|
+
: asRows(await chatly.request('GET', '/v1/webhooks/deliveries', { query }));
|
|
373
|
+
// Newest-first off the wire; replay in the order they happened.
|
|
374
|
+
const fresh = page.filter((row) => !seen.has(row.id)).reverse();
|
|
375
|
+
/*
|
|
376
|
+
* Poll 1 is exempt: it is the baseline page, not a window this loop could
|
|
377
|
+
* have overflowed, and with `--replay N` its `fresh` rows are new on
|
|
378
|
+
* purpose. From poll 2 on, a FULL page with nothing already seen on it
|
|
379
|
+
* means ≥ --limit deliveries landed since the last look and some are gone
|
|
380
|
+
* from the window.
|
|
381
|
+
*/
|
|
382
|
+
if (polls > 1 && fresh.length === page.length && page.length === opts.pageLimit) {
|
|
383
|
+
/*
|
|
384
|
+
* Every row on a FULL page was new, so the window may have overflowed
|
|
385
|
+
* between polls and some deliveries were never seen. This command reads
|
|
386
|
+
* one page per poll by design — walking the cursor backwards on every
|
|
387
|
+
* tick would re-read the whole log — so the honest thing is to say it.
|
|
388
|
+
*/
|
|
389
|
+
deps.err(`warning: all ${String(opts.pageLimit)} rows on this page were new, so events may have ` +
|
|
390
|
+
'been missed between polls. Use a shorter --interval or a larger --limit.\n');
|
|
391
|
+
}
|
|
392
|
+
for (const row of fresh) {
|
|
393
|
+
remember(seen, row.id);
|
|
394
|
+
if (!matches(row)) {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
seenCount += 1;
|
|
398
|
+
const detail = await chatly.request('GET', `/v1/webhooks/deliveries/${encodeURIComponent(row.id)}`);
|
|
399
|
+
/*
|
|
400
|
+
* The envelope the worker signs is `{ id, type, payload }`. `id` here
|
|
401
|
+
* is the DELIVERY ROW's id, not the `deliveryId` that was in the
|
|
402
|
+
* original signed body — that value is not stored anywhere readable. It
|
|
403
|
+
* is still stable per attempt, which is what a handler deduping on it
|
|
404
|
+
* needs.
|
|
405
|
+
*/
|
|
406
|
+
const envelope = { id: row.id, type: row.eventType, payload: detail.payload };
|
|
407
|
+
if (opts.json) {
|
|
408
|
+
printJson({ ...envelope, delivery: row });
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
const http = row.httpStatus === null ? '—' : String(row.httpStatus);
|
|
412
|
+
deps.out(`${row.eventType} ${row.id} attempt ${String(row.attempt)} ${row.status} ` +
|
|
413
|
+
`http ${http} ${row.createdAt}` +
|
|
414
|
+
(row.error === null ? '' : ` (${row.error})`));
|
|
415
|
+
}
|
|
416
|
+
if (opts.forwardTo !== null) {
|
|
417
|
+
if (await forward(opts, deps, envelope)) {
|
|
418
|
+
forwarded += 1;
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
refused += 1;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
if (deps.maxPolls !== undefined && polls >= deps.maxPolls) {
|
|
426
|
+
break;
|
|
427
|
+
}
|
|
428
|
+
await deps.sleep(opts.intervalMs, deps.signal);
|
|
429
|
+
}
|
|
430
|
+
return { seen: seenCount, forwarded, refused, polls };
|
|
431
|
+
}
|
|
432
|
+
/** An abortable sleep, so Ctrl-C does not wait out the poll interval. */
|
|
433
|
+
function sleepUntilAborted(ms, signal) {
|
|
434
|
+
return new Promise((resolve) => {
|
|
435
|
+
if (signal.aborted) {
|
|
436
|
+
resolve();
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
const timer = setTimeout(() => {
|
|
440
|
+
signal.removeEventListener('abort', onAbort);
|
|
441
|
+
resolve();
|
|
442
|
+
}, ms);
|
|
443
|
+
function onAbort() {
|
|
444
|
+
clearTimeout(timer);
|
|
445
|
+
resolve();
|
|
446
|
+
}
|
|
447
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* The command entry point.
|
|
452
|
+
*
|
|
453
|
+
* SIGINT and SIGTERM abort the loop rather than killing the process, so the
|
|
454
|
+
* summary still prints and the exit code is 0 — a developer tool stopped on
|
|
455
|
+
* purpose did not fail.
|
|
456
|
+
*/
|
|
457
|
+
export async function listen(chatly, args) {
|
|
458
|
+
const opts = parseListenOptions(args);
|
|
459
|
+
const controller = new AbortController();
|
|
460
|
+
const stop = () => {
|
|
461
|
+
controller.abort();
|
|
462
|
+
};
|
|
463
|
+
process.once('SIGINT', stop);
|
|
464
|
+
process.once('SIGTERM', stop);
|
|
465
|
+
const deps = {
|
|
466
|
+
fetchFn: globalThis.fetch.bind(globalThis),
|
|
467
|
+
now: () => Date.now(),
|
|
468
|
+
sleep: sleepUntilAborted,
|
|
469
|
+
signal: controller.signal,
|
|
470
|
+
out: (line) => {
|
|
471
|
+
process.stdout.write(`${line}\n`);
|
|
472
|
+
},
|
|
473
|
+
err: (line) => {
|
|
474
|
+
process.stderr.write(line);
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
try {
|
|
478
|
+
const summary = await tail(chatly, opts, deps);
|
|
479
|
+
process.stdout.write(`\nStopped. ${String(summary.seen)} event(s) seen` +
|
|
480
|
+
(opts.forwardTo === null
|
|
481
|
+
? '.\n'
|
|
482
|
+
: `, ${String(summary.forwarded)} forwarded, ${String(summary.refused)} not.\n`));
|
|
483
|
+
return 0;
|
|
484
|
+
}
|
|
485
|
+
finally {
|
|
486
|
+
process.off('SIGINT', stop);
|
|
487
|
+
process.off('SIGTERM', stop);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
//# sourceMappingURL=listen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listen.js","sourceRoot":"","sources":["../../src/commands/listen.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAmB,MAAM,YAAY,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAsEzC,6DAA6D;AAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC;AAEvB,MAAM,wBAAwB,GAAG,CAAC,CAAC;AACnC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAE9B;;;;;;;;;;;GAWG;AACH,SAAS,cAAc,CAAC,IAAY,EAAE,MAAc,EAAE,KAAa;IACjE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC9C,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7E,OAAO,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;AAC3B,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAgB;IACxC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACpE,CAAC;SACE,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAC/B,CAAC;IACF,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;AAClD,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,kBAAkB,CAAC,IAAgB;IACjD,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,IAAI,CAAC;IACxD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,IAAI,MAAM,GAAe,IAAI,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;QACD;;;;;;WAMG;QACH,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC;YACrF,MAAM,IAAI,KAAK,CACb,iBAAiB,SAAS,0BACxB,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,8BAA8B,MAAM,CAAC,QAAQ,IACtE,yBAAyB,GAAG,6DAA6D,CAC1F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,eAAe,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,wBAAwB,CAAC;IAChF,IAAI,eAAe,GAAG,oBAAoB,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CACb,cAAc,MAAM,CAAC,eAAe,CAAC,iBAAiB,MAAM,CAAC,oBAAoB,CAAC,WAAW;YAC3F,yFAAyF;YACzF,sDAAsD,CACzD,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,kBAAkB,CAAC;IACjE,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,YAAY,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IACpE,CAAC;IACD,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CACb,YAAY,MAAM,CAAC,MAAM,CAAC,yBAAyB,MAAM,CAAC,SAAS,CAAC,qBAAqB;YACvF,4DAA4D,CAC/D,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC;IACjD,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CACb,iEAAiE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,QAAQ;YACzF,uFAAuF;YACvF,iDAAiD,CACpD,CAAC;IACJ,CAAC;IAED,OAAO;QACL,SAAS;QACT,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,IAAI;QAC/C,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC;QAC9B,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,IAAI;QACzC,MAAM;QACN,UAAU,EAAE,eAAe,GAAG,IAAI;QAClC,MAAM;QACN,SAAS;QACT,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,MAAM,KAAK,GACT,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAE,KAA6B,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACjG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAsB,EAAE;QAC9C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,CAAC,GAAG,GAA8B,CAAC;QACzC,OAAO,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,WAAW,CAAC,KAAK,QAAQ,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,gBAAgB,CAAC,MAAoB,EAAE,IAAmB;IACvE,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,OAAO,CAAU,KAAK,EAAE,cAAc,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAE,SAA2B,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,sFAAsF;YACpF,sDAAsD;YACtD,qBAAqB;YACrB,yFAAyF;YACzF,4DAA4D;YAC5D,uFAAuF;YACvF,uEAAuE,CAC1E,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC;QACzD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CACb,wBAAwB,IAAI,CAAC,UAAU,qCAAqC;gBAC1E,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACpE,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,MAAM,CAAC,IAAmB,EAAE,SAAiC,EAAE,IAAgB;IACtF,IAAI,CAAC,GAAG,CACN,WAAW,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,6CAA6C;QAC9E,SAAS,MAAM,CAAC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAC9C,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,IAAI,CAAC,GAAG,CACN,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,gBAAgB;YACnE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,EAAE,CAAC,CACpE,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,GAAG,CACN,iBAAiB,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YAC9C,iFAAiF,CACpF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,SAAS,KAAK,IAAI;QACrB,CAAC,CAAC,oFAAoF;QACtF,CAAC,CAAC,iBAAiB,IAAI,CAAC,SAAS,EAAE,CACtC,CAAC;IACF,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,GAAG,CACN,IAAI,CAAC,MAAM,KAAK,IAAI;YAClB,CAAC,CAAC,sFAAsF;gBACpF,yEAAyE;YAC7E,CAAC,CAAC,yFAAyF;gBACvF,uEAAuE,CAC9E,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAC;AAC/F,CAAC;AAED,uFAAuF;AACvF,SAAS,QAAQ,CAAC,IAAiB,EAAE,EAAU;IAC7C,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACb,IAAI,IAAI,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjB,IAAI,IAAI,CAAC,IAAI,IAAI,QAAQ,EAAE,CAAC;gBAC1B,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,gFAAgF;AAChF,KAAK,UAAU,OAAO,CACpB,IAAmB,EACnB,IAAgB,EAChB,QAAwD;IAExD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;QAClC,kBAAkB,EAAE,QAAQ,CAAC,IAAI;QACjC,qBAAqB,EAAE,QAAQ,CAAC,EAAE;QAClC,wEAAwE;QACxE,mEAAmE;QACnE,iDAAiD;QACjD,wBAAwB,EAAE,GAAG;KAC9B,CAAC;IAEF,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC3D;;;;;WAKG;QACH,MAAM,KAAK,GAAG,qBAAqB,CAAC;YAClC,OAAO,EAAE,eAAe;YACxB,IAAI;YACJ,OAAO,EAAE,EAAE,sBAAsB,EAAE,SAAS,EAAE;YAC9C,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK;SACN,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CACN,uBAAuB,QAAQ,CAAC,EAAE,kDAAkD;gBAClF,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,iDAAiD;gBACnF,+BAA+B,CAClC,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAAC;QAC5C,OAAO,CAAC,sBAAsB,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IACzF,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE;YAC7C,MAAM,EAAE,MAAM;YACd,OAAO;YACP,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,GAAG,CACN,QAAQ,IAAI,CAAC,SAAS,aAAa,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI;gBACvD,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;oBACvC,CAAC,CAAC,iFAAiF;oBACnF,CAAC,CAAC,IAAI,CAAC,CACZ,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,QAAQ,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,IAAI,CAAC,GAAG,CACN,QAAQ,IAAI,CAAC,SAAS,iBAAiB,MAAM,0CAA0C,CACxF,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,MAAoB,EACpB,IAAmB,EACnB,IAAgB;IAEhB,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvD,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAE9B,MAAM,KAAK,GAAoC,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;IACzE,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;QAC7B,KAAK,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;IACxC,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IAChC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd;;;;;OAKG;IACH,MAAM,SAAS,GAAG,MAAM,CACtB,MAAM,MAAM,CAAC,OAAO,CAAU,KAAK,EAAE,yBAAyB,EAAE,EAAE,KAAK,EAAE,CAAC,CAC3E,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/C,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IACzB,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAC9F,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,GAAgB,EAAW,EAAE,CAC5C,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAEzD,SAAS,CAAC;QACR,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM;QACR,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1D,MAAM;QACR,CAAC;QACD,KAAK,IAAI,CAAC,CAAC;QAEX;;;;;WAKG;QACH,MAAM,IAAI,GACR,KAAK,KAAK,CAAC;YACT,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,MAAM,CAAC,MAAM,MAAM,CAAC,OAAO,CAAU,KAAK,EAAE,yBAAyB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;QAEzF,gEAAgE;QAChE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;QAChE;;;;;;WAMG;QACH,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE,CAAC;YAChF;;;;;eAKG;YACH,IAAI,CAAC,GAAG,CACN,gBAAgB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,kDAAkD;gBACtF,4EAA4E,CAC/E,CAAC;QACJ,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YACvB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClB,SAAS;YACX,CAAC;YACD,SAAS,IAAI,CAAC,CAAC;YACf,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CACjC,KAAK,EACL,2BAA2B,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CACxD,CAAC;YACF;;;;;;eAMG;YACH,MAAM,QAAQ,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;YAC9E,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,SAAS,CAAC,EAAE,GAAG,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;gBACpE,IAAI,CAAC,GAAG,CACN,GAAG,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,EAAE,aAAa,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,MAAM,IAAI;oBAC5E,QAAQ,IAAI,KAAK,GAAG,CAAC,SAAS,EAAE;oBAChC,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,GAAG,CAAC,CACjD,CAAC;YACJ,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;gBAC5B,IAAI,MAAM,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,CAAC;oBACxC,SAAS,IAAI,CAAC,CAAC;gBACjB,CAAC;qBAAM,CAAC;oBACN,OAAO,IAAI,CAAC,CAAC;gBACf,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,IAAI,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC1D,MAAM;QACR,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACxD,CAAC;AAED,yEAAyE;AACzE,SAAS,iBAAiB,CAAC,EAAU,EAAE,MAAmB;IACxD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACnC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC7C,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,EAAE,CAAC,CAAC;QACP,SAAS,OAAO;YACd,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAoB,EAAE,IAAgB;IACjE,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,UAAU,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAE9B,MAAM,IAAI,GAAe;QACvB,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;QAC1C,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;QACrB,KAAK,EAAE,iBAAiB;QACxB,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;YACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE;YACZ,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,cAAc,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB;YAChD,CAAC,IAAI,CAAC,SAAS,KAAK,IAAI;gBACtB,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,KAAK,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CACrF,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
|
package/dist/help.d.ts
CHANGED
|
@@ -22,5 +22,5 @@
|
|
|
22
22
|
* The convention the spec relies on: a command line starts with exactly two
|
|
23
23
|
* spaces and its first word is the command group.
|
|
24
24
|
*/
|
|
25
|
-
export declare const HELP = "chatly \u2014 the Chatly command line\n\nUSAGE\n chatly <command> [subcommand] [flags]\n\nAUTH\n login Store an API key in ~/.config/chatly/config.json (0600)\n logout Remove the stored key\n whoami Which workspace this key belongs to, and its scopes\n\nCONVERSATIONS\n conversations list Open conversations, newest first\n conversations get <id> One conversation\n conversations messages <id> The thread\n conversations send <id> <body>\n Reply as the key's machine identity\n conversations unattended Open with no agent reply yet\n conversations mood <id> Sentiment over the thread\n conversations return-to-bot <id> <bot-id>\n Give an open thread back to an assistant\n\nCONTACTS\n contacts list People in this workspace\n contacts get <id>\n contacts upsert --email --name --external-id --phone\n contacts tag <id> <tag> Add a tag\n contacts journey <id> Timeline: conversations, events, tickets\n contacts cards <id> Customer-card data for this person\n\nTICKETS\n tickets list --status --queue\n tickets get <id>\n tickets comments <id>\n tickets queues\n tickets lineage <id> Merge and split history\n tickets time <id> Time logged\n tickets status-history <id>\n\nKNOWLEDGE + SEARCH\n search <query> Across contacts, conversations, messages, tickets, KB\n kb articles Help-centre articles\n kb article <slug>\n kb collections\n\nEVENTS\n events track <contact-id> <name>\n Fire a CDP event. --prop key=value, repeatable\n events list --contact-id\n\nBOTS + EXTERNAL AGENTS\n bots list | get <id>\n bots create --body. type:\"external\" answers with a secret, ONCE\n bots update <id> --body\n bots update-external <id> --body. webhookUrl, timeoutSeconds, fallbackMessage\n bots rotate-secret <id> New signing secret, shown once. No overlap window\n bots deliveries <id> The push ledger. --status pending|delivered|failed|dead\n bots delivery <id> <delivery-id>\n One delivery, with the exact signed payload\n bots redeliver <id> <delivery-id>\n Queue the recorded payload again, from attempt 0\n bots test-delivery <id> Sign and POST a rehearsal payload; prints the response\n\nROUTING + AUTOMATION\n bot-routes list | fields | create | update <id> | delete <id>\n bot-routes resolve Dry-run the table. --body with a hypothetical visitor\n triggers list | get <id> | upsert | delete <id>\n brands list | get <id> | create | update <id> | delete <id>\n macros list | get <id> | create | update <id> | delete <id>\n email-templates templates | get <kind> | set <kind> | reset <kind>\n knowledge-gaps list | triage <id>\n\nINTEGRATIONS\n webhooks deliveries --status\n webhooks delivery <id>\n webhooks redeliver <id>\n webhooks endpoints Subscriptions, not traffic\n webhooks events The subscribable event catalogue\n webhooks schema-versions\n webhooks create --url --event (repeatable). Answers with whsec_, once\n webhooks pin <id> <version>\n customer-cards list | create | update <id> | delete <id>\n customer-cards rotate-secret <id>\n Update your endpoint BEFORE calling this\n docs-sources list | providers | discover | create | update <id> | delete <id>\n docs-sources sync <id> --full re-reads every page\n docs-sources subscribe <id> A refusal is a success: read the response\n channels list | get <id> | adapters | create | update <id>\n channels rotate-secret <id>\n\nWORKSPACE AS CODE\n plan Diff chatly.json against the live workspace. Reads only\n apply Make the plan's changes. Never deletes unless told\n --file <path> the document (- for stdin). Default: ./chatly.json\n --prune also delete what the document omits\n --write-only also send fields that cannot be read back\n --exit-code plan only: exit 2 when there is drift\n\nAI\n ai providers | quota\n ai add-provider BYOK. --body\n ai test-provider <key>\n ai tools | create-tool | update-tool <id> | delete-tool <id>\n ai tone | set-tone | generate-tone <sample>\n\nREPORTS\n reports overview --days\n reports agents Means, not percentiles\n reports conversations-by-day\n reports sources | response-times | voice\n reports attribution <dim> One of ten dimensions; an unknown one is refused\n reports cohorts --weeks, NOT --days\n reports themes --date. A daily snapshot; there is no regenerate\n reports theme-conversations <theme-id>\n reports teams | labels | sla\n --from --to --days --group-by\n\nBILLING\n billing summary | plans | invoices\n billing usage <event-type> One meter over a window. --from --to\n billing usage-daily <event-type>\n Dense: one row per UTC day, zeros included\n billing usage-monthly --month\n\nWORKSPACE\n workspace settings\n workspace labels | inboxes | skills\n workspace team-members <team-id>\n workspace key-scopes What a key may be granted\n\nRAW\n api <METHOD> <path> Any route, with auth, idempotency and retries\n chatly api GET /v1/feature-flags\n chatly api POST /v1/macros --body '{\"name\":\"Refund\"}'\n\nGLOBAL FLAGS\n --json Raw API response instead of a table\n --all Follow pagination to the end (list commands)\n --limit <n> Page size\n --cursor <c> Start from a cursor\n --key <ck_\u2026> Override the stored key for this call\n --api-url <url> Point at another Chatly environment\n --help, --version\n\nDocs: https://chatlychat.com/docs/sdk-cli\n";
|
|
25
|
+
export declare const HELP = "chatly \u2014 the Chatly command line\n\nUSAGE\n chatly <command> [subcommand] [flags]\n\nAUTH\n login Store an API key in ~/.config/chatly/config.json (0600)\n logout Remove the stored key\n whoami Which workspace this key belongs to, and its scopes\n\nCONVERSATIONS\n conversations list Open conversations, newest first\n conversations get <id> One conversation\n conversations messages <id> The thread\n conversations send <id> <body>\n Reply as the key's machine identity\n conversations unattended Open with no agent reply yet\n conversations mood <id> Sentiment over the thread\n conversations return-to-bot <id> <bot-id>\n Give an open thread back to an assistant\n\nCONTACTS\n contacts list People in this workspace\n contacts get <id>\n contacts upsert --email --name --external-id --phone\n contacts tag <id> <tag> Add a tag\n contacts journey <id> Timeline: conversations, events, tickets\n contacts cards <id> Customer-card data for this person\n\nTICKETS\n tickets list --status --queue\n tickets get <id>\n tickets comments <id>\n tickets queues\n tickets lineage <id> Merge and split history\n tickets time <id> Time logged\n tickets status-history <id>\n\nKNOWLEDGE + SEARCH\n search <query> Across contacts, conversations, messages, tickets, KB\n kb articles Help-centre articles\n kb article <slug>\n kb collections\n\nEVENTS\n events track <contact-id> <name>\n Fire a CDP event. --prop key=value, repeatable\n events list --contact-id\n\nBOTS + EXTERNAL AGENTS\n bots list | get <id>\n bots create --body. type:\"external\" answers with a secret, ONCE\n bots update <id> --body\n bots update-external <id> --body. webhookUrl, timeoutSeconds, fallbackMessage\n bots rotate-secret <id> New signing secret, shown once. No overlap window\n bots deliveries <id> The push ledger. --status pending|delivered|failed|dead\n bots delivery <id> <delivery-id>\n One delivery, with the exact signed payload\n bots redeliver <id> <delivery-id>\n Queue the recorded payload again, from attempt 0\n bots test-delivery <id> Sign and POST a rehearsal payload; prints the response\n\nROUTING + AUTOMATION\n bot-routes list | fields | create | update <id> | delete <id>\n bot-routes resolve Dry-run the table. --body with a hypothetical visitor\n triggers list | get <id> | upsert | delete <id>\n brands list | get <id> | create | update <id> | delete <id>\n macros list | get <id> | create | update <id> | delete <id>\n email-templates templates | get <kind> | set <kind> | reset <kind>\n knowledge-gaps list | triage <id>\n\nINTEGRATIONS\n webhooks deliveries --status\n webhooks delivery <id>\n webhooks redeliver <id>\n webhooks endpoints Subscriptions, not traffic\n webhooks events The subscribable event catalogue\n webhooks schema-versions\n webhooks create --url --event (repeatable). Answers with whsec_, once\n webhooks pin <id> <version>\n customer-cards list | create | update <id> | delete <id>\n customer-cards rotate-secret <id>\n Update your endpoint BEFORE calling this\n docs-sources list | providers | discover | create | update <id> | delete <id>\n docs-sources sync <id> --full re-reads every page\n docs-sources subscribe <id> A refusal is a success: read the response\n channels list | get <id> | adapters | create | update <id>\n channels rotate-secret <id>\n\nDEVELOPING AGAINST WEBHOOKS\n listen Tail this workspace's webhook deliveries and POST\n each one to a local URL. Registers nothing\n --forward-to <url> where to POST (omit to print only)\n --secret <whsec_\u2026> sign the forwarded request\n --endpoint <id> one subscription's traffic only\n --event <name> repeatable; filters client-side\n --status <s> delivered | failed | dead\n --replay <n> forward the n newest rows first\n --interval <seconds> poll interval, default 2\n\nWORKSPACE AS CODE\n plan Diff chatly.json against the live workspace. Reads only\n apply Make the plan's changes. Never deletes unless told\n --file <path> the document (- for stdin). Default: ./chatly.json\n --prune also delete what the document omits\n --write-only also send fields that cannot be read back\n --exit-code plan only: exit 2 when there is drift\n\nAI\n ai providers | quota\n ai add-provider BYOK. --body\n ai test-provider <key>\n ai tools | create-tool | update-tool <id> | delete-tool <id>\n ai tone | set-tone | generate-tone <sample>\n\nREPORTS\n reports overview --days\n reports agents Means, not percentiles\n reports conversations-by-day\n reports sources | response-times | voice\n reports attribution <dim> One of ten dimensions; an unknown one is refused\n reports cohorts --weeks, NOT --days\n reports themes --date. A daily snapshot; there is no regenerate\n reports theme-conversations <theme-id>\n reports teams | labels | sla\n --from --to --days --group-by\n\nBILLING\n billing summary | plans | invoices\n billing usage <event-type> One meter over a window. --from --to\n billing usage-daily <event-type>\n Dense: one row per UTC day, zeros included\n billing usage-monthly --month\n\nWORKSPACE\n workspace settings\n workspace labels | inboxes | skills\n workspace team-members <team-id>\n workspace key-scopes What a key may be granted\n\nRAW\n api <METHOD> <path> Any route, with auth, idempotency and retries\n chatly api GET /v1/feature-flags\n chatly api POST /v1/macros --body '{\"name\":\"Refund\"}'\n\nGLOBAL FLAGS\n --json Raw API response instead of a table\n --all Follow pagination to the end (list commands)\n --limit <n> Page size\n --cursor <c> Start from a cursor\n --key <ck_\u2026> Override the stored key for this call\n --api-url <url> Point at another Chatly environment\n --help, --version\n\nDocs: https://chatlychat.com/docs/sdk-cli\n";
|
|
26
26
|
//# sourceMappingURL=help.d.ts.map
|
package/dist/help.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,IAAI,21NA2JhB,CAAC"}
|
package/dist/help.js
CHANGED
|
@@ -111,6 +111,17 @@ INTEGRATIONS
|
|
|
111
111
|
channels list | get <id> | adapters | create | update <id>
|
|
112
112
|
channels rotate-secret <id>
|
|
113
113
|
|
|
114
|
+
DEVELOPING AGAINST WEBHOOKS
|
|
115
|
+
listen Tail this workspace's webhook deliveries and POST
|
|
116
|
+
each one to a local URL. Registers nothing
|
|
117
|
+
--forward-to <url> where to POST (omit to print only)
|
|
118
|
+
--secret <whsec_…> sign the forwarded request
|
|
119
|
+
--endpoint <id> one subscription's traffic only
|
|
120
|
+
--event <name> repeatable; filters client-side
|
|
121
|
+
--status <s> delivered | failed | dead
|
|
122
|
+
--replay <n> forward the n newest rows first
|
|
123
|
+
--interval <seconds> poll interval, default 2
|
|
124
|
+
|
|
114
125
|
WORKSPACE AS CODE
|
|
115
126
|
plan Diff chatly.json against the live workspace. Reads only
|
|
116
127
|
apply Make the plan's changes. Never deletes unless told
|
package/dist/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2JnB,CAAC"}
|
package/dist/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAkB,YAAY,EAAwB,MAAM,sBAAsB,CAAC;AAE1F,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAkB,YAAY,EAAwB,MAAM,sBAAsB,CAAC;AAE1F,OAAO,EAAwB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AA0BlE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAC7B,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAwDpE,CAAC;AAEF,2EAA2E;AAC3E,eAAO,MAAM,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBpD,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,YAAY,CAAC;AAIxF,wBAAsB,GAAG,CACvB,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAC3B,UAAU,GAAE,aAA8B,GACzC,OAAO,CAAC,MAAM,CAAC,CAkDjB;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAqBvE"}
|
package/dist/run.js
CHANGED
|
@@ -13,6 +13,7 @@ import * as auth from './commands/auth.js';
|
|
|
13
13
|
import * as config from './commands/config.js';
|
|
14
14
|
import * as insights from './commands/insights.js';
|
|
15
15
|
import * as integrations from './commands/integrations.js';
|
|
16
|
+
import * as listenCmd from './commands/listen.js';
|
|
16
17
|
import * as cmd from './commands/resources.js';
|
|
17
18
|
import * as wac from './commands/workspace-as-code.js';
|
|
18
19
|
import { resolveCredentials } from './config.js';
|
|
@@ -26,7 +27,7 @@ import { HELP } from './help.js';
|
|
|
26
27
|
* drifts — it said `0.1.0` while the published package was `0.1.2` — so
|
|
27
28
|
* `cli.spec.ts` asserts the two agree and fails if they do not.
|
|
28
29
|
*/
|
|
29
|
-
const VERSION = '0.
|
|
30
|
+
const VERSION = '0.2.0';
|
|
30
31
|
/** Commands that need no credential. Everything else resolves a key first. */
|
|
31
32
|
const UNAUTHENTICATED = new Set(['login', 'logout', 'help', 'version']);
|
|
32
33
|
/**
|
|
@@ -62,6 +63,15 @@ export const COMMANDS = {
|
|
|
62
63
|
'knowledge-gaps': config.knowledgeGaps,
|
|
63
64
|
// ── Integrations ──────────────────────────────────────────────────────
|
|
64
65
|
webhooks: integrations.webhooks,
|
|
66
|
+
/*
|
|
67
|
+
* `listen` sits beside `webhooks` rather than under it, because it is not a
|
|
68
|
+
* CRUD verb on the same resource — it is the `stripe listen` equivalent, a
|
|
69
|
+
* long-running tail, and it is what a developer types without reading
|
|
70
|
+
* anything first. Read `commands/listen.ts`'s header before changing how it
|
|
71
|
+
* gets its events: the three possible designs are enumerated there and two
|
|
72
|
+
* of them are impossible with a `ck_` key.
|
|
73
|
+
*/
|
|
74
|
+
listen: listenCmd.listen,
|
|
65
75
|
'customer-cards': integrations.customerCards,
|
|
66
76
|
'docs-sources': integrations.docsSources,
|
|
67
77
|
channels: integrations.channels,
|
package/dist/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatlychat/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "The Chatly command line — inspect conversations, send replies, read reports and call any API route from a terminal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/chatlychat/chatly-cli#readme",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"LICENSE"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@chatlychat/sdk-node": "0.
|
|
33
|
+
"@chatlychat/sdk-node": "0.4.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "20.14.10",
|