hobots 1.5.1 → 1.7.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.
@@ -1,7 +1,76 @@
1
- export { ManagerAgentInfo, ManagerPollRequest, ManagerPollResponse, ManagerRunDescriptor, ManagerRunError, ManagerRunStatus, ManagerRunUpdateRequest, ManagerRunUpdateResponse, ManagerRunUpdateStatus, RunLogEntry, RunLogLevel } from './manager/protocol.cjs';
1
+ /**
2
+ * Tipos do protocolo de tasks do Hobots (agente SDK ↔ servidor).
3
+ *
4
+ * Este arquivo é a fonte de verdade do wire format e não pode importar nada:
5
+ * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
6
+ * contra estes tipos (reexportados por `hobots/protocol`).
7
+ */
8
+ /** Ciclo de vida completo de uma run no servidor. */
9
+ type RunStatus = 'pending' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'canceled';
10
+ /** Subconjunto que o agente pode enviar no PATCH. */
11
+ type RunUpdateStatus = 'running' | 'succeeded' | 'failed';
12
+ type RunLogLevel = 'debug' | 'info' | 'warning' | 'error' | 'success';
13
+ interface RunLogEntry {
14
+ /** ISO 8601 — relógio do agente, apenas para exibição */
15
+ ts: string;
16
+ level: RunLogLevel;
17
+ message: string;
18
+ }
19
+ interface AgentInfo {
20
+ /** Identidade canônica do agente — correlaciona com o heartbeat de telemetria */
21
+ instance_id: string;
22
+ name?: string;
23
+ /** Versão do SDK */
24
+ version?: string;
25
+ /** Hostname da máquina */
26
+ host?: string;
27
+ /** Tasks registradas no agente */
28
+ tasks?: string[];
29
+ }
30
+ /** POST /v1/tasks/poll */
31
+ interface PollRequest {
32
+ agent?: AgentInfo;
33
+ /** Quantas runs reivindicar de uma vez (1..5). Default: 1 */
34
+ max?: number;
35
+ /** Só entrega runs destas tasks (nomes registrados no agente) */
36
+ tasks?: string[];
37
+ }
38
+ interface RunDescriptor {
39
+ id: string;
40
+ task: string;
41
+ params: Record<string, unknown>;
42
+ form: {
43
+ id: string;
44
+ name: string;
45
+ } | null;
46
+ /** Origem da run: 'hobots' | 'link' | 'schedule' (informativo) */
47
+ source: string;
48
+ /** ISO 8601 (relógio do servidor) */
49
+ created_at: string;
50
+ }
51
+ interface PollResponse {
52
+ runs: RunDescriptor[];
53
+ }
54
+ interface RunError {
55
+ /** ex.: nome da classe do erro */
56
+ type?: string;
57
+ message: string;
58
+ stack?: string;
59
+ }
60
+ /** PATCH /v1/tasks/runs/{id} — 'running' pode repetir com logs incrementais */
61
+ interface RunUpdateRequest {
62
+ status: RunUpdateStatus;
63
+ /** Apenas com status 'failed' */
64
+ error?: RunError;
65
+ /** Delta desde o último envio — o servidor concatena */
66
+ logs?: RunLogEntry[];
67
+ }
68
+ interface RunUpdateResponse {
69
+ ok: true;
70
+ }
2
71
 
3
72
  /**
4
- * Tipos do protocolo de ingestão do Hobots Monitor (SDK → servidor).
73
+ * Tipos do protocolo do Hobots (SDK → servidor).
5
74
  *
6
75
  * Este arquivo é a fonte de verdade do wire format e só pode reexportar tipos:
7
76
  * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
@@ -82,7 +151,7 @@ interface TransactionPayload {
82
151
  tags?: Record<string, string>;
83
152
  release?: string;
84
153
  environment?: string;
85
- /** Correlaciona esta transaction a uma execução do Manager (ctx.tx dentro de um task handler) */
154
+ /** Correlaciona esta transaction a uma execução de task (ctx.tx dentro de um task handler) */
86
155
  run_id?: string;
87
156
  }
88
157
  type CheckInStatus = 'in_progress' | 'ok' | 'error';
@@ -130,4 +199,4 @@ interface Envelope {
130
199
  items: EnvelopeItem[];
131
200
  }
132
201
 
133
- export type { Breadcrumb, CheckInPayload, CheckInStatus, Envelope, EnvelopeItem, EventPayload, EventUser, ExceptionData, HeartbeatPayload, Severity, SpanData, SpanStatus, StackFrame, TransactionPayload };
202
+ export type { AgentInfo, Breadcrumb, CheckInPayload, CheckInStatus, Envelope, EnvelopeItem, EventPayload, EventUser, ExceptionData, HeartbeatPayload, PollRequest, PollResponse, RunDescriptor, RunError, RunLogEntry, RunLogLevel, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, Severity, SpanData, SpanStatus, StackFrame, TransactionPayload };
@@ -1,7 +1,76 @@
1
- export { ManagerAgentInfo, ManagerPollRequest, ManagerPollResponse, ManagerRunDescriptor, ManagerRunError, ManagerRunStatus, ManagerRunUpdateRequest, ManagerRunUpdateResponse, ManagerRunUpdateStatus, RunLogEntry, RunLogLevel } from './manager/protocol.js';
1
+ /**
2
+ * Tipos do protocolo de tasks do Hobots (agente SDK ↔ servidor).
3
+ *
4
+ * Este arquivo é a fonte de verdade do wire format e não pode importar nada:
5
+ * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
6
+ * contra estes tipos (reexportados por `hobots/protocol`).
7
+ */
8
+ /** Ciclo de vida completo de uma run no servidor. */
9
+ type RunStatus = 'pending' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'canceled';
10
+ /** Subconjunto que o agente pode enviar no PATCH. */
11
+ type RunUpdateStatus = 'running' | 'succeeded' | 'failed';
12
+ type RunLogLevel = 'debug' | 'info' | 'warning' | 'error' | 'success';
13
+ interface RunLogEntry {
14
+ /** ISO 8601 — relógio do agente, apenas para exibição */
15
+ ts: string;
16
+ level: RunLogLevel;
17
+ message: string;
18
+ }
19
+ interface AgentInfo {
20
+ /** Identidade canônica do agente — correlaciona com o heartbeat de telemetria */
21
+ instance_id: string;
22
+ name?: string;
23
+ /** Versão do SDK */
24
+ version?: string;
25
+ /** Hostname da máquina */
26
+ host?: string;
27
+ /** Tasks registradas no agente */
28
+ tasks?: string[];
29
+ }
30
+ /** POST /v1/tasks/poll */
31
+ interface PollRequest {
32
+ agent?: AgentInfo;
33
+ /** Quantas runs reivindicar de uma vez (1..5). Default: 1 */
34
+ max?: number;
35
+ /** Só entrega runs destas tasks (nomes registrados no agente) */
36
+ tasks?: string[];
37
+ }
38
+ interface RunDescriptor {
39
+ id: string;
40
+ task: string;
41
+ params: Record<string, unknown>;
42
+ form: {
43
+ id: string;
44
+ name: string;
45
+ } | null;
46
+ /** Origem da run: 'hobots' | 'link' | 'schedule' (informativo) */
47
+ source: string;
48
+ /** ISO 8601 (relógio do servidor) */
49
+ created_at: string;
50
+ }
51
+ interface PollResponse {
52
+ runs: RunDescriptor[];
53
+ }
54
+ interface RunError {
55
+ /** ex.: nome da classe do erro */
56
+ type?: string;
57
+ message: string;
58
+ stack?: string;
59
+ }
60
+ /** PATCH /v1/tasks/runs/{id} — 'running' pode repetir com logs incrementais */
61
+ interface RunUpdateRequest {
62
+ status: RunUpdateStatus;
63
+ /** Apenas com status 'failed' */
64
+ error?: RunError;
65
+ /** Delta desde o último envio — o servidor concatena */
66
+ logs?: RunLogEntry[];
67
+ }
68
+ interface RunUpdateResponse {
69
+ ok: true;
70
+ }
2
71
 
3
72
  /**
4
- * Tipos do protocolo de ingestão do Hobots Monitor (SDK → servidor).
73
+ * Tipos do protocolo do Hobots (SDK → servidor).
5
74
  *
6
75
  * Este arquivo é a fonte de verdade do wire format e só pode reexportar tipos:
7
76
  * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
@@ -82,7 +151,7 @@ interface TransactionPayload {
82
151
  tags?: Record<string, string>;
83
152
  release?: string;
84
153
  environment?: string;
85
- /** Correlaciona esta transaction a uma execução do Manager (ctx.tx dentro de um task handler) */
154
+ /** Correlaciona esta transaction a uma execução de task (ctx.tx dentro de um task handler) */
86
155
  run_id?: string;
87
156
  }
88
157
  type CheckInStatus = 'in_progress' | 'ok' | 'error';
@@ -130,4 +199,4 @@ interface Envelope {
130
199
  items: EnvelopeItem[];
131
200
  }
132
201
 
133
- export type { Breadcrumb, CheckInPayload, CheckInStatus, Envelope, EnvelopeItem, EventPayload, EventUser, ExceptionData, HeartbeatPayload, Severity, SpanData, SpanStatus, StackFrame, TransactionPayload };
202
+ export type { AgentInfo, Breadcrumb, CheckInPayload, CheckInStatus, Envelope, EnvelopeItem, EventPayload, EventUser, ExceptionData, HeartbeatPayload, PollRequest, PollResponse, RunDescriptor, RunError, RunLogEntry, RunLogLevel, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, Severity, SpanData, SpanStatus, StackFrame, TransactionPayload };
package/docs/README.md CHANGED
@@ -1,22 +1,22 @@
1
1
  # Documentação — hobots
2
2
 
3
- SDK JavaScript da **Hobots** para instrumentar funcionários digitais (RPAs) e integrações. Cliente HTTP puro, sem dependências de runtime, para Node 18+ (o Monitor também roda no browser para captura de erros).
3
+ SDK JavaScript da **Hobots** para instrumentar funcionários digitais (RPAs) e integrações. Cliente HTTP puro, sem dependências de runtime, para Node 18+ (a telemetria também roda no browser para captura de erros).
4
4
 
5
5
  O SDK expõe **duas capabilities** autenticadas pelo **mesmo Client Secret do projeto**, configuradas em **um único `init()`** com **um único import** (`import * as Hobots from 'hobots'`):
6
6
 
7
7
  | Capability | Como habilita | Para quê |
8
8
  | --- | --- | --- |
9
- | **Monitor** | sempre ativo no `init()` | Telemetria que o programa **emite** sozinho: erros com stack trace, performance (transactions/spans), check-ins de cron e heartbeats de uptime. Instala handlers globais de erro; os timers são `unref`'d, então nunca seguram o processo vivo. |
10
- | **Manager** | `manager: true` (ou opções) no `init()` | Execução **sob demanda**: o agente faz polling no app, executa handlers registrados e reporta status/logs. `start()` **mantém o processo vivo** até `stop()`/`close()`. |
9
+ | **Telemetria** | sempre ativa no `init()` | O que o programa **emite** sozinho: erros com stack trace (módulo **Issues**), performance (transactions/spans) e heartbeats de uptime (módulo **Agentes**), check-ins de cron (módulo **Monitores**). Instala handlers globais de erro; os timers são `unref`'d, então nunca seguram o processo vivo. |
10
+ | **Tasks** | `tasks: true` (ou opções) no `init()` | Execução **sob demanda**: o agente faz polling no app, executa handlers registrados e reporta status/logs — o módulo **Solicitações**. `start()` **mantém o processo vivo** até `stop()`/`close()`. |
11
11
 
12
12
  ## Páginas
13
13
 
14
14
  Se termos como transaction, span, breadcrumb, tag, context, extra, flush e close ainda não são familiares, comece por **Conceitos** — as outras páginas assumem esse vocabulário.
15
15
 
16
16
  - [Conceitos](./concepts.md) — o vocabulário: o que cada coisa é, por que existe e quando escolher uma em vez da outra.
17
- - [Getting started](./getting-started.md) — instalação, Client Secret, o `init` único, Monitor e Manager.
18
- - [Monitor](./monitor.md) — erros, breadcrumbs, escopo, transactions/spans, crons e heartbeat.
19
- - [Manager](./manager.md) — registro de handlers, `RunContext`, cancelamento, concorrência, idempotência.
17
+ - [Getting started](./getting-started.md) — instalação, Client Secret, o `init` único, telemetria e tasks.
18
+ - [Telemetria](./monitor.md) — erros, breadcrumbs, escopo, transactions/spans, crons e heartbeat.
19
+ - [Tasks](./tasks.md) — registro de handlers, `RunContext`, cancelamento, concorrência, idempotência.
20
20
  - [Referência de API](./api-reference.md) — todas as funções e tabelas de opções com defaults.
21
21
  - [Protocolo & transporte](./protocol.md) — o Client Secret, endpoints, envelope, retries e onde vive o claim atômico.
22
22
 
@@ -28,13 +28,13 @@ import * as Hobots from 'hobots';
28
28
  // O Client Secret do projeto — copie em Configurações → Projetos no app
29
29
  const clientSecret = 'hb_<64 hex>';
30
30
 
31
- // Um init só: telemetria sempre ativa; manager habilita a execução sob demanda.
31
+ // Um init só: telemetria sempre ativa; tasks habilita a execução sob demanda.
32
32
  // O instanceId é a identidade única — o robô aparece como um agente só no painel.
33
33
  Hobots.init({
34
34
  clientSecret,
35
35
  instanceId: 'vm-cliente-01',
36
36
  heartbeat: true,
37
- manager: true,
37
+ tasks: true,
38
38
  });
39
39
 
40
40
  Hobots.register('processar-nfe', async (params, ctx) => {
@@ -4,14 +4,12 @@
4
4
 
5
5
  | Import | Conteúdo |
6
6
  | --- | --- |
7
- | `hobots` | Tudo: `init` único, funções do Monitor, `register`/`start`/`stop` do Manager, `close`, classes (`Client`, `Scope`, `Transaction`, `Span`, `ManagerAgent`, `ManagerApi`), `resolveConfig`, `DEFAULT_BASE_URL` e tipos. |
8
- | `hobots/protocol` | Tipos do wire format (Monitor e Manager). |
9
-
10
- `hobots/manager/protocol` segue existindo como alias transitório dos tipos do wire format do Manager.
7
+ | `hobots` | Tudo: `init` único, funções de telemetria, `register`/`start`/`stop` de tasks, `close`, classes (`Client`, `Scope`, `Transaction`, `Span`), `DEFAULT_BASE_URL`, `scrubSecrets` e tipos. |
8
+ | `hobots/protocol` | Tipos do wire format (telemetria e tasks). |
11
9
 
12
10
  ---
13
11
 
14
- ## Monitor — funções
12
+ ## Telemetria — funções
15
13
 
16
14
  | Função | Assinatura | Retorno |
17
15
  | --- | --- | --- |
@@ -25,18 +23,18 @@
25
23
  | `setContext` | `setContext(name: string, ctx: Record<string,unknown> \| null): void` | — |
26
24
  | `setExtra` | `setExtra(key: string, value: unknown): void` | — |
27
25
  | `withScope` | `withScope<T>(cb: (scope: Scope) => T): T` | retorno do callback |
28
- | `startTransaction` | `startTransaction(name: string, op?: string): Transaction` | transaction |
26
+ | `startTransaction` | `startTransaction(name: string, op?: string): Transaction` | transaction (dentro de um handler de task, a própria `ctx.tx`) |
29
27
  | `checkIn` | `checkIn(options: CheckInOptions): string \| undefined` | check_in_id |
30
28
  | `withMonitor` | `withMonitor<T>(slug: string, fn: () => T \| Promise<T>, options?: WithMonitorOptions): Promise<T>` | retorno de `fn` |
31
29
  | `flush` | `flush(timeoutMs = 5_000): Promise<boolean>` | enviou tudo dentro do prazo? |
32
- | `close` | `close(timeoutMs = 5_000): Promise<boolean>` | para o Manager (aguarda runs) + heartbeat + flush final do transport |
30
+ | `close` | `close(timeoutMs = 5_000): Promise<boolean>` | para o polling de tasks (aguarda runs) + heartbeat + flush final do transport |
33
31
 
34
32
  ### O que cada função faz
35
33
 
36
34
  Os conceitos por trás dessas chamadas estão em [Conceitos](./concepts.md); aqui está o que cada uma **faz** e o que **devolve**.
37
35
 
38
- - **`init(options)`** — cria o cliente, instala os handlers globais de erro (a menos que `captureUnhandled: false`), inicia o heartbeat se configurado e cria o agente do Manager se `manager` foi passado. Chamar de novo **substitui** o cliente e o agente (os handlers registrados com `register` são preservados; o [scope](./concepts.md#scope) **não** é limpo). Chame uma vez, o mais cedo possível.
39
- - **`getClient()`** — devolve o cliente atual ou `undefined` se o `init()` nunca rodou. Útil para checar se o SDK está ativo.
36
+ - **`init(options)`** — cria o cliente, instala os handlers globais de erro (a menos que `captureUnhandled: false`), inicia o heartbeat se configurado e cria o agente de tasks se `tasks` foi passado. Chamar de novo **substitui** o cliente e o agente (os handlers registrados com `register` são preservados; o [scope](./concepts.md#scope) **não** é limpo). Chame uma vez, o mais cedo possível.
37
+ - **`getClient()`** — devolve o cliente atual ou `undefined` se o `init()` nunca rodou. Útil para checar se o SDK está ativo. A config resolvida (URL base e endpoints) é acessível via `getClient()?.config` (veja abaixo).
40
38
  - **`captureException(error, hint?)`** — monta um [evento](./concepts.md#evento) a partir da exceção (tipo, mensagem, stack trace), mescla o scope e enfileira. O `level` é `error` a menos que você passe outro no `hint`.
41
39
  - **`captureMessage(message, level = 'info', hint?)`** — mesma coisa, sem exceção: um evento só com texto. Bom para marcos (`'success'`) e avisos que não são erro.
42
40
  > **Atenção:** as duas devolvem um `event_id` **mesmo quando o evento foi descartado** por [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate) ou por [`beforeSend`](./concepts.md#beforesend). O retorno não prova que algo foi enviado — só é `undefined` quando o `init()` não foi chamado.
@@ -46,21 +44,21 @@ Os conceitos por trás dessas chamadas estão em [Conceitos](./concepts.md); aqu
46
44
  - **`setContext(name, ctx | null)`** — define um [context](./concepts.md#context) nomeado. Passar `null` **apaga o grupo inteiro**. Os grupos `runtime` e `os` são injetados pelo SDK em todo evento.
47
45
  - **`setExtra(key, value)`** — anexa um dado livre, sem estrutura e sem índice. Conceito e critério de escolha em [Extra](./concepts.md#extra).
48
46
  - **`withScope(cb)`** — roda o callback com um **clone** do scope e restaura o original no fim; devolve o que o callback devolver. É **síncrono** — um `await` dentro do callback não isola de código concorrente. Conceito: [withScope](./concepts.md#withscope).
49
- - **`startTransaction(name, op?)`** — abre uma [transaction](./concepts.md#transaction) de performance. A decisão de [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate) acontece **aqui**, não no `finish()`. Nada é enviado até o `finish()`. Dentro de um handler do Manager, use [`ctx.tx`](./concepts.md#transaction-de-run-ctxtx) em vez desta.
47
+ - **`startTransaction(name, op?)`** — abre uma [transaction](./concepts.md#transaction) de performance. A decisão de [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate) acontece **aqui**, não no `finish()`. Nada é enviado até o `finish()`. **Dentro de um handler de task**, devolve a [transaction da própria run](./concepts.md#transaction-de-run-ctxtx) (`ctx.tx`) em vez de criar uma segunda — cada execução tem exatamente uma transaction; fora de um handler, cria uma transaction nova, sem `run_id`.
50
48
  - **`checkIn(options)`** — envia um [check-in](./concepts.md#check-in) avulso e devolve o `check_in_id`. Reaproveite o id do `in_progress` para fechar a execução com `ok`/`error`.
51
49
  - **`withMonitor(slug, fn, options?)`** — envolve `fn` no par de check-ins (`in_progress` → `ok`/`error`) medindo a duração, e devolve o que `fn` devolver. Em caso de erro, fecha como `error`, captura o evento com a tag `monitor: <slug>` e **relança** a exceção. Passe `schedule` para o servidor criar/atualizar o monitor sozinho e detectar execução perdida.
52
50
  - **`flush(timeoutMs = 5_000)`** → `Promise<boolean>` — empurra a fila do transport e aguarda os envios em andamento. `true` = tudo saiu no prazo; `false` = o SDK parou de esperar (os envios em voo seguem tentando). O SDK **continua utilizável** depois. Conceito: [Fila, flush e close](./concepts.md#fila-flush-e-close).
53
51
  - **`close(timeoutMs = 5_000)`** → `Promise<boolean>` — encerra tudo na ordem agente → heartbeat → flush final. O `timeoutMs` é gasto **duas vezes** (espera das runs, depois flush). Depois do `close()` o transport está fechado e todo item novo é descartado com aviso no console; não há `reopen()`. Conceito: [Fila, flush e close](./concepts.md#fila-flush-e-close).
54
52
 
55
- Classes exportadas: `Client`, `Scope`, `Transaction`, `Span`. Função `resolveConfig({ clientSecret }): ResolvedConfig` — resolve a credencial nos endpoints (constante `DEFAULT_BASE_URL = 'https://api2.hobots.app'`, em `src/config.ts`; em desenvolvimento a env `HOBOTS_API_URL` sobrescreve a URL base):
53
+ Classes exportadas: `Client`, `Scope`, `Transaction`, `Span`. A resolução da credencial nos endpoints é interna ao `init()` (constante `DEFAULT_BASE_URL = 'https://api2.hobots.app'`, exportada; em desenvolvimento a env `HOBOTS_API_URL` sobrescreve a URL base). A config resolvida fica acessível em `getClient()?.config`:
56
54
 
57
55
  ```ts
58
- interface ResolvedConfig {
59
- key: string; // Client Secret do projeto (vai no Authorization: Bearer, nunca na URL)
60
- baseUrl: string; // DEFAULT_BASE_URL, ou HOBOTS_API_URL em desenvolvimento
61
- ingestEndpoint: string; // <baseUrl>/v1/ingest
62
- managerBaseUrl: string; // <baseUrl>/v1/manager
63
- }
56
+ getClient()?.config; // {
57
+ // key: string; — Client Secret do projeto (vai no Authorization: Bearer, nunca na URL)
58
+ // baseUrl: string; — DEFAULT_BASE_URL, ou HOBOTS_API_URL em desenvolvimento
59
+ // ingestEndpoint: string; — <baseUrl>/v1/ingest
60
+ // tasksBaseUrl: string; — <baseUrl>/v1/tasks
61
+ // }
64
62
  ```
65
63
 
66
64
  ### Métodos de `Transaction` / `Span` / `Scope`
@@ -74,25 +72,23 @@ Todos encadeáveis, exceto `finish()` e `toJSON()`.
74
72
 
75
73
  ---
76
74
 
77
- ## Manager — funções
75
+ ## Tasks — funções
78
76
 
79
- Habilitado com `manager: true` (ou `ManagerOptions`) no `init()` único. Todas exportadas do import raiz `hobots`:
77
+ Habilitadas com `tasks: true` (ou `TasksOptions`) no `init()` único. Todas exportadas do import raiz `hobots`:
80
78
 
81
79
  | Função | Assinatura |
82
80
  | --- | --- |
83
- | `register` | `register<P>(task: string, handler: ManagerTaskHandler<P>): void` |
84
- | `start` | `start(): void` — lança se o `init()` não configurou `manager` ou sem tasks registradas |
85
- | `stop` | `stop(timeoutMs = 30_000): Promise<boolean>` — para só o Manager; a telemetria continua |
81
+ | `register` | `register<P>(task: string, handler: TaskHandler<P>): void` |
82
+ | `start` | `start(): void` — lança se o `init()` não configurou `tasks` ou sem tasks registradas |
83
+ | `stop` | `stop(timeoutMs = 30_000): Promise<boolean>` — para só o polling de tasks; a telemetria continua |
86
84
 
87
85
  ### O que cada função faz
88
86
 
89
- - **`register(task, handler)`** — associa um handler ao `task_slug` configurado no formulário do app. Registre **antes** de `start()`; pode ser chamado antes do `init()`. Registrar o mesmo `task` duas vezes **sobrescreve** o handler (com aviso no console). Se o `init()` não habilitou o Manager, o SDK avisa e não faz nada. Tipagem dos params: `register<{ lote: number }>(…)`.
90
- - **`start()`** — começa o polling. **Mantém o processo vivo** até `stop()`/`close()` — o timer não é `unref`'d, ao contrário dos do Monitor. Lança se o `init()` não configurou `manager` ou se nenhuma task foi registrada. Também instala os handlers de saída (SIGINT/SIGTERM/erro fatal) que reportam as runs ativas como `AgentTerminated`, a menos que `installExitHandlers: false`.
91
- - **`stop(timeoutMs = 30_000)`** → `Promise<boolean>` — encerra o polling e aguarda as [runs](./concepts.md#run) ativas terminarem. Para **só o Manager**: a telemetria (heartbeat, captura de erros) continua funcionando. Devolve `false` se estourou o timeout — as runs que ainda estavam rodando são reportadas como `AgentTerminated`. Para encerrar tudo, use [`close()`](./concepts.md#fila-flush-e-close).
92
-
93
- Classes/erros exportados: `ManagerAgent`, `ManagerApi`, `ManagerApiError`.
87
+ - **`register(task, handler)`** — associa um handler ao `task_slug` configurado no formulário do app (**Configurações → Formulários**). Registre **antes** de `start()`; pode ser chamado antes do `init()`. Registrar o mesmo `task` duas vezes **sobrescreve** o handler (com aviso no console). Se o `init()` não habilitou as tasks, o SDK avisa e não faz nada. Tipagem dos params: `register<{ lote: number }>(…)`.
88
+ - **`start()`** — começa o polling. **Mantém o processo vivo** até `stop()`/`close()` — o timer não é `unref`'d, ao contrário dos da telemetria. Lança se o `init()` não configurou `tasks` ou se nenhuma task foi registrada. Também instala os handlers de saída (SIGINT/SIGTERM/erro fatal) que reportam as runs ativas como `AgentTerminated`, a menos que `installExitHandlers: false`.
89
+ - **`stop(timeoutMs = 30_000)`** → `Promise<boolean>` — encerra o polling e aguarda as [runs](./concepts.md#run) ativas terminarem. Para **só as tasks**: a telemetria (heartbeat, captura de erros) continua funcionando. Devolve `false` se estourou o timeout — as runs que ainda estavam rodando são reportadas como `AgentTerminated`. Para encerrar tudo, use [`close()`](./concepts.md#fila-flush-e-close).
94
90
 
95
- No poll, o agente se identifica com `ManagerAgentInfo` (`hobots/protocol`): o campo `instance_id` (o `instanceId` do `init()`) é a identidade canônica do agente — a mesma do heartbeat do Monitor, então os dois canais convergem em um agente no painel.
91
+ No poll, o agente se identifica com `AgentInfo` (`hobots/protocol`): o campo `instance_id` (o `instanceId` do `init()`) é a identidade canônica do agente — a mesma do heartbeat de telemetria, então os dois canais convergem em um agente no painel.
96
92
 
97
93
  ---
98
94
 
@@ -105,14 +101,14 @@ No poll, o agente se identifica com `ManagerAgentInfo` (`hobots/protocol`): o ca
105
101
  | `clientSecret` | `string` | — | **obrigatório**; o Client Secret do projeto (`hb_<64 hex>`), copiado em **Configurações → Projetos** |
106
102
  | `environment` | `string` | `'production'` | ambiente lógico |
107
103
  | `release` | `string` | — | versão do programa, ex. `robo-nfe@1.4.2` |
108
- | `instanceId` | `string` | **obrigatório** | identidade única da instância; heartbeat do Monitor e agente do Manager convergem nela |
104
+ | `instanceId` | `string` | **obrigatório** | identidade única da instância; heartbeat e poll de tasks convergem nela |
109
105
  | `tags` | `Record<string,string>` | — | tags aplicadas a todos os eventos |
110
106
  | `sampleRate` | `number` | `1` | amostragem de erros (0..1) |
111
107
  | `tracesSampleRate` | `number` | `1` | amostragem de transactions (0..1) |
112
108
  | `maxBreadcrumbs` | `number` | `100` | tamanho do buffer de breadcrumbs |
113
109
  | `captureUnhandled` | `boolean` | `true` | handlers globais de erro |
114
110
  | `heartbeat` | `boolean \| HeartbeatOptions` | `false` | heartbeat periódico |
115
- | `manager` | `boolean \| ManagerOptions` | `false` | habilita o agente Manager (`true` usa defaults) |
111
+ | `tasks` | `boolean \| TasksOptions` | `false` | habilita a execução sob demanda (`true` usa defaults) |
116
112
  | `beforeSend` | `(event) => event \| null` | — | edita/descarta evento (retorne `null` para descartar) |
117
113
  | `debug` | `boolean` | `false` | loga atividade do SDK |
118
114
  | `flushIntervalMs` | `number` | `2000` | intervalo do flush automático do transport |
@@ -157,9 +153,9 @@ O teto da fila do transport (200 itens; ao encher, o **mais antigo** é descarta
157
153
  | `schedule` | `string` | expressão cron (upsert do monitor) |
158
154
  | `timezone` | `string` | fuso do `schedule` |
159
155
 
160
- ### ManagerOptions
156
+ ### TasksOptions
161
157
 
162
- Valor do campo `manager` do `InitOptions`. O Client Secret, o `debug` e a identidade (`instanceId`) vêm do `init()`.
158
+ Valor do campo `tasks` do `InitOptions`. O Client Secret, o `debug` e a identidade (`instanceId`) vêm do `init()`.
163
159
 
164
160
  | Opção | Tipo | Default | Descrição |
165
161
  | --- | --- | --- | --- |
@@ -170,17 +166,17 @@ Valor do campo `manager` do `InitOptions`. O Client Secret, o `debug` e a identi
170
166
  | `cancelCheckIntervalMs` | `number` | `5000` | heartbeat de cancelamento por run (clamp 1000..15000) — também é o sinal de vida da run (servidor marca `AgentTerminated` após ~60s sem reporte) |
171
167
  | `installExitHandlers` | `boolean` | `true` | handlers de SIGINT/SIGTERM/uncaughtException que reportam as runs ativas como `AgentTerminated` antes do processo morrer; nunca interferem quando o programa tem handler próprio |
172
168
 
173
- ### ManagerTaskHandler / RunContext
169
+ ### TaskHandler / RunContext
174
170
 
175
171
  ```ts
176
172
  // o retorno do handler é ignorado — nada além de status/logs/erro é enviado ao servidor
177
- type ManagerTaskHandler<P = Record<string, unknown>> =
173
+ type TaskHandler<P = Record<string, unknown>> =
178
174
  (params: P, ctx: RunContext) => void | Promise<void>;
179
175
 
180
176
  interface RunContext {
181
177
  runId: string;
182
178
  task: string;
183
- log(level: 'debug' | 'info' | 'warning' | 'error', message: string): void;
179
+ log: RunLogger; // ctx.log.debug/info/warn/error/success(message)
184
180
  tx: Transaction; // transaction desta run — correlacionada e finalizada pelo SDK
185
181
  signal: AbortSignal;
186
182
  throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
@@ -189,8 +185,8 @@ interface RunContext {
189
185
  ```
190
186
 
191
187
  - **`runId` / `task`** — identificam a execução; úteis para correlacionar com os seus próprios logs.
192
- - **`log(level, message)`** — enfileira uma linha de log enviada ao app em PATCHes incrementais, e **também imprime no terminal local**. Conceito: [Run](./concepts.md#run).
193
- - **`tx`** — a [transaction de performance da run](./concepts.md#transaction-de-run-ctxtx). Use `ctx.tx.startChild(op, description)` para medir as etapas; **não** chame `finish()` nela nem abra uma transaction própria com `startTransaction()`.
188
+ - **`log.<level>(message)`** — níveis `debug`, `info`, `warn`, `error` e `success`; enfileira uma linha de log enviada ao app em PATCHes incrementais, e **também imprime no terminal local**. Conceito: [Run](./concepts.md#run).
189
+ - **`tx`** — a [transaction de performance da run](./concepts.md#transaction-de-run-ctxtx). Use `ctx.tx.startChild(op, description)` para medir as etapas; **não** chame `finish()` nela. `startTransaction()` dentro do handler devolve essa mesma transaction.
194
190
  - **`signal`** — `AbortSignal` que dispara em cancelamento no app, timeout ou shutdown.
195
191
  - **`throwIfCanceled()`** — o ponto de parada de uma linha: lança `RunCanceled` se o `signal` já disparou.
196
192
  - **`sleep(ms)`** — espera que respeita o `signal` (rejeita com `RunCanceled` em vez de dormir até o fim). Use no lugar do seu `sleep` em esperas longas.
@@ -201,7 +197,7 @@ interface RunContext {
201
197
 
202
198
  Todos os prazos do SDK num lugar só. A coluna **Onde configura** diz se o valor é seu ou fixo — o que está com `—` é comportamento do SDK ou do servidor e não se muda pelo `init()`.
203
199
 
204
- ### Monitor — envio de telemetria
200
+ ### Telemetria — envio
205
201
 
206
202
  | Tempo | Default | Onde configura | O que acontece |
207
203
  | --- | --- | --- | --- |
@@ -213,20 +209,20 @@ Todos os prazos do SDK num lugar só. A coluna **Onde configura** diz se o valor
213
209
  | ladder de retry | `1s, 4s, 16s` | — (fixo) | 3 tentativas por envelope; depois ele é descartado. 4xx (exceto 429) não tem retry |
214
210
  | heartbeat | `30000` ms | `init({ heartbeat: { intervalMs } })` | bate **imediatamente** no `init()` e depois a cada intervalo; o valor vai no payload e define quanto silêncio o servidor tolera antes de marcar offline |
215
211
 
216
- ### Manager — polling e runs
212
+ ### Tasks — polling e runs
217
213
 
218
214
  | Tempo | Default | Onde configura | O que acontece |
219
215
  | --- | --- | --- | --- |
220
- | poll sem trabalho | `5000` ms (mín. `1000`) | `manager: { pollIntervalMs }` | é só o **teto da espera quando não há nada**: com trabalho na fila o próximo poll é imediato ([drain mode](./concepts.md#drain-mode)) |
221
- | flush de logs da run | `2000` ms | `manager: { logFlushIntervalMs }` | ou na hora, ao acumular 20 linhas |
222
- | heartbeat de cancelamento | `5000` ms (clamp `1000`..`15000`) | `manager: { cancelCheckIntervalMs }` | detecta cancelamento feito no app **e** é o sinal de vida da run (veja a nota 2) |
223
- | timeout por run | sem timeout | `manager: { taskTimeoutMs }` | no estouro dispara `ctx.signal`, libera o slot de concorrência e reporta `TaskTimeout` — **não mata** o handler |
216
+ | poll sem trabalho | `5000` ms (mín. `1000`) | `tasks: { pollIntervalMs }` | é só o **teto da espera quando não há nada**: com trabalho na fila o próximo poll é imediato ([drain mode](./concepts.md#drain-mode)) |
217
+ | flush de logs da run | `2000` ms | `tasks: { logFlushIntervalMs }` | ou na hora, ao acumular 20 linhas |
218
+ | heartbeat de cancelamento | `5000` ms (clamp `1000`..`15000`) | `tasks: { cancelCheckIntervalMs }` | detecta cancelamento feito no app **e** é o sinal de vida da run (veja a nota 2) |
219
+ | timeout por run | sem timeout | `tasks: { taskTimeoutMs }` | no estouro dispara `ctx.signal`, libera o slot de concorrência e reporta `TaskTimeout` — **não mata** o handler |
224
220
  | `stop(timeoutMs)` | `30000` ms | argumento | espera as runs ativas; no estouro elas são reportadas como `AgentTerminated` |
225
221
  | retry do poll | `1s, 4s, 16s` | — (fixo) | erros de rede/5xx |
226
222
  | retry com chave rejeitada (401) | `30000` ms | — (fixo) | segue tentando devagar, com log throttled |
227
223
  | PATCH do caminho de saída | `~2500` ms | — (fixo) | melhor esforço, sem retry, ao morrer com run ativa |
228
224
  | sweep do servidor | `~60000` ms | — (servidor) | run `running` sem reporte por esse tempo vira `failed`/`AgentTerminated`, sem re-entrega |
229
225
 
230
- **Nota 1 — `close(timeoutMs)` gasta o tempo duas vezes.** Ele espera as runs do Manager (`timeoutMs`) e **depois** faz o flush final (`timeoutMs`), em sequência. Pior caso ≈ `2 × timeoutMs`; `close()` sem argumento pode levar até ~35s (30s aguardando runs + 5s de flush). Se o seu SIGTERM tem prazo curto (Kubernetes, systemd), dimensione por aí.
226
+ **Nota 1 — `close(timeoutMs)` gasta o tempo duas vezes.** Ele espera as runs de tasks (`timeoutMs`) e **depois** faz o flush final (`timeoutMs`), em sequência. Pior caso ≈ `2 × timeoutMs`; `close()` sem argumento pode levar até ~35s (30s aguardando runs + 5s de flush). Se o seu SIGTERM tem prazo curto (Kubernetes, systemd), dimensione por aí.
231
227
 
232
228
  **Nota 2 — o teto de 15s do `cancelCheckIntervalMs` existe por causa do sweep de 60s.** Esse heartbeat é o que mantém o `last_report_at` da run atualizado; o clamp garante que o intervalo nunca chegue perto do prazo em que o servidor declara a run morta.