hobots 1.6.0 → 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,12 +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). |
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). |
9
9
 
10
10
  ---
11
11
 
12
- ## Monitor — funções
12
+ ## Telemetria — funções
13
13
 
14
14
  | Função | Assinatura | Retorno |
15
15
  | --- | --- | --- |
@@ -23,18 +23,18 @@
23
23
  | `setContext` | `setContext(name: string, ctx: Record<string,unknown> \| null): void` | — |
24
24
  | `setExtra` | `setExtra(key: string, value: unknown): void` | — |
25
25
  | `withScope` | `withScope<T>(cb: (scope: Scope) => T): T` | retorno do callback |
26
- | `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`) |
27
27
  | `checkIn` | `checkIn(options: CheckInOptions): string \| undefined` | check_in_id |
28
28
  | `withMonitor` | `withMonitor<T>(slug: string, fn: () => T \| Promise<T>, options?: WithMonitorOptions): Promise<T>` | retorno de `fn` |
29
29
  | `flush` | `flush(timeoutMs = 5_000): Promise<boolean>` | enviou tudo dentro do prazo? |
30
- | `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 |
31
31
 
32
32
  ### O que cada função faz
33
33
 
34
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**.
35
35
 
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 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.
37
- - **`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).
38
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`.
39
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.
40
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.
@@ -44,21 +44,21 @@ Os conceitos por trás dessas chamadas estão em [Conceitos](./concepts.md); aqu
44
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.
45
45
  - **`setExtra(key, value)`** — anexa um dado livre, sem estrutura e sem índice. Conceito e critério de escolha em [Extra](./concepts.md#extra).
46
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).
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 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`.
48
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`.
49
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.
50
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).
51
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).
52
52
 
53
- 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`:
54
54
 
55
55
  ```ts
56
- interface ResolvedConfig {
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
- managerBaseUrl: string; // <baseUrl>/v1/manager
61
- }
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
+ // }
62
62
  ```
63
63
 
64
64
  ### Métodos de `Transaction` / `Span` / `Scope`
@@ -72,25 +72,23 @@ Todos encadeáveis, exceto `finish()` e `toJSON()`.
72
72
 
73
73
  ---
74
74
 
75
- ## Manager — funções
75
+ ## Tasks — funções
76
76
 
77
- 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`:
78
78
 
79
79
  | Função | Assinatura |
80
80
  | --- | --- |
81
- | `register` | `register<P>(task: string, handler: ManagerTaskHandler<P>): void` |
82
- | `start` | `start(): void` — lança se o `init()` não configurou `manager` ou sem tasks registradas |
83
- | `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 |
84
84
 
85
85
  ### O que cada função faz
86
86
 
87
- - **`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 }>(…)`.
88
- - **`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`.
89
- - **`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).
90
-
91
- 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).
92
90
 
93
- 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.
94
92
 
95
93
  ---
96
94
 
@@ -103,14 +101,14 @@ No poll, o agente se identifica com `ManagerAgentInfo` (`hobots/protocol`): o ca
103
101
  | `clientSecret` | `string` | — | **obrigatório**; o Client Secret do projeto (`hb_<64 hex>`), copiado em **Configurações → Projetos** |
104
102
  | `environment` | `string` | `'production'` | ambiente lógico |
105
103
  | `release` | `string` | — | versão do programa, ex. `robo-nfe@1.4.2` |
106
- | `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 |
107
105
  | `tags` | `Record<string,string>` | — | tags aplicadas a todos os eventos |
108
106
  | `sampleRate` | `number` | `1` | amostragem de erros (0..1) |
109
107
  | `tracesSampleRate` | `number` | `1` | amostragem de transactions (0..1) |
110
108
  | `maxBreadcrumbs` | `number` | `100` | tamanho do buffer de breadcrumbs |
111
109
  | `captureUnhandled` | `boolean` | `true` | handlers globais de erro |
112
110
  | `heartbeat` | `boolean \| HeartbeatOptions` | `false` | heartbeat periódico |
113
- | `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) |
114
112
  | `beforeSend` | `(event) => event \| null` | — | edita/descarta evento (retorne `null` para descartar) |
115
113
  | `debug` | `boolean` | `false` | loga atividade do SDK |
116
114
  | `flushIntervalMs` | `number` | `2000` | intervalo do flush automático do transport |
@@ -155,9 +153,9 @@ O teto da fila do transport (200 itens; ao encher, o **mais antigo** é descarta
155
153
  | `schedule` | `string` | expressão cron (upsert do monitor) |
156
154
  | `timezone` | `string` | fuso do `schedule` |
157
155
 
158
- ### ManagerOptions
156
+ ### TasksOptions
159
157
 
160
- 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()`.
161
159
 
162
160
  | Opção | Tipo | Default | Descrição |
163
161
  | --- | --- | --- | --- |
@@ -168,17 +166,17 @@ Valor do campo `manager` do `InitOptions`. O Client Secret, o `debug` e a identi
168
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) |
169
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 |
170
168
 
171
- ### ManagerTaskHandler / RunContext
169
+ ### TaskHandler / RunContext
172
170
 
173
171
  ```ts
174
172
  // o retorno do handler é ignorado — nada além de status/logs/erro é enviado ao servidor
175
- type ManagerTaskHandler<P = Record<string, unknown>> =
173
+ type TaskHandler<P = Record<string, unknown>> =
176
174
  (params: P, ctx: RunContext) => void | Promise<void>;
177
175
 
178
176
  interface RunContext {
179
177
  runId: string;
180
178
  task: string;
181
- log(level: 'debug' | 'info' | 'warning' | 'error', message: string): void;
179
+ log: RunLogger; // ctx.log.debug/info/warn/error/success(message)
182
180
  tx: Transaction; // transaction desta run — correlacionada e finalizada pelo SDK
183
181
  signal: AbortSignal;
184
182
  throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
@@ -187,8 +185,8 @@ interface RunContext {
187
185
  ```
188
186
 
189
187
  - **`runId` / `task`** — identificam a execução; úteis para correlacionar com os seus próprios logs.
190
- - **`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).
191
- - **`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.
192
190
  - **`signal`** — `AbortSignal` que dispara em cancelamento no app, timeout ou shutdown.
193
191
  - **`throwIfCanceled()`** — o ponto de parada de uma linha: lança `RunCanceled` se o `signal` já disparou.
194
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.
@@ -199,7 +197,7 @@ interface RunContext {
199
197
 
200
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()`.
201
199
 
202
- ### Monitor — envio de telemetria
200
+ ### Telemetria — envio
203
201
 
204
202
  | Tempo | Default | Onde configura | O que acontece |
205
203
  | --- | --- | --- | --- |
@@ -211,20 +209,20 @@ Todos os prazos do SDK num lugar só. A coluna **Onde configura** diz se o valor
211
209
  | ladder de retry | `1s, 4s, 16s` | — (fixo) | 3 tentativas por envelope; depois ele é descartado. 4xx (exceto 429) não tem retry |
212
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 |
213
211
 
214
- ### Manager — polling e runs
212
+ ### Tasks — polling e runs
215
213
 
216
214
  | Tempo | Default | Onde configura | O que acontece |
217
215
  | --- | --- | --- | --- |
218
- | 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)) |
219
- | flush de logs da run | `2000` ms | `manager: { logFlushIntervalMs }` | ou na hora, ao acumular 20 linhas |
220
- | 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) |
221
- | 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 |
222
220
  | `stop(timeoutMs)` | `30000` ms | argumento | espera as runs ativas; no estouro elas são reportadas como `AgentTerminated` |
223
221
  | retry do poll | `1s, 4s, 16s` | — (fixo) | erros de rede/5xx |
224
222
  | retry com chave rejeitada (401) | `30000` ms | — (fixo) | segue tentando devagar, com log throttled |
225
223
  | PATCH do caminho de saída | `~2500` ms | — (fixo) | melhor esforço, sem retry, ao morrer com run ativa |
226
224
  | sweep do servidor | `~60000` ms | — (servidor) | run `running` sem reporte por esse tempo vira `failed`/`AgentTerminated`, sem re-entrega |
227
225
 
228
- **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í.
229
227
 
230
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.
package/docs/concepts.md CHANGED
@@ -21,13 +21,13 @@ Os defaults numéricos **não** estão aqui — eles vivem em [Tempos e interval
21
21
  | [Breadcrumb](#breadcrumb) | Migalha da trilha que levou até o erro | Marcar cada passo relevante do robô |
22
22
  | [Transaction](#transaction) | Unidade de trabalho nomeada, com duração | Medir quanto uma rotina inteira demorou |
23
23
  | [Span](#span) | Uma etapa medida dentro da transaction | Descobrir **onde** o tempo foi gasto |
24
- | [ctx.tx](#transaction-de-run-ctxtx) | A transaction que o SDK já abriu para a run | Medir as etapas de um handler do Manager |
24
+ | [ctx.tx](#transaction-de-run-ctxtx) | A transaction que o SDK já abriu para a run | Medir as etapas de um handler de task |
25
25
  | [Amostragem](#amostragem-samplerate-e-tracessamplerate) | Enviar só uma fração do que acontece | Volume alto demais para enviar tudo |
26
26
  | [Check-in](#check-in) | Par de avisos "comecei" / "terminei" de um job agendado | Cron que precisa ser vigiado |
27
27
  | [Heartbeat](#heartbeat) | Batimento "estou vivo" | Saber que o robô está de pé, mesmo parado |
28
28
  | [instanceId](#instanceid) | A identidade da instância do robô | Sempre — é obrigatório no `init()` |
29
29
  | [Release e environment](#release-e-environment) | Qual versão, em qual ambiente | Separar produção de homologação; achar a versão que quebrou |
30
- | [Run](#run) | Uma execução solicitada no app | O Manager inteiro gira em volta disso |
30
+ | [Run](#run) | Uma execução solicitada no app | As tasks inteiras giram em volta disso |
31
31
  | [Claim](#claim) | O ato de um agente pegar uma run para si | Entender por que dois agentes nunca colidem |
32
32
  | [Drain mode](#drain-mode) | O agente acelera o poll enquanto tem trabalho | Entender o ritmo do polling |
33
33
  | [Fila, flush e close](#fila-flush-e-close) | Nada é enviado na hora — vai para uma fila | Encerrar o processo sem perder telemetria |
@@ -35,15 +35,28 @@ Os defaults numéricos **não** estão aqui — eles vivem em [Tempos e interval
35
35
 
36
36
  > **Nota de manutenção:** esta página é a fonte canônica das explicações de conceito. As outras páginas da doc, o `README.md` do pacote e os tooltips do app parafraseiam daqui — quando um conceito muda, muda aqui primeiro.
37
37
 
38
+ ## O SDK e os módulos do app
39
+
40
+ Cada API do SDK alimenta um módulo do app da Hobots (app.hobots.app). O mapa:
41
+
42
+ | No SDK | No app |
43
+ | --- | --- |
44
+ | **Projeto** — o "funcionário digital"; dono do Client Secret (`hb_…`) que autentica tudo | **Configurações → Projetos** (é lá que você copia a credencial) |
45
+ | **Agente / instância** — o par `(project_id, instance_id)`; heartbeat e poll de tasks convergem nele | Módulo **Agentes** (uptime, performance) |
46
+ | **[Evento](#evento)** agrupado em **issue** — `captureException` / `captureMessage` | Módulo **Issues** |
47
+ | **Monitor (cron)** — `withMonitor` / `checkIn` com `schedule` | Módulo **Monitores** |
48
+ | **[Transaction](#transaction) / spans** — `startTransaction` (e [`ctx.tx`](#transaction-de-run-ctxtx) dentro de uma run) | Performance no módulo **Agentes**; nas execuções, a aba de performance da solicitação |
49
+ | **Task / [run](#run)** — `register('task-slug', …)` casa com o `task_slug` do formulário | Módulo **Solicitações** (formulários em **Configurações → Formulários**) |
50
+
38
51
  ---
39
52
 
40
53
  ## Evento
41
54
 
42
- Um **evento** é a foto de um instante que vale a pena registrar: uma exceção que estourou ou uma mensagem que você mandou. É a unidade básica do Monitor.
55
+ Um **evento** é a foto de um instante que vale a pena registrar: uma exceção que estourou ou uma mensagem que você mandou. É a unidade básica da telemetria.
43
56
 
44
57
  Quando você chama `captureException` ou `captureMessage`, o SDK monta o evento com o que a exceção traz (tipo, mensagem, stack trace com os frames em ordem) e **anexa tudo que está no [scope](#scope)** naquele momento: tags, usuário, contexts, extras e a trilha de [breadcrumbs](#breadcrumb). Depois disso o evento vai para a [fila](#fila-flush-e-close) e é enviado em lote.
45
58
 
46
- No servidor, eventos parecidos são agrupados numa **issue** — é por isso que 4.000 falhas do mesmo timeout não viram 4.000 linhas na sua tela. Quem decide o que é "parecido" é o [fingerprint](#fingerprint).
59
+ No servidor, eventos parecidos são agrupados numa **issue** — o que você vê no módulo Issues do app. É por isso que 4.000 falhas do mesmo timeout não viram 4.000 linhas na sua tela. Quem decide o que é "parecido" é o [fingerprint](#fingerprint).
47
60
 
48
61
  ```js
49
62
  Hobots.captureException(error);
@@ -207,7 +220,7 @@ Tamanho do buffer: [`maxBreadcrumbs`](./api-reference.md#initoptions).
207
220
 
208
221
  Uma **transaction** é uma unidade de trabalho **nomeada** e **medida**: ela começa, termina, e o que fica registrado é quanto tempo levou. É a resposta para "quanto demora minha rotina de emissão?" — e, quando você adiciona [spans](#span), para "onde foram esses minutos?".
209
222
 
210
- Enquanto o [evento](#evento) responde _o que quebrou_, a transaction responde _quanto tempo levou_. São os dois eixos do Monitor.
223
+ Enquanto o [evento](#evento) responde _o que quebrou_, a transaction responde _quanto tempo levou_. São os dois eixos da telemetria.
211
224
 
212
225
  ```js
213
226
  const tx = Hobots.startTransaction('processar-lote', 'rpa.job');
@@ -226,7 +239,7 @@ Três coisas que valem saber:
226
239
 
227
240
  O `status` default é `'ok'`; encadeáveis: `setStatus`, `setName`, `setTag`.
228
241
 
229
- Dentro de um handler do Manager você **não** cria transaction — já existe uma em [`ctx.tx`](#transaction-de-run-ctxtx).
242
+ Dentro de um handler de task você **não** cria transaction — já existe uma em [`ctx.tx`](#transaction-de-run-ctxtx), e o `startTransaction()` chamado lá dentro devolve exatamente ela.
230
243
 
231
244
  ## Span
232
245
 
@@ -249,7 +262,7 @@ O `op` é a categoria (útil para agrupar "todas as queries") e a `description`
249
262
 
250
263
  ## Transaction de run (ctx.tx)
251
264
 
252
- Dentro de um handler do Manager você **não precisa** criar uma transaction: o SDK já abriu uma para aquela execução e entregou em `ctx.tx`. Ela nasce quando o agente captura a run, é **correlacionada** à execução pelo `run_id`, recebe o status conforme o desfecho (`ok`, `error` ou `cancelled`) e é **finalizada automaticamente** quando o handler termina — você nunca chama `ctx.tx.finish()`.
265
+ Dentro de um handler de task você **não precisa** criar uma transaction: o SDK já abriu uma para aquela execução e entregou em `ctx.tx`. Ela nasce quando o agente captura a run, é **correlacionada** à execução pelo `run_id`, recebe o status conforme o desfecho (`ok`, `error` ou `cancelled`) e é **finalizada automaticamente** quando o handler termina — você nunca chama `ctx.tx.finish()`.
253
266
 
254
267
  O que sobra para você é a parte interessante: marcar as **etapas** do trabalho com [spans](#span). Cada `startChild` vira uma barra no waterfall da aba de performance daquela execução no app.
255
268
 
@@ -270,8 +283,8 @@ Hobots.register('processar-nfe', async (params, ctx) => {
270
283
 
271
284
  Sem nenhum `startChild` a transaction ainda existe e ainda mede o tempo total da run — o waterfall só fica com uma barra. Cada span que você abre é uma resposta a mais para "onde foram os 4 minutos".
272
285
 
273
- - **Não chame `Hobots.startTransaction()` dentro de um handler.** Você criaria uma segunda transaction, **sem** correlação com a run, e ela não apareceria na execução.
274
- - `ctx.tx` **não respeita o `tracesSampleRate`** — toda run gera uma transaction. A amostragem vale para as transactions que **você** abre com `startTransaction()`.
286
+ - **`Hobots.startTransaction()` dentro de um handler devolve a própria `ctx.tx`.** Cada execução tem exatamente **uma** transaction: o SDK detecta o contexto da run e reutiliza a transaction dela em vez de criar uma segunda — os spans caem no mesmo waterfall. Fora de um handler, `startTransaction()` cria uma transaction nova, sem `run_id`.
287
+ - `ctx.tx` **não respeita o `tracesSampleRate`** — toda run gera uma transaction. A amostragem vale para as transactions que **você** abre com `startTransaction()` fora de uma run.
275
288
  - O nome é `run:<task>` e o `op` é `hobots.task`, preenchidos pelo SDK.
276
289
 
277
290
  ## Amostragem (sampleRate e tracesSampleRate)
@@ -338,11 +351,13 @@ Dois detalhes:
338
351
 
339
352
  O timer do heartbeat é `unref`'d — ele **não** segura o processo vivo.
340
353
 
354
+ Com `tasks: true`, o heartbeat é **opcional**: o próprio poll de tasks já marca a presença do agente no painel. Ele continua essencial para agentes só de telemetria.
355
+
341
356
  ## instanceId
342
357
 
343
358
  O **`instanceId`** é a identidade da instância do robô: qual VM, qual container, qual máquina. É **obrigatório** no `init()` e deve ser **estável entre reinícios** (`vm-cliente-01`, `container-nfe-3`) — se você gerar um valor novo a cada boot, o app vê uma frota de robôs fantasmas em vez de um robô que reiniciou.
344
359
 
345
- O que o torna especial é que ele é a identidade dos **dois** canais ao mesmo tempo: o [heartbeat](#heartbeat) do Monitor e o agente do [Manager](./manager.md) enviam o mesmo `instanceId`. O servidor correlaciona os dois, e o robô aparece como **um agente só** no painel — sem nenhuma configuração extra.
360
+ O que o torna especial é que ele é a identidade dos **dois** canais ao mesmo tempo: o [heartbeat](#heartbeat) e o agente de [tasks](./tasks.md) enviam o mesmo `instanceId`. O servidor correlaciona os dois, e o robô aparece como **um agente só** no módulo Agentes — sem nenhuma configuração extra.
346
361
 
347
362
  ## Release e environment
348
363
 
@@ -359,7 +374,7 @@ Servem a duas perguntas concretas:
359
374
 
360
375
  Uma **run** (execução) é um pedido concreto de trabalho criado no app: alguém preencheu o formulário da task, ou uma automação disparou, e agora existe uma solicitação esperando um agente pegar.
361
376
 
362
- É a unidade em volta da qual o [Manager](./manager.md) inteiro gira. O ciclo de vida no servidor:
377
+ É a unidade em volta da qual as [tasks](./tasks.md) inteiras giram — no app, cada run é uma solicitação no módulo **Solicitações**. O ciclo de vida no servidor:
363
378
 
364
379
  ```
365
380
  pending → claimed → running → succeeded | failed | canceled
@@ -372,7 +387,7 @@ pending → claimed → running → succeeded | failed | canceled
372
387
 
373
388
  O agente só transiciona para `running`, `succeeded` e `failed`. `pending` e `claimed` são do servidor; `canceled` vem de alguém cancelando no app.
374
389
 
375
- Cada run carrega os **`params`** (o JSON validado do formulário) e chega ao seu código como o primeiro argumento do handler, junto de um [`RunContext`](./api-reference.md#managertaskhandler--runcontext) com logs, sinal de cancelamento e a [transaction](#transaction-de-run-ctxtx).
390
+ Cada run carrega os **`params`** (o JSON validado do formulário) e chega ao seu código como o primeiro argumento do handler, junto de um [`RunContext`](./api-reference.md#taskhandler--runcontext) com logs, sinal de cancelamento e a [transaction](#transaction-de-run-ctxtx).
376
391
 
377
392
  ## Claim
378
393
 
@@ -406,13 +421,13 @@ Devolve `true` se tudo saiu dentro do tempo e `false` se estourou. `false` **nã
406
421
 
407
422
  ### `close(timeoutMs?)` — "acabou, encerra"
408
423
 
409
- Encerra tudo, **nesta ordem**: para o agente do Manager (aguardando as runs em execução) → para o heartbeat → faz o flush final e fecha o transport. É sempre a última linha do seu programa.
424
+ Encerra tudo, **nesta ordem**: para o agente de tasks (aguardando as runs em execução) → para o heartbeat → faz o flush final e fecha o transport. É sempre a última linha do seu programa.
410
425
 
411
426
  > **Atenção:** `close()` é **terminal e sem volta**. Depois dele, todo `captureException`, transaction, check-in ou heartbeat é **descartado** com um aviso no console — não existe `reopen()`. Se o programa precisar voltar a emitir telemetria, chame `Hobots.init()` de novo.
412
427
 
413
- > **Atenção:** o `timeoutMs` do `close()` é aplicado **duas vezes, em sequência** — uma para esperar as runs do Manager, outra para o flush final. `close(15_000)` pode levar até ~30s no pior caso. Se você tem um SIGTERM com prazo curto (Kubernetes, systemd), dimensione por aí.
428
+ > **Atenção:** o `timeoutMs` do `close()` é aplicado **duas vezes, em sequência** — uma para esperar as runs de tasks, outra para o flush final. `close(15_000)` pode levar até ~30s no pior caso. Se você tem um SIGTERM com prazo curto (Kubernetes, systemd), dimensione por aí.
414
429
 
415
- O `flush` cobre a fila do **Monitor**. Os logs de uma run do Manager (`ctx.log`) são um canal separado, com o próprio ritmo — quem espera por eles é o `close()`/`stop()`, ao aguardar a run terminar.
430
+ O `flush` cobre a fila da **telemetria**. Os logs de uma run de task (`ctx.log`) são um canal separado, com o próprio ritmo — quem espera por eles é o `close()`/`stop()`, ao aguardar a run terminar.
416
431
 
417
432
  Defaults e tempos dos dois: [Tempos e intervalos](./api-reference.md#tempos-e-intervalos).
418
433