@neetru/cli 2.12.6 → 2.12.7

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,563 @@
1
+ /**
2
+ * Submenu de Chat — integrado ao menu interativo do CLI (`neetru` sem args).
3
+ *
4
+ * Exporta `runChatMenu()` que `ui.ts` chama quando o usuário seleciona "Chat"
5
+ * no menu principal.
6
+ *
7
+ * Fluxo:
8
+ * runChatMenu()
9
+ * └─ promptSubMenu "Chat"
10
+ * ├─ "Listar canais" → lista + seleciona → entrar no canal
11
+ * ├─ "Entrar em canal" → digita id ou escolhe → loop interativo
12
+ * ├─ "Abrir canal novo" → prompt nome/tipo → cria
13
+ * ├─ "Fechar canal" → prompt id → fecha (bloqueia 'global')
14
+ * └─ "Voltar"
15
+ *
16
+ * Loop interativo de canal (entrar em canal):
17
+ * - Exibe histórico das últimas 24h ao entrar.
18
+ * - readline pra enviar mensagem (Enter envia; linha em branco sai; Ctrl-C sai).
19
+ * - Ao sair volta pro submenu de chat.
20
+ *
21
+ * Ciclo de vida do stdin:
22
+ * - O `promptSubMenu` de `ui.ts` deixa o stdin "quente" (raw) antes de chamar
23
+ * `runChatMenu`. O loop interativo de canal usa `createInterface` (readline)
24
+ * que funciona sem raw mode. Antes de abrir o readline saímos do raw mode e
25
+ * restauramos ao terminar — padrão igual ao usado em `runChatLoop` de chat.ts.
26
+ * - `runChatMenu` NUNCA chama `process.exit` diretamente — a blindagem de
27
+ * `runTerminalUi` substitui `process.exit` por throw.
28
+ */
29
+ import chalk from 'chalk';
30
+ import ora from 'ora';
31
+ import inquirer from 'inquirer';
32
+ import { createInterface } from 'node:readline';
33
+ import { apiRequest } from '../lib/api-client.js';
34
+ import { resolveToken } from '../lib/cli-read.js';
35
+ import { log } from '../utils/logger.js';
36
+ import { fmtTimestamp } from '../lib/render.js';
37
+ // ─── Helpers de display ───────────────────────────────────────────────────────
38
+ function channelTypeLabel(type) {
39
+ if (type === 'global')
40
+ return chalk.cyan('global');
41
+ if (type === 'product')
42
+ return chalk.blue('produto');
43
+ return chalk.dim('custom');
44
+ }
45
+ function channelTypeLabelPlain(type) {
46
+ if (type === 'global')
47
+ return 'global';
48
+ if (type === 'product')
49
+ return 'produto';
50
+ return 'custom';
51
+ }
52
+ /** Converte createdAt (Timestamp, string, number, ou unknown) em milissegundos. */
53
+ function toMillis(value) {
54
+ if (!value)
55
+ return 0;
56
+ if (typeof value === 'number')
57
+ return value;
58
+ if (typeof value === 'string')
59
+ return Date.parse(value) || 0;
60
+ // Firestore Timestamp-like: { seconds, nanoseconds }
61
+ if (typeof value === 'object' && value !== null) {
62
+ const obj = value;
63
+ if (typeof obj['seconds'] === 'number')
64
+ return obj['seconds'] * 1000;
65
+ if (typeof obj['_seconds'] === 'number')
66
+ return obj['_seconds'] * 1000;
67
+ // Instância com método toMillis()
68
+ if (typeof obj.toMillis === 'function') {
69
+ return obj.toMillis();
70
+ }
71
+ }
72
+ return 0;
73
+ }
74
+ /** Formata createdAt como HH:MM (hora local curta). */
75
+ function fmtHHMM(value) {
76
+ const ms = toMillis(value);
77
+ if (!ms)
78
+ return '--:--';
79
+ const d = new Date(ms);
80
+ return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;
81
+ }
82
+ function colorRole(role) {
83
+ if (role === 'operator')
84
+ return chalk.green('operador');
85
+ return chalk.cyan('dev');
86
+ }
87
+ function colorRoleSystem() {
88
+ return chalk.gray('sistema');
89
+ }
90
+ function actorLabel(msg) {
91
+ const email = msg.author?.email ?? msg.author?.actorId ?? '?';
92
+ const type = msg.author?.actorType ?? 'cli';
93
+ if (type === 'agent_claude')
94
+ return chalk.magenta(`[IA] ${email}`);
95
+ if (type === 'human') {
96
+ if (msg.role === 'operator')
97
+ return chalk.green(email);
98
+ return chalk.cyan(email);
99
+ }
100
+ // cli / sistema
101
+ return chalk.gray(`[cli] ${email}`);
102
+ }
103
+ /** Imprime uma mensagem individual com layout caprichado. */
104
+ function printMessage(msg) {
105
+ const ts = chalk.dim(fmtHHMM(msg.createdAt));
106
+ const type = msg.author?.actorType ?? 'cli';
107
+ const roleTag = type === 'agent_claude'
108
+ ? colorRoleSystem()
109
+ : colorRole(msg.role);
110
+ const actor = actorLabel(msg);
111
+ // Linha de cabeçalho: timestamp + role + autor
112
+ process.stdout.write(`${ts} ${roleTag} ${actor}\n`);
113
+ // Corpo indentado
114
+ const lines = msg.body.split('\n');
115
+ for (const l of lines) {
116
+ process.stdout.write(` ${l}\n`);
117
+ }
118
+ process.stdout.write('\n');
119
+ }
120
+ function printChannel(ch) {
121
+ const tag = channelTypeLabel(ch.type);
122
+ const slug = ch.productSlug ? chalk.dim(` (${ch.productSlug})`) : '';
123
+ const lastMsg = ch.lastMessageAt
124
+ ? chalk.dim(` última msg: ${fmtTimestamp(ch.lastMessageAt)}`)
125
+ : '';
126
+ console.log(` ${chalk.bold(ch.name)}${slug} ${tag} ${chalk.dim(ch.id)}${lastMsg}`);
127
+ }
128
+ // ─── API helpers ──────────────────────────────────────────────────────────────
129
+ async function fetchChannels(token) {
130
+ const res = await apiRequest('/api/cli/v1/chat/channels', { token });
131
+ return res.channels ?? [];
132
+ }
133
+ async function fetchMessages(token, channelId, sinceHours = 24) {
134
+ const qs = new URLSearchParams({ channelId, sinceHours: String(sinceHours) });
135
+ const res = await apiRequest(`/api/cli/v1/chat?${qs.toString()}`, { token });
136
+ return res.messages ?? [];
137
+ }
138
+ async function postMessage(token, channelId, text) {
139
+ const res = await apiRequest('/api/cli/v1/chat', {
140
+ method: 'POST',
141
+ token,
142
+ body: { channelId, message: text, actorType: 'cli' },
143
+ });
144
+ return res.id;
145
+ }
146
+ async function createChannel(token, name, type, productSlug) {
147
+ const res = await apiRequest('/api/cli/v1/chat/channels', {
148
+ method: 'POST',
149
+ token,
150
+ body: { name, type, ...(productSlug ? { productSlug } : {}) },
151
+ });
152
+ return res.id;
153
+ }
154
+ async function closeChannel(token, channelId) {
155
+ await apiRequest(`/api/cli/v1/chat/channels/${channelId}/close`, {
156
+ method: 'POST',
157
+ token,
158
+ body: {},
159
+ });
160
+ }
161
+ // ─── Loop interativo de canal ─────────────────────────────────────────────────
162
+ /** Largura da linha divisória ajustada ao terminal (máx 72). */
163
+ function divider(width = 72) {
164
+ const w = Math.min(width, process.stdout.columns ?? width);
165
+ return chalk.dim('─'.repeat(w));
166
+ }
167
+ /**
168
+ * Entra no loop de mensagens de um canal. Mostra histórico das últimas 24h,
169
+ * depois readline pra enviar mensagens. Linha em branco ou Ctrl-C volta pro
170
+ * menu de chat.
171
+ *
172
+ * Polling real-time: timer a cada ~2.5s busca mensagens novas (dedup por id).
173
+ * As mensagens novas são impressas ACIMA do prompt readline (re-escrevendo a
174
+ * linha de input) de forma não-intrusiva. Timer é limpo no cleanup.
175
+ *
176
+ * Gerencia raw mode: desativa raw ao entrar (readline precisa de modo canônico)
177
+ * e restaura ao sair.
178
+ */
179
+ async function runChannelLoop(token, channel) {
180
+ const POLL_INTERVAL_MS = 2500;
181
+ // Sai do raw mode pra readline funcionar corretamente
182
+ const wasRaw = process.stdin.isRaw === true;
183
+ if (typeof process.stdin.setRawMode === 'function') {
184
+ process.stdin.setRawMode(false);
185
+ }
186
+ process.stdout.write('\x1B[?25h'); // mostra cursor
187
+ let pollTimer = null;
188
+ try {
189
+ // ── Limpa a tela e imprime o header do canal ──────────────────────────
190
+ process.stdout.write('\x1B[2J\x1B[H'); // clear screen, cursor ao topo
191
+ const typeLabel = channelTypeLabelPlain(channel.type);
192
+ const headerLine = ` ${chalk.bold.cyan(channel.name)}` +
193
+ ` ${chalk.dim(`[${typeLabel}]`)}` +
194
+ (channel.productSlug ? chalk.dim(` produto: ${channel.productSlug}`) : '') +
195
+ ` ${chalk.dim(channel.id)}`;
196
+ process.stdout.write(`\n${divider()}\n`);
197
+ process.stdout.write(`${headerLine}\n`);
198
+ process.stdout.write(`${divider()}\n`);
199
+ process.stdout.write(chalk.dim(' Ctrl-C ou linha em branco para sair · mensagens novas aparecem automaticamente\n'));
200
+ process.stdout.write(`${divider()}\n\n`);
201
+ // ── Carrega histórico das últimas 24h ─────────────────────────────────
202
+ const spinner = ora({ text: 'Carregando histórico…', color: 'cyan' }).start();
203
+ let messages = [];
204
+ try {
205
+ messages = await fetchMessages(token, channel.id);
206
+ spinner.stop();
207
+ }
208
+ catch {
209
+ spinner.fail('Falha ao carregar histórico — continuando sem ele.');
210
+ }
211
+ // Conjunto de IDs já vistos (dedup do polling)
212
+ const seenIds = new Set(messages.map((m) => m.id));
213
+ if (messages.length > 0) {
214
+ process.stdout.write(chalk.dim(` Últimas 24h — ${messages.length} mensagem(ns):\n\n`));
215
+ for (const msg of messages)
216
+ printMessage(msg);
217
+ }
218
+ else {
219
+ process.stdout.write(chalk.dim(' Nenhuma mensagem nas últimas 24h.\n\n'));
220
+ }
221
+ if (!process.stdin.isTTY) {
222
+ log.error('Terminal não-interativo — não é possível enviar mensagens aqui.');
223
+ return;
224
+ }
225
+ // ── Readline de input ─────────────────────────────────────────────────
226
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
227
+ /**
228
+ * Imprime mensagens novas sem quebrar o prompt do readline.
229
+ * Estratégia: apaga a linha do prompt atual (ANSI), imprime as msgs,
230
+ * depois re-escreve o prompt. Degradação graciosa em terminais sem ANSI.
231
+ */
232
+ const printNewMessages = (newMsgs) => {
233
+ if (newMsgs.length === 0)
234
+ return;
235
+ // Apaga a linha do prompt atual
236
+ process.stdout.write('\r\x1B[K');
237
+ for (const msg of newMsgs)
238
+ printMessage(msg);
239
+ // Re-escreve o prompt manualmente (readline não tem API pública pra isso)
240
+ process.stdout.write(chalk.cyan('> '));
241
+ };
242
+ // ── Timer de polling ──────────────────────────────────────────────────
243
+ let pollActive = true;
244
+ pollTimer = setInterval(() => {
245
+ if (!pollActive)
246
+ return;
247
+ fetchMessages(token, channel.id)
248
+ .then((all) => {
249
+ if (!pollActive)
250
+ return;
251
+ const newMsgs = all.filter((m) => !seenIds.has(m.id));
252
+ if (newMsgs.length > 0) {
253
+ // Ordena por createdAt antes de exibir
254
+ newMsgs.sort((a, b) => toMillis(a.createdAt) - toMillis(b.createdAt));
255
+ for (const m of newMsgs)
256
+ seenIds.add(m.id);
257
+ printNewMessages(newMsgs);
258
+ }
259
+ })
260
+ .catch(() => {
261
+ // Silencia erros de polling — não interrompe o uso
262
+ });
263
+ }, POLL_INTERVAL_MS);
264
+ // ── Loop de input ─────────────────────────────────────────────────────
265
+ const askLine = () => new Promise((resolve) => {
266
+ rl.question(chalk.cyan('> '), (answer) => resolve(answer.trim()));
267
+ });
268
+ // eslint-disable-next-line no-constant-condition
269
+ while (true) {
270
+ let line;
271
+ try {
272
+ line = await askLine();
273
+ }
274
+ catch {
275
+ // Ctrl-C ou fechamento do stream
276
+ break;
277
+ }
278
+ if (!line)
279
+ break;
280
+ const sendSpinner = ora({ text: 'Enviando…', color: 'cyan' }).start();
281
+ try {
282
+ const id = await postMessage(token, channel.id, line);
283
+ sendSpinner.stop();
284
+ // Adiciona o id ao seenIds para o polling não reexibir a própria msg
285
+ seenIds.add(id);
286
+ // Confirmação discreta inline
287
+ process.stdout.write(chalk.dim(` ✓ enviado\n\n`));
288
+ }
289
+ catch (error) {
290
+ sendSpinner.fail('Falha ao enviar.');
291
+ if (error instanceof Error) {
292
+ process.stdout.write(chalk.red(` ${error.message}\n`));
293
+ }
294
+ // Não encerra o loop — permite tentar de novo
295
+ }
296
+ }
297
+ pollActive = false;
298
+ rl.close();
299
+ process.stdout.write(chalk.dim('\n (Saindo do canal…)\n\n'));
300
+ }
301
+ finally {
302
+ // Para o timer de polling
303
+ if (pollTimer !== null) {
304
+ clearInterval(pollTimer);
305
+ pollTimer = null;
306
+ }
307
+ // Restaura raw mode pro menu retomar corretamente
308
+ if (typeof process.stdin.setRawMode === 'function') {
309
+ process.stdin.setRawMode(wasRaw);
310
+ }
311
+ process.stdin.resume();
312
+ }
313
+ }
314
+ // ─── Submenu: listar canais e selecionar ─────────────────────────────────────
315
+ /**
316
+ * Lista canais, exibe tabela, e oferece seleção via inquirer (modo não-raw).
317
+ * Retorna o canal selecionado ou `null` se o usuário cancelou.
318
+ */
319
+ async function promptSelectChannel(token, channels) {
320
+ if (channels.length === 0) {
321
+ log.dim('Nenhum canal aberto encontrado.');
322
+ return null;
323
+ }
324
+ console.log();
325
+ console.log(chalk.bold('Canais disponíveis:\n'));
326
+ for (const ch of channels)
327
+ printChannel(ch);
328
+ console.log();
329
+ const choices = [
330
+ ...channels.map((ch) => ({
331
+ name: `${chalk.bold(ch.name)} ${channelTypeLabel(ch.type)} ${chalk.dim(ch.id)}`,
332
+ value: ch.id,
333
+ short: ch.name,
334
+ })),
335
+ { name: chalk.dim('Cancelar'), value: '__cancel__', short: 'Cancelar' },
336
+ ];
337
+ const { selected } = await inquirer.prompt([
338
+ {
339
+ type: 'list',
340
+ name: 'selected',
341
+ message: 'Selecione um canal:',
342
+ choices,
343
+ },
344
+ ]);
345
+ if (selected === '__cancel__')
346
+ return null;
347
+ return channels.find((ch) => ch.id === selected) ?? null;
348
+ }
349
+ // ─── Submenu: criar canal ─────────────────────────────────────────────────────
350
+ async function promptCreateChannel(token) {
351
+ const { name, type } = await inquirer.prompt([
352
+ {
353
+ type: 'input',
354
+ name: 'name',
355
+ message: 'Nome do canal:',
356
+ validate: (v) => v.trim().length > 0 || 'Obrigatório.',
357
+ },
358
+ {
359
+ type: 'list',
360
+ name: 'type',
361
+ message: 'Tipo do canal:',
362
+ choices: [
363
+ { name: 'Produto (vinculado a um produto Neetru)', value: 'product', short: 'produto' },
364
+ { name: 'Geral (sem produto específico)', value: 'custom', short: 'geral' },
365
+ ],
366
+ },
367
+ ]);
368
+ let productSlug;
369
+ if (type === 'product') {
370
+ const ans = await inquirer.prompt([
371
+ {
372
+ type: 'input',
373
+ name: 'slug',
374
+ message: 'Slug do produto (ex: pdv-agiliza):',
375
+ validate: (v) => v.trim().length > 0 || 'Obrigatório.',
376
+ },
377
+ ]);
378
+ productSlug = ans.slug.trim();
379
+ }
380
+ const spinner = ora({ text: 'Criando canal…', color: 'blue' }).start();
381
+ try {
382
+ const id = await createChannel(token, name.trim(), type, productSlug);
383
+ spinner.stop();
384
+ log.success(`Canal criado com sucesso (id: ${id})`);
385
+ }
386
+ catch (error) {
387
+ spinner.fail('Falha ao criar canal.');
388
+ if (error instanceof Error)
389
+ console.error(chalk.red(` ${error.message}`));
390
+ }
391
+ }
392
+ // ─── Submenu: fechar canal ────────────────────────────────────────────────────
393
+ async function promptCloseChannel(token, channels) {
394
+ const closeable = channels.filter((ch) => ch.id !== 'global');
395
+ if (closeable.length === 0) {
396
+ log.dim('Nenhum canal disponível para fechar (o canal Global nunca pode ser fechado).');
397
+ return;
398
+ }
399
+ const choices = [
400
+ ...closeable.map((ch) => ({
401
+ name: `${chalk.bold(ch.name)} ${channelTypeLabel(ch.type)} ${chalk.dim(ch.id)}`,
402
+ value: ch.id,
403
+ short: ch.name,
404
+ })),
405
+ { name: chalk.dim('Cancelar'), value: '__cancel__', short: 'Cancelar' },
406
+ ];
407
+ const { channelId } = await inquirer.prompt([
408
+ {
409
+ type: 'list',
410
+ name: 'channelId',
411
+ message: 'Qual canal fechar?',
412
+ choices,
413
+ },
414
+ ]);
415
+ if (channelId === '__cancel__')
416
+ return;
417
+ const { confirm } = await inquirer.prompt([
418
+ {
419
+ type: 'confirm',
420
+ name: 'confirm',
421
+ message: `Confirma fechar o canal "${closeable.find((c) => c.id === channelId)?.name ?? channelId}"?`,
422
+ default: false,
423
+ },
424
+ ]);
425
+ if (!confirm) {
426
+ log.dim('Operação cancelada.');
427
+ return;
428
+ }
429
+ const spinner = ora({ text: 'Fechando canal…', color: 'blue' }).start();
430
+ try {
431
+ await closeChannel(token, channelId);
432
+ spinner.stop();
433
+ log.success('Canal fechado.');
434
+ }
435
+ catch (error) {
436
+ spinner.fail('Falha ao fechar canal.');
437
+ if (error instanceof Error)
438
+ console.error(chalk.red(` ${error.message}`));
439
+ }
440
+ }
441
+ // ─── Entrada principal do submenu de chat ─────────────────────────────────────
442
+ /**
443
+ * Submenu raiz de Chat. Chamado por `runTerminalUi` em `ui.ts`.
444
+ *
445
+ * Usa o `promptSubMenu` de `ui.ts` indiretamente por reimplementação local
446
+ * que delega ao `inquirer` list (mode não-raw) — compatível com o ciclo de
447
+ * vida do menu principal, que passa o controle com stdin "quente".
448
+ *
449
+ * O loop `for (;;)` mantém o submenu ativo até o usuário escolher "Voltar".
450
+ */
451
+ export async function runChatMenu() {
452
+ const token = await resolveToken();
453
+ if (!token) {
454
+ log.error('Sessão não encontrada. Faça login com `neetru login`.');
455
+ return;
456
+ }
457
+ for (;;) {
458
+ // Carrega canais pra ter a lista disponível nas ações que precisam
459
+ let channels = [];
460
+ try {
461
+ const spinner = ora({ text: 'Carregando canais…', color: 'blue' }).start();
462
+ channels = await fetchChannels(token);
463
+ spinner.stop();
464
+ }
465
+ catch {
466
+ // Continua mesmo sem lista — algumas ações ainda funcionam
467
+ }
468
+ // Resumo rápido no topo do submenu
469
+ console.log();
470
+ if (channels.length > 0) {
471
+ const globalCh = channels.find((c) => c.id === 'global');
472
+ console.log(chalk.bold('Chat — canais abertos: ') +
473
+ chalk.cyan(String(channels.length)) +
474
+ (globalCh ? chalk.dim(' (global disponível)') : ''));
475
+ }
476
+ else {
477
+ console.log(chalk.bold('Chat'));
478
+ }
479
+ console.log();
480
+ const { action } = await inquirer.prompt([
481
+ {
482
+ type: 'list',
483
+ name: 'action',
484
+ message: 'Chat — o que deseja fazer?',
485
+ choices: [
486
+ {
487
+ name: `${chalk.bold('Listar canais')} ${chalk.dim('— ver lista e entrar num canal')}`,
488
+ value: 'list',
489
+ short: 'Listar canais',
490
+ },
491
+ {
492
+ name: `${chalk.bold('Entrar em canal')} ${chalk.dim('— digitar id ou escolher')}`,
493
+ value: 'enter',
494
+ short: 'Entrar em canal',
495
+ },
496
+ {
497
+ name: `${chalk.bold('Abrir canal novo')} ${chalk.dim('— criar canal de produto ou geral')}`,
498
+ value: 'new',
499
+ short: 'Abrir canal novo',
500
+ },
501
+ {
502
+ name: `${chalk.bold('Fechar canal')} ${chalk.dim('— marcar canal como encerrado')}`,
503
+ value: 'close',
504
+ short: 'Fechar canal',
505
+ },
506
+ {
507
+ name: chalk.dim('Voltar'),
508
+ value: 'back',
509
+ short: 'Voltar',
510
+ },
511
+ ],
512
+ },
513
+ ]);
514
+ if (action === 'back')
515
+ return;
516
+ if (action === 'list') {
517
+ if (channels.length === 0) {
518
+ log.dim('Nenhum canal aberto. Use "Abrir canal novo" pra criar um.');
519
+ continue;
520
+ }
521
+ const selected = await promptSelectChannel(token, channels);
522
+ if (selected) {
523
+ await runChannelLoop(token, selected);
524
+ }
525
+ continue;
526
+ }
527
+ if (action === 'enter') {
528
+ if (channels.length > 0) {
529
+ // Oferece seleção visual quando há canais disponíveis
530
+ const selected = await promptSelectChannel(token, channels);
531
+ if (selected) {
532
+ await runChannelLoop(token, selected);
533
+ }
534
+ }
535
+ else {
536
+ // Sem canais: pede o id manualmente
537
+ const { channelId } = await inquirer.prompt([
538
+ {
539
+ type: 'input',
540
+ name: 'channelId',
541
+ message: 'ID do canal (ex: global):',
542
+ validate: (v) => v.trim().length > 0 || 'Obrigatório.',
543
+ },
544
+ ]);
545
+ const id = channelId.trim();
546
+ // Canal sintético com mínimo de info pra entrar no loop
547
+ const synthetic = { id, name: id, type: 'custom' };
548
+ await runChannelLoop(token, synthetic);
549
+ }
550
+ continue;
551
+ }
552
+ if (action === 'new') {
553
+ await promptCreateChannel(token);
554
+ // Depois de criar, volta ao loop pra atualizar a lista
555
+ continue;
556
+ }
557
+ if (action === 'close') {
558
+ await promptCloseChannel(token, channels);
559
+ continue;
560
+ }
561
+ }
562
+ }
563
+ //# sourceMappingURL=chat-menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-menu.js","sourceRoot":"","sources":["../../src/commands/chat-menu.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,41 @@
1
1
  import type { Command } from 'commander';
2
2
  type ActorType = 'agent_claude' | 'human' | 'cli';
3
+ export interface ChatChannelsOptions {
4
+ json?: boolean;
5
+ }
6
+ /**
7
+ * Lista os canais de chat abertos.
8
+ *
9
+ * integrationNeeded — registrar em `registerChatCommand`:
10
+ * ```ts
11
+ * chatCmd.command('channels').action(async (opts) => runChatChannels(opts));
12
+ * ```
13
+ */
14
+ export declare function runChatChannels(opts: ChatChannelsOptions): Promise<void>;
3
15
  export interface ChatSendOptions {
4
- product: string;
16
+ /** Canal de destino (novo — tem precedência sobre product). */
17
+ channel?: string;
18
+ /** Produto legado (mantido por retrocompat; ignorado quando channel está presente). */
19
+ product?: string;
5
20
  actorType?: ActorType;
6
21
  productId?: string;
7
22
  json?: boolean;
8
23
  }
9
24
  export declare function runChatSend(message: string, opts: ChatSendOptions): Promise<void>;
10
25
  export interface ChatHistoryOptions {
11
- product: string;
26
+ /** Canal de destino (novo — tem precedência sobre product). */
27
+ channel?: string;
28
+ /** Produto legado (mantido por retrocompat). */
29
+ product?: string;
12
30
  hours?: string;
13
31
  json?: boolean;
14
32
  }
15
33
  export declare function runChatHistory(opts: ChatHistoryOptions): Promise<void>;
16
34
  export interface ChatLoopOptions {
17
- product: string;
35
+ /** Canal de destino (novo — tem precedência sobre product). */
36
+ channel?: string;
37
+ /** Produto legado (retrocompat). */
38
+ product?: string;
18
39
  actorType?: ActorType;
19
40
  json?: boolean;
20
41
  }
@@ -22,6 +43,15 @@ export declare function runChatLoop(opts: ChatLoopOptions): Promise<void>;
22
43
  /**
23
44
  * Registra o comando `neetru chat` no programa Commander.
24
45
  *
46
+ * Subcomandos:
47
+ * neetru chat channels → lista canais abertos
48
+ * neetru chat send --channel <id> "msg" → envia mensagem num canal
49
+ * neetru chat send --product <slug> "msg" → legado (por produto)
50
+ * neetru chat history --channel <id> → histórico de canal
51
+ * neetru chat history --product <slug> → histórico legado
52
+ * neetru chat --channel <id> → loop interativo de canal
53
+ * neetru chat --product <slug> → loop interativo legado
54
+ *
25
55
  * integrationNeeded — adicionar em src/index.ts (ou onde os subcomandos
26
56
  * são registrados):
27
57
  * ```ts