@chatlychat/cli 0.0.0-stage → 0.1.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.
@@ -0,0 +1,377 @@
1
+ import { bool, num, str } from '../args.js';
2
+ import { itemsOf, nextCursorOf, printJson, printTable } from '../output.js';
3
+ /** Shared list behaviour: one page, or every page with `--all`. */
4
+ async function renderList(args, columns, onePage, everyPage) {
5
+ const json = bool(args.flags, 'json');
6
+ if (bool(args.flags, 'all')) {
7
+ if (everyPage === undefined) {
8
+ process.stderr.write('--all is not available for this command (it is not cursor-paginated).\n');
9
+ return 1;
10
+ }
11
+ const rows = [];
12
+ for await (const row of everyPage()) {
13
+ rows.push(row);
14
+ }
15
+ if (json) {
16
+ printJson(rows);
17
+ }
18
+ else {
19
+ printTable(rows, columns);
20
+ }
21
+ return 0;
22
+ }
23
+ const query = {};
24
+ const limit = num(args.flags, 'limit');
25
+ if (limit !== undefined) {
26
+ query['limit'] = limit;
27
+ }
28
+ const cursor = str(args.flags, 'cursor');
29
+ if (cursor !== undefined) {
30
+ query['cursor'] = cursor;
31
+ }
32
+ const page = await onePage(query);
33
+ if (json) {
34
+ printJson(page);
35
+ return 0;
36
+ }
37
+ printTable(itemsOf(page), columns);
38
+ const next = nextCursorOf(page);
39
+ if (next !== null) {
40
+ process.stdout.write(`next page: --cursor ${next} (or --all)\n`);
41
+ }
42
+ return 0;
43
+ }
44
+ /** `--prop key=value`, repeatable, into an object. */
45
+ function props(args) {
46
+ const raw = args.flags['prop'];
47
+ const list = raw === undefined ? [] : Array.isArray(raw) ? raw : [String(raw)];
48
+ if (list.length === 0) {
49
+ return undefined;
50
+ }
51
+ const out = {};
52
+ for (const pair of list) {
53
+ const eq = pair.indexOf('=');
54
+ if (eq <= 0) {
55
+ throw new Error(`--prop expects key=value, got "${pair}"`);
56
+ }
57
+ out[pair.slice(0, eq)] = pair.slice(eq + 1);
58
+ }
59
+ return out;
60
+ }
61
+ function need(args, index, what) {
62
+ const value = args.path[index];
63
+ if (value === undefined) {
64
+ throw new Error(`Missing ${what}. See \`chatly --help\`.`);
65
+ }
66
+ return value;
67
+ }
68
+ export async function conversations(chatly, args) {
69
+ const sub = args.path[1] ?? 'list';
70
+ const json = bool(args.flags, 'json');
71
+ switch (sub) {
72
+ case 'list':
73
+ return renderList(args, ['id', 'status', 'channel', 'contactId', 'lastMessageAt'], (q) => chatly.conversations.list(q), () => chatly.conversations.listAll());
74
+ case 'get': {
75
+ printJson(await chatly.conversations.get(need(args, 2, 'a conversation id')));
76
+ return 0;
77
+ }
78
+ case 'messages': {
79
+ const page = await chatly.conversations.messages(need(args, 2, 'a conversation id'));
80
+ if (json) {
81
+ printJson(page);
82
+ return 0;
83
+ }
84
+ printTable(itemsOf(page), ['id', 'authorType', 'kind', 'body', 'createdAt'], 60);
85
+ return 0;
86
+ }
87
+ case 'send': {
88
+ const id = need(args, 2, 'a conversation id');
89
+ const body = args.path.slice(3).join(' ') || str(args.flags, 'body');
90
+ if (body === undefined || body.length === 0) {
91
+ throw new Error('Nothing to send. `chatly conversations send <id> "your reply"`.');
92
+ }
93
+ const sent = await chatly.conversations.send({ conversationId: id, body });
94
+ if (json) {
95
+ printJson(sent);
96
+ }
97
+ else {
98
+ process.stdout.write('sent\n');
99
+ }
100
+ return 0;
101
+ }
102
+ case 'unattended': {
103
+ const res = await chatly.conversations.unattended();
104
+ if (json) {
105
+ printJson(res);
106
+ return 0;
107
+ }
108
+ printTable(itemsOf(res), ['id', 'status', 'channel', 'waitingSince']);
109
+ return 0;
110
+ }
111
+ default:
112
+ throw new Error(`Unknown: conversations ${sub}`);
113
+ }
114
+ }
115
+ export async function contacts(chatly, args) {
116
+ const sub = args.path[1] ?? 'list';
117
+ const json = bool(args.flags, 'json');
118
+ switch (sub) {
119
+ case 'list':
120
+ return renderList(args, ['id', 'name', 'email', 'phone', 'externalId'], (q) => chatly.contacts.list(q), () => chatly.contacts.listAll());
121
+ case 'get':
122
+ printJson(await chatly.contacts.get(need(args, 2, 'a contact id')));
123
+ return 0;
124
+ case 'upsert': {
125
+ const input = {
126
+ ...(str(args.flags, 'email') === undefined ? {} : { email: str(args.flags, 'email') }),
127
+ ...(str(args.flags, 'name') === undefined ? {} : { name: str(args.flags, 'name') }),
128
+ ...(str(args.flags, 'phone') === undefined ? {} : { phone: str(args.flags, 'phone') }),
129
+ ...(str(args.flags, 'external-id') === undefined
130
+ ? {}
131
+ : { externalId: str(args.flags, 'external-id') }),
132
+ };
133
+ if (Object.keys(input).length === 0) {
134
+ throw new Error('Nothing to upsert. Pass at least one of --email --name --phone --external-id.');
135
+ }
136
+ printJson(await chatly.contacts.upsert(input));
137
+ return 0;
138
+ }
139
+ case 'tag': {
140
+ const id = need(args, 2, 'a contact id');
141
+ const tag = need(args, 3, 'a tag');
142
+ await chatly.contacts.addTags(id, tag);
143
+ process.stdout.write(`tagged ${id} with "${tag}"\n`);
144
+ return 0;
145
+ }
146
+ case 'journey': {
147
+ const res = await chatly.contacts.journey(need(args, 2, 'a contact id'));
148
+ if (json) {
149
+ printJson(res);
150
+ return 0;
151
+ }
152
+ printTable(itemsOf(res), ['type', 'at', 'summary'], 70);
153
+ return 0;
154
+ }
155
+ default:
156
+ throw new Error(`Unknown: contacts ${sub}`);
157
+ }
158
+ }
159
+ export async function tickets(chatly, args) {
160
+ const sub = args.path[1] ?? 'list';
161
+ switch (sub) {
162
+ case 'list':
163
+ return renderList(args, ['id', 'number', 'subject', 'status', 'priority', 'assigneeId'], (q) => {
164
+ const extra = { ...q };
165
+ const status = str(args.flags, 'status');
166
+ if (status !== undefined) {
167
+ extra['status'] = status;
168
+ }
169
+ const queue = str(args.flags, 'queue');
170
+ if (queue !== undefined) {
171
+ extra['queue'] = queue;
172
+ }
173
+ return chatly.tickets.list(extra);
174
+ }, () => chatly.tickets.listAll());
175
+ case 'comments':
176
+ printJson(await chatly.tickets.comments(need(args, 2, 'a ticket id')));
177
+ return 0;
178
+ case 'queues':
179
+ printJson(await chatly.tickets.queues());
180
+ return 0;
181
+ default:
182
+ throw new Error(`Unknown: tickets ${sub}`);
183
+ }
184
+ }
185
+ export async function search(chatly, args) {
186
+ const query = args.path.slice(1).join(' ');
187
+ if (query.length === 0) {
188
+ throw new Error('Nothing to search for. `chatly search "refund policy"`.');
189
+ }
190
+ const res = await chatly.search.query(query);
191
+ if (bool(args.flags, 'json')) {
192
+ printJson(res);
193
+ return 0;
194
+ }
195
+ printTable(itemsOf(res), ['kind', 'id', 'title', 'snippet'], 60);
196
+ return 0;
197
+ }
198
+ export async function kb(chatly, args) {
199
+ const sub = args.path[1] ?? 'articles';
200
+ switch (sub) {
201
+ case 'articles':
202
+ return renderList(args, ['id', 'slug', 'title', 'status', 'updatedAt'], (q) => chatly.kb.list(q), () => chatly.kb.listAll());
203
+ case 'article':
204
+ printJson(await chatly.kb.article(need(args, 2, 'an article slug')));
205
+ return 0;
206
+ case 'collections':
207
+ printJson(await chatly.kb.collections());
208
+ return 0;
209
+ default:
210
+ throw new Error(`Unknown: kb ${sub}`);
211
+ }
212
+ }
213
+ export async function events(chatly, args) {
214
+ const sub = args.path[1] ?? 'list';
215
+ switch (sub) {
216
+ case 'track': {
217
+ const contactId = need(args, 2, 'a contact id');
218
+ const name = need(args, 3, 'an event name');
219
+ const properties = props(args);
220
+ await chatly.events.track({ contactId, name, ...(properties ? { properties } : {}) });
221
+ process.stdout.write(`tracked "${name}" for ${contactId}\n`);
222
+ return 0;
223
+ }
224
+ case 'list':
225
+ return renderList(args, ['id', 'name', 'contactId', 'createdAt'], (q) => {
226
+ const extra = { ...q };
227
+ const contactId = str(args.flags, 'contact-id');
228
+ if (contactId !== undefined) {
229
+ extra['contactId'] = contactId;
230
+ }
231
+ return chatly.events.list(extra);
232
+ }, () => chatly.events.listAll());
233
+ default:
234
+ throw new Error(`Unknown: events ${sub}`);
235
+ }
236
+ }
237
+ export async function webhooks(chatly, args) {
238
+ const sub = args.path[1] ?? 'deliveries';
239
+ switch (sub) {
240
+ case 'deliveries':
241
+ return renderList(args, ['id', 'event', 'status', 'responseStatus', 'attempts', 'createdAt'], (q) => chatly.webhooks.list(q), () => chatly.webhooks.listAll());
242
+ case 'delivery':
243
+ printJson(await chatly.webhooks.delivery(need(args, 2, 'a delivery id')));
244
+ return 0;
245
+ case 'redeliver': {
246
+ const id = need(args, 2, 'a delivery id');
247
+ printJson(await chatly.webhooks.redeliver(id));
248
+ return 0;
249
+ }
250
+ default:
251
+ throw new Error(`Unknown: webhooks ${sub}`);
252
+ }
253
+ }
254
+ export async function reports(chatly, args) {
255
+ const sub = args.path[1] ?? 'overview';
256
+ const range = {};
257
+ const from = str(args.flags, 'from');
258
+ if (from !== undefined) {
259
+ range['from'] = from;
260
+ }
261
+ const to = str(args.flags, 'to');
262
+ if (to !== undefined) {
263
+ range['to'] = to;
264
+ }
265
+ switch (sub) {
266
+ case 'overview':
267
+ printJson(await chatly.reports.overview(range));
268
+ return 0;
269
+ case 'agents':
270
+ printJson(await chatly.reports.agents(range));
271
+ return 0;
272
+ case 'sla':
273
+ printJson(await chatly.reports.sla(range));
274
+ return 0;
275
+ case 'conversations-by-day':
276
+ printJson(await chatly.reports.conversationsByDay(range));
277
+ return 0;
278
+ default:
279
+ throw new Error(`Unknown: reports ${sub}`);
280
+ }
281
+ }
282
+ export async function workspace(chatly, args) {
283
+ const sub = args.path[1] ?? 'settings';
284
+ const json = bool(args.flags, 'json');
285
+ const show = (value, columns) => {
286
+ if (json) {
287
+ printJson(value);
288
+ }
289
+ else {
290
+ printTable(itemsOf(value), columns);
291
+ }
292
+ return 0;
293
+ };
294
+ switch (sub) {
295
+ case 'settings':
296
+ printJson(await chatly.workspace.settings());
297
+ return 0;
298
+ case 'labels':
299
+ return show(await chatly.workspace.labels(), ['id', 'name', 'color']);
300
+ case 'inboxes':
301
+ return show(await chatly.workspace.inboxes(), ['id', 'name', 'channelId']);
302
+ case 'team-members': {
303
+ const teamId = args.path[2];
304
+ if (teamId === undefined) {
305
+ throw new Error('Give a team id: `chatly workspace team-members <team-id>`.\n' +
306
+ 'There is no key-accessible route that lists teams — take the id from a ' +
307
+ "conversation's teamId or an inbox's routingTeamId.");
308
+ }
309
+ return show(await chatly.workspace.teamMembers(teamId), ['id', 'name', 'email', 'role']);
310
+ }
311
+ case 'skills':
312
+ printJson(await chatly.workspace.agentSkills());
313
+ return 0;
314
+ default:
315
+ throw new Error(`Unknown: workspace ${sub}`);
316
+ }
317
+ }
318
+ export async function channels(chatly, args) {
319
+ const sub = args.path[1] ?? 'list';
320
+ if (sub === 'get') {
321
+ printJson(await chatly.channels.get(need(args, 2, 'a channel id')));
322
+ return 0;
323
+ }
324
+ const res = await chatly.channels.list();
325
+ if (bool(args.flags, 'json')) {
326
+ printJson(res);
327
+ return 0;
328
+ }
329
+ printTable(itemsOf(res), ['id', 'publicId', 'type', 'name', 'status']);
330
+ return 0;
331
+ }
332
+ export async function billing(chatly, args) {
333
+ const sub = args.path[1] ?? 'usage';
334
+ if (sub === 'plans') {
335
+ printJson(await chatly.billing.plans());
336
+ return 0;
337
+ }
338
+ printJson(await chatly.billing.usage());
339
+ return 0;
340
+ }
341
+ /**
342
+ * The raw passthrough — `gh api` for Chatly.
343
+ *
344
+ * 85 of the 140 key-accessible routes have no named command here, and adding
345
+ * one for each would be a worse CLI. This keeps every route reachable with
346
+ * the same auth, idempotency key, retry policy and typed errors.
347
+ */
348
+ export async function api(chatly, args) {
349
+ const method = (args.path[1] ?? 'GET').toUpperCase();
350
+ if (!['GET', 'POST', 'PATCH', 'PUT', 'DELETE'].includes(method)) {
351
+ throw new Error(`Unsupported method "${method}". Use GET, POST, PATCH, PUT or DELETE.`);
352
+ }
353
+ const path = args.path[2];
354
+ if (path === undefined || !path.startsWith('/')) {
355
+ throw new Error('Give a path: `chatly api GET /v1/feature-flags`.');
356
+ }
357
+ const rawBody = str(args.flags, 'body');
358
+ let body;
359
+ if (rawBody !== undefined) {
360
+ try {
361
+ body = JSON.parse(rawBody);
362
+ }
363
+ catch {
364
+ throw new Error(`--body is not valid JSON: ${rawBody.slice(0, 60)}`);
365
+ }
366
+ }
367
+ const query = {};
368
+ for (const [k, v] of Object.entries(args.flags)) {
369
+ if (k.startsWith('q-') && typeof v === 'string') {
370
+ query[k.slice(2)] = v;
371
+ }
372
+ }
373
+ const res = await chatly.request(method, path, { query, ...(body === undefined ? {} : { body }) });
374
+ printJson(res ?? { ok: true });
375
+ return 0;
376
+ }
377
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/commands/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Where the API key comes from, in order of precedence.
3
+ *
4
+ * 1. `--key` on the command line — for a one-off against another workspace.
5
+ * 2. `CHATLY_API_KEY` in the environment — the CI shape.
6
+ * 3. `~/.config/chatly/config.json`, written by `chatly login`.
7
+ *
8
+ * The file is created 0600. A workspace API key is a bearer credential for an
9
+ * entire workspace; a world-readable config file is a credential leak on a
10
+ * shared machine, and this repo has already had 35 database dumps readable by
11
+ * anyone who guessed a URL.
12
+ */
13
+ export declare const CONFIG_PATH: string;
14
+ export interface CliConfig {
15
+ apiKey?: string;
16
+ apiUrl?: string;
17
+ }
18
+ export declare function readConfig(path?: string): CliConfig;
19
+ export declare function writeConfig(next: CliConfig, path?: string): void;
20
+ export interface Resolved {
21
+ readonly apiKey: string;
22
+ readonly apiUrl: string | undefined;
23
+ readonly source: 'flag' | 'env' | 'config';
24
+ }
25
+ export declare function resolveCredentials(flagKey: string | undefined, flagUrl: string | undefined, env?: NodeJS.ProcessEnv, path?: string): Resolved;
26
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,QAIvB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,UAAU,CAAC,IAAI,GAAE,MAAoB,GAAG,SAAS,CAkBhE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,GAAE,MAAoB,GAAG,IAAI,CAM7E;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;CAC5C;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,GAAE,MAAoB,GACzB,QAAQ,CAiBV"}
package/dist/config.js ADDED
@@ -0,0 +1,60 @@
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ /**
5
+ * Where the API key comes from, in order of precedence.
6
+ *
7
+ * 1. `--key` on the command line — for a one-off against another workspace.
8
+ * 2. `CHATLY_API_KEY` in the environment — the CI shape.
9
+ * 3. `~/.config/chatly/config.json`, written by `chatly login`.
10
+ *
11
+ * The file is created 0600. A workspace API key is a bearer credential for an
12
+ * entire workspace; a world-readable config file is a credential leak on a
13
+ * shared machine, and this repo has already had 35 database dumps readable by
14
+ * anyone who guessed a URL.
15
+ */
16
+ export const CONFIG_PATH = join(process.env['XDG_CONFIG_HOME'] ?? join(homedir(), '.config'), 'chatly', 'config.json');
17
+ export function readConfig(path = CONFIG_PATH) {
18
+ if (!existsSync(path)) {
19
+ return {};
20
+ }
21
+ try {
22
+ const parsed = JSON.parse(readFileSync(path, 'utf8'));
23
+ if (typeof parsed !== 'object' || parsed === null) {
24
+ return {};
25
+ }
26
+ const obj = parsed;
27
+ return {
28
+ ...(typeof obj['apiKey'] === 'string' ? { apiKey: obj['apiKey'] } : {}),
29
+ ...(typeof obj['apiUrl'] === 'string' ? { apiUrl: obj['apiUrl'] } : {}),
30
+ };
31
+ }
32
+ catch {
33
+ // A corrupt config must not stop `--key` from working.
34
+ return {};
35
+ }
36
+ }
37
+ export function writeConfig(next, path = CONFIG_PATH) {
38
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
39
+ writeFileSync(path, `${JSON.stringify(next, null, 2)}\n`, { mode: 0o600 });
40
+ // `mode` on writeFileSync only applies when the file is CREATED. An existing
41
+ // file keeps whatever permissions it had, so set them explicitly.
42
+ chmodSync(path, 0o600);
43
+ }
44
+ export function resolveCredentials(flagKey, flagUrl, env = process.env, path = CONFIG_PATH) {
45
+ const file = readConfig(path);
46
+ const apiUrl = flagUrl ?? env['CHATLY_API_URL'] ?? file.apiUrl;
47
+ if (flagKey !== undefined && flagKey.length > 0) {
48
+ return { apiKey: flagKey, apiUrl, source: 'flag' };
49
+ }
50
+ const fromEnv = env['CHATLY_API_KEY'];
51
+ if (fromEnv !== undefined && fromEnv.length > 0) {
52
+ return { apiKey: fromEnv, apiUrl, source: 'env' };
53
+ }
54
+ if (file.apiKey !== undefined && file.apiKey.length > 0) {
55
+ return { apiKey: file.apiKey, apiUrl, source: 'config' };
56
+ }
57
+ throw new Error('No API key. Run `chatly login`, set CHATLY_API_KEY, or pass --key.\n' +
58
+ 'Create a key in the dashboard under Settings → API keys.');
59
+ }
60
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/help.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ 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\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\nTICKETS\n tickets list --status --queue\n tickets comments <id>\n tickets queues\n\nKNOWLEDGE + SEARCH\n search <query> Across contacts, conversations, messages, tickets, KB\n kb articles Help-centre articles\n kb article <slug>\n\nEVENTS\n events track <contact-id> <name>\n Fire a CDP event. --prop key=value, repeatable\n events list --contact-id\n\nWEBHOOKS\n webhooks deliveries --status\n webhooks redeliver <id>\n\nREPORTS\n reports overview --from --to\n reports agents\n reports sla\n\nWORKSPACE\n workspace settings\n workspace labels | inboxes | skills\n workspace team-members <team-id>\n channels list | channels get <id>\n billing usage | billing plans\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/cli\n";
2
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,82EAuEhB,CAAC"}
package/dist/help.js ADDED
@@ -0,0 +1,73 @@
1
+ export const HELP = `chatly — the Chatly command line
2
+
3
+ USAGE
4
+ chatly <command> [subcommand] [flags]
5
+
6
+ AUTH
7
+ login Store an API key in ~/.config/chatly/config.json (0600)
8
+ logout Remove the stored key
9
+ whoami Which workspace this key belongs to, and its scopes
10
+
11
+ CONVERSATIONS
12
+ conversations list Open conversations, newest first
13
+ conversations get <id> One conversation
14
+ conversations messages <id> The thread
15
+ conversations send <id> <body>
16
+ Reply as the key's machine identity
17
+ conversations unattended Open with no agent reply yet
18
+
19
+ CONTACTS
20
+ contacts list People in this workspace
21
+ contacts get <id>
22
+ contacts upsert --email --name --external-id --phone
23
+ contacts tag <id> <tag> Add a tag
24
+ contacts journey <id> Timeline: conversations, events, tickets
25
+
26
+ TICKETS
27
+ tickets list --status --queue
28
+ tickets comments <id>
29
+ tickets queues
30
+
31
+ KNOWLEDGE + SEARCH
32
+ search <query> Across contacts, conversations, messages, tickets, KB
33
+ kb articles Help-centre articles
34
+ kb article <slug>
35
+
36
+ EVENTS
37
+ events track <contact-id> <name>
38
+ Fire a CDP event. --prop key=value, repeatable
39
+ events list --contact-id
40
+
41
+ WEBHOOKS
42
+ webhooks deliveries --status
43
+ webhooks redeliver <id>
44
+
45
+ REPORTS
46
+ reports overview --from --to
47
+ reports agents
48
+ reports sla
49
+
50
+ WORKSPACE
51
+ workspace settings
52
+ workspace labels | inboxes | skills
53
+ workspace team-members <team-id>
54
+ channels list | channels get <id>
55
+ billing usage | billing plans
56
+
57
+ RAW
58
+ api <METHOD> <path> Any route, with auth, idempotency and retries
59
+ chatly api GET /v1/feature-flags
60
+ chatly api POST /v1/macros --body '{"name":"Refund"}'
61
+
62
+ GLOBAL FLAGS
63
+ --json Raw API response instead of a table
64
+ --all Follow pagination to the end (list commands)
65
+ --limit <n> Page size
66
+ --cursor <c> Start from a cursor
67
+ --key <ck_…> Override the stored key for this call
68
+ --api-url <url> Point at another Chatly environment
69
+ --help, --version
70
+
71
+ Docs: https://chatlychat.com/docs/cli
72
+ `;
73
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuEnB,CAAC"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
package/dist/main.js ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `chatly` — the command line.
4
+ *
5
+ * Dogfoods `@chatlychat/sdk-node`: every call goes through the published SDK,
6
+ * so the CLI and a customer's own integration exercise the same transport,
7
+ * the same retry policy and the same error model. When the SDK's errors are
8
+ * unhelpful, we feel it first.
9
+ *
10
+ * This file is only the process boundary — argv in, exit code out. The
11
+ * behaviour is in `run.ts`, which takes argv as a parameter and is therefore
12
+ * testable without spawning anything.
13
+ */
14
+ import { explain, run } from './run.js';
15
+ run(process.argv.slice(2))
16
+ .then((code) => {
17
+ process.exitCode = code;
18
+ })
19
+ .catch((err) => {
20
+ const { code, message } = explain(err);
21
+ process.stderr.write(`${message}\n`);
22
+ process.exitCode = code;
23
+ });
24
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAExC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;KACvB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;IACb,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,CAAC;KACD,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IACtB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;IACrC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Rendering. Two modes, and the choice is the caller's, not ours.
3
+ *
4
+ * Default: a table a person reads. `--json`: the raw API response, unmodified,
5
+ * so a script can pipe it to `jq`. The second one matters more than it looks —
6
+ * a CLI that only pretty-prints cannot be used in a pipeline, and a CLI that
7
+ * only emits JSON is unpleasant to use by hand.
8
+ */
9
+ export declare function printJson(value: unknown): void;
10
+ /**
11
+ * A fixed-width table. Width is computed from the content, and every cell is
12
+ * truncated to `max` so one 4KB message body cannot destroy the layout.
13
+ */
14
+ export declare function printTable(rows: ReadonlyArray<unknown>, columns: ReadonlyArray<string>, max?: number): void;
15
+ /** `{ items, nextCursor }` from a list endpoint, defensively. */
16
+ export declare function itemsOf(value: unknown): ReadonlyArray<unknown>;
17
+ export declare function nextCursorOf(value: unknown): string | null;
18
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAE9C;AAiBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,EAC5B,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,GAAG,SAAK,GACP,IAAI,CAmBN;AAED,iEAAiE;AACjE,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,CAe9D;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAQ1D"}