hobots 1.2.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -6
- package/dist/index.cjs +10 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -10
- package/dist/index.d.ts +5 -10
- package/dist/index.js +10 -6
- package/dist/index.js.map +1 -1
- package/dist/manager/protocol.cjs.map +1 -1
- package/dist/manager/protocol.d.cts +2 -2
- package/dist/manager/protocol.d.ts +2 -2
- package/docs/README.md +0 -1
- package/docs/api-reference.md +4 -5
- package/docs/getting-started.md +4 -6
- package/docs/manager.md +1 -2
- package/docs/monitor.md +0 -1
- package/docs/protocol.md +9 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,7 +42,6 @@ Você usa **uma, outra ou as duas**:
|
|
|
42
42
|
```js
|
|
43
43
|
Hobots.init({
|
|
44
44
|
clientSecret: 'hb_<64 hex>',
|
|
45
|
-
// baseUrl: 'http://localhost:3002', // só em desenvolvimento
|
|
46
45
|
instanceId: 'vm-cliente-01',
|
|
47
46
|
heartbeat: true, // Monitor: "estou vivo" a cada 30s
|
|
48
47
|
manager: { pollIntervalMs: 5_000 }, // Manager: execução sob demanda
|
|
@@ -66,7 +65,7 @@ Cada projeto tem **um único Client Secret** — a mesma credencial autentica o
|
|
|
66
65
|
hb_<64 hex>
|
|
67
66
|
```
|
|
68
67
|
|
|
69
|
-
(Chaves antigas, 64 hex puros, continuam válidas no servidor.) A credencial é **secreta** e viaja sempre no header `Authorization: Bearer` — nunca na URL. Copie o Client Secret no app, em **Configurações → Projetos** — os snippets de integração já vêm prontos. O SDK fala com `https://
|
|
68
|
+
(Chaves antigas, 64 hex puros, continuam válidas no servidor.) A credencial é **secreta** e viaja sempre no header `Authorization: Bearer` — nunca na URL. Copie o Client Secret no app, em **Configurações → Projetos** — os snippets de integração já vêm prontos. O SDK fala com a API oficial `https://api2.hobots.app` automaticamente; em desenvolvimento, aponte para outro host com a env `HOBOTS_API_URL` (ex.: `HOBOTS_API_URL=http://localhost:3001`).
|
|
70
69
|
|
|
71
70
|
---
|
|
72
71
|
|
|
@@ -81,7 +80,6 @@ Inicialize **uma vez**, o mais cedo possível no processo. Cria o cliente, insta
|
|
|
81
80
|
```js
|
|
82
81
|
Hobots.init({
|
|
83
82
|
clientSecret: 'hb_<64 hex>',
|
|
84
|
-
// baseUrl: 'http://localhost:3002', // só em desenvolvimento
|
|
85
83
|
environment: 'production',
|
|
86
84
|
release: 'robo-nfe@1.4.2',
|
|
87
85
|
instanceId: 'vm-cliente-01',
|
|
@@ -93,7 +91,6 @@ Hobots.init({
|
|
|
93
91
|
| Opção | Tipo | Default | Descrição |
|
|
94
92
|
| --- | --- | --- | --- |
|
|
95
93
|
| `clientSecret` | `string` | **obrigatório** | o Client Secret do projeto (`hb_<64 hex>`), copiado em **Configurações → Projetos** |
|
|
96
|
-
| `baseUrl` | `string` | `'https://app.hobots.app'` | host do app da Hobots — só sobrescreva em desenvolvimento (ex.: `http://localhost:3002`) |
|
|
97
94
|
| `environment` | `string` | `'production'` | ambiente lógico |
|
|
98
95
|
| `release` | `string` | — | versão do programa, ex. `robo-nfe@1.4.2` |
|
|
99
96
|
| `instanceId` | `string` | **obrigatório** | identidade única da instância — heartbeat do Monitor e agente do Manager convergem nela |
|
|
@@ -233,7 +230,6 @@ Capability de **execução remota sob demanda**, habilitada com `manager: true`
|
|
|
233
230
|
```js
|
|
234
231
|
Hobots.init({
|
|
235
232
|
clientSecret: 'hb_<64 hex>',
|
|
236
|
-
// baseUrl: 'http://localhost:3002', // só em desenvolvimento
|
|
237
233
|
instanceId: 'vm-cliente-01',
|
|
238
234
|
manager: true, // ou { pollIntervalMs, concurrency, ... }
|
|
239
235
|
});
|
|
@@ -370,7 +366,7 @@ A 2.0 unifica o Manager no import raiz — `hobots/manager` **foi removido**:
|
|
|
370
366
|
+await Hobots.close(15_000);
|
|
371
367
|
```
|
|
372
368
|
|
|
373
|
-
- A `dsn` (mecanismo antigo, `https://<secretKey>@host/<slug>`) não existe mais — passe `clientSecret` (
|
|
369
|
+
- A `dsn` (mecanismo antigo, `https://<secretKey>@host/<slug>`) não existe mais — passe `clientSecret` (em desenvolvimento, aponte para outro host com a env `HOBOTS_API_URL`). Copie o Client Secret em **Configurações → Projetos**.
|
|
374
370
|
- `agentName` e `serverName` não existem mais — a identidade do agente é o `instanceId` (obrigatório, sem fallback).
|
|
375
371
|
- As opções do Manager (`pollIntervalMs`, `concurrency`, `taskTimeoutMs`, `logFlushIntervalMs`) vão no campo `manager` do `init()`; `clientSecret` e `debug` não se repetem.
|
|
376
372
|
- Tipos (`ManagerTaskHandler`, `RunContext`, `ManagerOptions`) e classes (`ManagerAgent`, `ManagerApi`) agora vêm de `hobots`; o wire format vem de `hobots/protocol`.
|
package/dist/index.cjs
CHANGED
|
@@ -52,23 +52,27 @@ __export(src_exports, {
|
|
|
52
52
|
module.exports = __toCommonJS(src_exports);
|
|
53
53
|
|
|
54
54
|
// src/config.ts
|
|
55
|
-
var DEFAULT_BASE_URL = "https://
|
|
55
|
+
var DEFAULT_BASE_URL = "https://api2.hobots.app";
|
|
56
|
+
function envBaseUrl() {
|
|
57
|
+
if (typeof process === "undefined" || !process.env) return void 0;
|
|
58
|
+
return process.env.HOBOTS_API_URL?.trim() || void 0;
|
|
59
|
+
}
|
|
56
60
|
function resolveConfig(options, prefix = "[hobots]") {
|
|
57
61
|
const key = options.clientSecret?.trim();
|
|
58
62
|
if (!key) {
|
|
59
63
|
throw new Error(`${prefix} clientSecret ausente \u2014 copie o Client Secret do projeto em Configura\xE7\xF5es \u2192 Projetos`);
|
|
60
64
|
}
|
|
61
|
-
const baseUrl = (
|
|
65
|
+
const baseUrl = (envBaseUrl() ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
62
66
|
try {
|
|
63
67
|
new URL(baseUrl);
|
|
64
68
|
} catch {
|
|
65
|
-
throw new Error(`${prefix}
|
|
69
|
+
throw new Error(`${prefix} HOBOTS_API_URL inv\xE1lida: "${baseUrl}" \u2014 esperado ex.: http://localhost:3001`);
|
|
66
70
|
}
|
|
67
71
|
return {
|
|
68
72
|
key,
|
|
69
73
|
baseUrl,
|
|
70
|
-
ingestEndpoint: `${baseUrl}/
|
|
71
|
-
managerBaseUrl: `${baseUrl}/
|
|
74
|
+
ingestEndpoint: `${baseUrl}/v1/ingest`,
|
|
75
|
+
managerBaseUrl: `${baseUrl}/v1/manager`
|
|
72
76
|
};
|
|
73
77
|
}
|
|
74
78
|
|
|
@@ -1105,7 +1109,7 @@ function init(options) {
|
|
|
1105
1109
|
if (options.manager) {
|
|
1106
1110
|
const managerOptions = options.manager === true ? {} : options.manager;
|
|
1107
1111
|
agent = new ManagerAgent(
|
|
1108
|
-
{ ...managerOptions, clientSecret: options.clientSecret,
|
|
1112
|
+
{ ...managerOptions, clientSecret: options.clientSecret, instanceId: options.instanceId, debug: options.debug },
|
|
1109
1113
|
registry
|
|
1110
1114
|
);
|
|
1111
1115
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/stacktrace.ts","../src/utils.ts","../src/eventbuilder.ts","../src/transport.ts","../src/client.ts","../src/heartbeat.ts","../src/instrument.ts","../src/scope.ts","../src/transaction.ts","../src/checkin.ts","../src/manager/api.ts","../src/manager/context.ts","../src/manager/agent.ts","../src/core.ts"],"sourcesContent":["export {\n init,\n getClient,\n captureException,\n captureMessage,\n addBreadcrumb,\n setTag,\n setTags,\n setUser,\n setContext,\n setExtra,\n withScope,\n startTransaction,\n checkIn,\n withMonitor,\n flush,\n register,\n start,\n stop,\n close,\n} from './core';\n\nexport { Client } from './client';\nexport { Scope, type BreadcrumbInput } from './scope';\nexport { Transaction, Span } from './transaction';\nexport { resolveConfig, DEFAULT_BASE_URL, type ResolvedConfig } from './config';\nexport type { CheckInOptions, WithMonitorOptions } from './checkin';\nexport type { InitOptions, CaptureHint, HeartbeatOptions, ManagerOptions } from './types';\n\nexport { ManagerAgent } from './manager/agent';\nexport { ManagerApi, ManagerApiError } from './manager/api';\nexport type { ManagerTaskHandler, RunContext } from './manager/types';\n\nexport type {\n Severity,\n StackFrame,\n Breadcrumb,\n ExceptionData,\n EventUser,\n EventPayload,\n SpanData,\n TransactionPayload,\n CheckInStatus,\n CheckInPayload,\n HeartbeatPayload,\n EnvelopeItem,\n Envelope,\n} from './protocol';\n\nexport type {\n ManagerRunStatus,\n ManagerRunUpdateStatus,\n RunLogLevel,\n RunLogEntry,\n ManagerAgentInfo,\n ManagerPollRequest,\n ManagerRunDescriptor,\n ManagerPollResponse,\n ManagerRunError,\n ManagerRunUpdateRequest,\n ManagerRunUpdateResponse,\n} from './manager/protocol';\n","/** Host SaaS da Hobots — o SDK sempre fala com ele, salvo override de baseUrl (dev). */\nexport const DEFAULT_BASE_URL = 'https://app.hobots.app';\n\nexport interface ResolvedConfig {\n /** Client Secret do projeto (enviado como Authorization: Bearer, nunca na URL) */\n key: string;\n baseUrl: string;\n /** Ingestão do Monitor: <baseUrl>/api/ingest */\n ingestEndpoint: string;\n /** API do Manager: <baseUrl>/api/manager */\n managerBaseUrl: string;\n}\n\ninterface ConfigInput {\n clientSecret: string;\n baseUrl?: string;\n}\n\n/** Resolve clientSecret + baseUrl nos endpoints do Monitor e do Manager. */\nexport function resolveConfig(options: ConfigInput, prefix = '[hobots]'): ResolvedConfig {\n const key = options.clientSecret?.trim();\n if (!key) {\n throw new Error(`${prefix} clientSecret ausente — copie o Client Secret do projeto em Configurações → Projetos`);\n }\n\n const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n try {\n new URL(baseUrl);\n } catch {\n throw new Error(`${prefix} baseUrl inválida: \"${baseUrl}\" — esperado ex.: https://app.hobots.app`);\n }\n\n return {\n key,\n baseUrl,\n ingestEndpoint: `${baseUrl}/api/ingest`,\n managerBaseUrl: `${baseUrl}/api/manager`,\n };\n}\n","import type { StackFrame } from './protocol';\n\nconst MAX_FRAMES = 50;\n\n// \" at fn (file:1:2)\" | \" at file:1:2\" | \" at async fn (file:1:2)\"\nconst FRAME_RE = /^\\s*at\\s+(?:async\\s+)?(?:(.+?)\\s+\\()?(.+?)\\)?$/;\nconst LOCATION_RE = /^(.*?):(\\d+):(\\d+)$/;\n\nfunction isInApp(filename: string | undefined): boolean {\n if (!filename) return false;\n if (filename.startsWith('node:')) return false;\n if (filename.startsWith('internal/')) return false;\n if (filename.includes('node_modules')) return false;\n if (filename === '<anonymous>') return false;\n return true;\n}\n\n/** Converte um `error.stack` do V8 em frames (ordem innermost-first, como o V8 imprime). */\nexport function parseStacktrace(stack: string | undefined | null): StackFrame[] {\n if (!stack) return [];\n\n const frames: StackFrame[] = [];\n for (const line of stack.split('\\n')) {\n if (frames.length >= MAX_FRAMES) break;\n const match = FRAME_RE.exec(line);\n if (!match || !line.trimStart().startsWith('at ')) continue;\n\n const [, fn, location] = match;\n const loc = LOCATION_RE.exec(location ?? '');\n const filename = loc ? loc[1] : location;\n frames.push({\n function: fn || '<anonymous>',\n filename: filename || undefined,\n lineno: loc?.[2] ? Number(loc[2]) : undefined,\n colno: loc?.[3] ? Number(loc[3]) : undefined,\n in_app: isInApp(filename),\n });\n }\n return frames;\n}\n","export const SDK_NAME = 'hobots';\nexport const SDK_VERSION = '1.0.0';\n\nexport function isNode(): boolean {\n return typeof process !== 'undefined' && typeof process.versions?.node === 'string';\n}\n\n/** uuid v4 sem hífens (32 hex). Fallback para contextos sem crypto.randomUUID. */\nexport function uuid4(): string {\n const cryptoRef = (globalThis as { crypto?: Crypto }).crypto;\n if (cryptoRef && typeof cryptoRef.randomUUID === 'function') {\n return cryptoRef.randomUUID().replace(/-/g, '');\n }\n let out = '';\n for (let i = 0; i < 32; i++) {\n out += Math.floor(Math.random() * 16).toString(16);\n }\n return out;\n}\n\nexport function nowISO(): string {\n return new Date().toISOString();\n}\n\n/** Timers não devem segurar o processo Node aberto. */\nexport function unrefTimer(timer: unknown): void {\n (timer as { unref?: () => void } | undefined)?.unref?.();\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, ms);\n unrefTimer(timer);\n });\n}\n\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\nconst PREFIX = '[hobots-monitor]';\n\nexport function makeLogger(enabled: boolean, prefix: string = PREFIX): Logger {\n return {\n debug: (...args) => enabled && console.debug(prefix, ...args),\n warn: (...args) => enabled && console.warn(prefix, ...args),\n error: (...args) => console.error(prefix, ...args),\n };\n}\n","import type { EventPayload, Severity } from './protocol';\nimport { parseStacktrace } from './stacktrace';\nimport { nowISO, uuid4 } from './utils';\n\nfunction safeString(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n const json = JSON.stringify(value);\n if (json && json !== '{}') return json;\n } catch {\n // objetos circulares etc. caem no String()\n }\n return String(value);\n}\n\nexport function eventFromException(error: unknown, level: Severity = 'error'): EventPayload {\n let type: string;\n let value: string;\n let frames = [] as ReturnType<typeof parseStacktrace>;\n\n if (error instanceof Error) {\n type = error.name || 'Error';\n value = error.message;\n frames = parseStacktrace(error.stack);\n } else {\n type = 'NonError';\n value = safeString(error);\n }\n\n return {\n event_id: uuid4(),\n timestamp: nowISO(),\n level,\n exception: {\n type,\n value,\n ...(frames.length > 0 ? { stacktrace: { frames } } : {}),\n },\n };\n}\n\nexport function eventFromMessage(message: string, level: Severity = 'info'): EventPayload {\n return {\n event_id: uuid4(),\n timestamp: nowISO(),\n level,\n message,\n };\n}\n","import type { Envelope, EnvelopeItem } from './protocol';\nimport { SDK_NAME, SDK_VERSION, nowISO, sleep, unrefTimer, type Logger } from './utils';\n\nconst RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\nconst DEFAULT_FLUSH_INTERVAL_MS = 2_000;\nconst DEFAULT_MAX_BATCH_SIZE = 10;\nconst DEFAULT_MAX_QUEUE_SIZE = 200;\n\nexport interface TransportOptions {\n endpoint: string;\n /** Chave secreta do projeto — enviada como Authorization: Bearer */\n key: string;\n logger: Logger;\n flushIntervalMs?: number;\n maxBatchSize?: number;\n maxQueueSize?: number;\n}\n\n/** Fila em memória com batch + retry. Envia envelopes via fetch (Node 18+/browser). */\nexport class Transport {\n private readonly endpoint: string;\n private readonly key: string;\n private readonly logger: Logger;\n private readonly flushIntervalMs: number;\n private readonly maxBatchSize: number;\n private readonly maxQueueSize: number;\n\n private buffer: EnvelopeItem[] = [];\n private timer: ReturnType<typeof setTimeout> | undefined;\n private pending = new Set<Promise<void>>();\n private closed = false;\n\n constructor(options: TransportOptions) {\n this.endpoint = options.endpoint;\n this.key = options.key;\n this.logger = options.logger;\n this.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.maxBatchSize = options.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;\n this.maxQueueSize = options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n }\n\n enqueue(item: EnvelopeItem): void {\n if (this.closed) {\n this.logger.warn('transport fechado, item descartado:', item.type);\n return;\n }\n if (this.buffer.length >= this.maxQueueSize) {\n this.buffer.shift();\n this.logger.warn('fila cheia, item mais antigo descartado');\n }\n this.buffer.push(item);\n\n if (this.buffer.length >= this.maxBatchSize) {\n void this.flushBuffer();\n } else {\n this.schedule();\n }\n }\n\n private schedule(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n void this.flushBuffer();\n }, this.flushIntervalMs);\n unrefTimer(this.timer);\n }\n\n private flushBuffer(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n if (this.buffer.length === 0) return Promise.resolve();\n\n const items = this.buffer.splice(0, this.buffer.length);\n const envelope: Envelope = {\n sdk: { name: SDK_NAME, version: SDK_VERSION },\n sent_at: nowISO(),\n items,\n };\n\n const request: Promise<void> = this.sendWithRetry(envelope).finally(() => {\n this.pending.delete(request);\n });\n this.pending.add(request);\n return request;\n }\n\n private async sendWithRetry(envelope: Envelope): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${this.key}` },\n body: JSON.stringify(envelope),\n });\n if (response.ok) {\n this.logger.debug(`envelope enviado (${envelope.items.length} itens)`);\n return;\n }\n // 4xx (exceto 429) não é recuperável — descarta sem retry\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n this.logger.error(`envelope rejeitado (HTTP ${response.status}), descartado`);\n return;\n }\n throw new Error(`HTTP ${response.status}`);\n } catch (error) {\n const delay = RETRY_DELAYS_MS[attempt];\n if (delay === undefined) {\n this.logger.error('envelope descartado após retries:', error);\n return;\n }\n this.logger.warn(`falha no envio (${String(error)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n }\n }\n\n /** Envia o que estiver na fila e aguarda envios em andamento (até timeoutMs). */\n async flush(timeoutMs = 5_000): Promise<boolean> {\n void this.flushBuffer();\n const all = Promise.allSettled([...this.pending]).then(() => true);\n return Promise.race([all, sleep(timeoutMs).then(() => false)]);\n }\n\n async close(timeoutMs = 5_000): Promise<boolean> {\n const result = await this.flush(timeoutMs);\n this.closed = true;\n return result;\n }\n}\n","import type { CheckInPayload, EventPayload, HeartbeatPayload, Severity, TransactionPayload } from './protocol';\nimport type { CaptureHint, InitOptions } from './types';\nimport { resolveConfig, type ResolvedConfig } from './config';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport type { Scope } from './scope';\nimport { Transport } from './transport';\nimport { isNode, makeLogger, type Logger } from './utils';\n\nfunction runtimeContexts(): Record<string, Record<string, unknown>> {\n if (isNode()) {\n return {\n runtime: { name: 'node', version: process.version },\n os: { name: process.platform, arch: process.arch },\n };\n }\n return { runtime: { name: 'browser' } };\n}\n\nexport class Client {\n readonly options: InitOptions;\n readonly config: ResolvedConfig;\n readonly logger: Logger;\n private readonly transport: Transport;\n\n constructor(options: InitOptions) {\n this.options = options;\n this.logger = makeLogger(!!options.debug);\n this.config = resolveConfig(options);\n this.transport = new Transport({\n endpoint: this.config.ingestEndpoint,\n key: this.config.key,\n logger: this.logger,\n flushIntervalMs: options.flushIntervalMs,\n maxBatchSize: options.maxBatchSize,\n });\n }\n\n captureException(error: unknown, hint: CaptureHint | undefined, scope: Scope): string {\n return this.captureEvent(eventFromException(error, hint?.level ?? 'error'), hint, scope);\n }\n\n captureMessage(message: string, level: Severity, hint: CaptureHint | undefined, scope: Scope): string {\n return this.captureEvent(eventFromMessage(message, level), hint, scope);\n }\n\n captureEvent(event: EventPayload, hint: CaptureHint | undefined, scope: Scope): string {\n const sampleRate = this.options.sampleRate ?? 1;\n if (sampleRate < 1 && Math.random() >= sampleRate) {\n this.logger.debug('evento descartado por sampleRate');\n return event.event_id;\n }\n\n const prepared = this.prepareEvent(event, hint, scope);\n const final = this.options.beforeSend ? this.options.beforeSend(prepared) : prepared;\n if (!final) {\n this.logger.debug('evento descartado por beforeSend');\n return event.event_id;\n }\n\n this.transport.enqueue({ type: 'event', payload: final });\n return final.event_id;\n }\n\n private prepareEvent(event: EventPayload, hint: CaptureHint | undefined, scope: Scope): EventPayload {\n const tags = { ...this.options.tags, ...scope.tags, ...event.tags, ...hint?.tags };\n const extra = { ...scope.extra, ...event.extra, ...hint?.extra };\n\n return {\n ...event,\n level: hint?.level ?? event.level ?? scope.level ?? 'error',\n release: event.release ?? this.options.release,\n environment: event.environment ?? this.options.environment ?? 'production',\n tags: Object.keys(tags).length > 0 ? tags : undefined,\n extra: Object.keys(extra).length > 0 ? extra : undefined,\n user: event.user ?? scope.user,\n contexts: { ...runtimeContexts(), ...scope.contexts, ...event.contexts },\n breadcrumbs: scope.breadcrumbs.length > 0 ? [...scope.breadcrumbs] : event.breadcrumbs,\n fingerprint: hint?.fingerprint ?? event.fingerprint ?? scope.fingerprint,\n };\n }\n\n sendTransaction(payload: TransactionPayload): void {\n this.transport.enqueue({\n type: 'transaction',\n payload: {\n ...payload,\n release: payload.release ?? this.options.release,\n environment: payload.environment ?? this.options.environment ?? 'production',\n tags: { ...this.options.tags, ...payload.tags },\n },\n });\n }\n\n sendCheckIn(payload: CheckInPayload): void {\n this.transport.enqueue({\n type: 'check_in',\n payload: {\n ...payload,\n release: payload.release ?? this.options.release,\n environment: payload.environment ?? this.options.environment ?? 'production',\n },\n });\n }\n\n sendHeartbeat(payload: HeartbeatPayload): void {\n this.transport.enqueue({\n type: 'heartbeat',\n payload: { ...payload, release: payload.release ?? this.options.release },\n });\n }\n\n flush(timeoutMs?: number): Promise<boolean> {\n return this.transport.flush(timeoutMs);\n }\n\n close(timeoutMs?: number): Promise<boolean> {\n return this.transport.close(timeoutMs);\n }\n}\n","import type { Client } from './client';\nimport type { HeartbeatOptions } from './types';\nimport { nowISO, unrefTimer } from './utils';\n\nconst DEFAULT_INTERVAL_MS = 30_000;\n\n/** Batimento periódico \"estou vivo\" — o servidor marca a instância offline quando ele para. */\nexport class Heartbeat {\n private readonly intervalMs: number;\n private readonly instanceId: string;\n private readonly name: string;\n private readonly metadata?: Record<string, unknown>;\n private timer: ReturnType<typeof setInterval> | undefined;\n\n constructor(\n private readonly client: Client,\n options: HeartbeatOptions = {},\n instanceId: string\n ) {\n this.intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;\n this.instanceId = instanceId;\n this.name = options.name ?? instanceId;\n this.metadata = options.metadata;\n }\n\n start(): void {\n if (this.timer) return;\n this.beat();\n this.timer = setInterval(() => this.beat(), this.intervalMs);\n unrefTimer(this.timer);\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n private beat(): void {\n this.client.sendHeartbeat({\n instance_id: this.instanceId,\n name: this.name,\n interval_ms: this.intervalMs,\n timestamp: nowISO(),\n metadata: this.metadata,\n });\n }\n}\n","import type { Client } from './client';\nimport type { Scope } from './scope';\nimport { isNode } from './utils';\n\nlet installed = false;\n\n/**\n * Registra handlers globais de erro.\n * Node: preserva a semântica padrão — após capturar e flushar um uncaughtException,\n * o processo encerra com código 1 (a menos que o programa tenha handler próprio).\n */\nexport function installGlobalHandlers(client: Client, getScope: () => Scope): void {\n if (installed) return;\n installed = true;\n\n if (isNode()) {\n process.on('uncaughtException', (error: Error) => {\n client.captureException(error, { level: 'fatal', tags: { mechanism: 'uncaughtException' } }, getScope());\n void client.flush(2_000).then(() => {\n if (process.listenerCount('uncaughtException') <= 1) {\n console.error(error);\n process.exit(1);\n }\n });\n });\n\n process.on('unhandledRejection', (reason: unknown) => {\n client.captureException(reason, { level: 'error', tags: { mechanism: 'unhandledRejection' } }, getScope());\n // fetch em andamento segura o processo aberto até o envio terminar\n void client.flush(2_000);\n });\n\n // rede de segurança: envia o que restou na fila quando o event loop esvazia\n process.on('beforeExit', () => {\n void client.flush(2_000);\n });\n return;\n }\n\n if (typeof window !== 'undefined') {\n window.addEventListener('error', event => {\n client.captureException(event.error ?? event.message, { tags: { mechanism: 'onerror' } }, getScope());\n });\n window.addEventListener('unhandledrejection', event => {\n client.captureException(event.reason, { tags: { mechanism: 'onunhandledrejection' } }, getScope());\n });\n window.addEventListener('pagehide', () => {\n void client.flush(1_000);\n });\n }\n}\n\n/** Apenas para testes internos. */\nexport function resetGlobalHandlersForTesting(): void {\n installed = false;\n}\n","import type { Breadcrumb, EventUser, Severity } from './protocol';\nimport { nowISO } from './utils';\n\nexport type BreadcrumbInput = Omit<Breadcrumb, 'timestamp'> & { timestamp?: string };\n\n/** Estado contextual anexado aos eventos: tags, usuário, contexts, extras e breadcrumbs. */\nexport class Scope {\n tags: Record<string, string> = {};\n user?: EventUser;\n contexts: Record<string, Record<string, unknown>> = {};\n extra: Record<string, unknown> = {};\n level?: Severity;\n fingerprint?: string[];\n breadcrumbs: Breadcrumb[] = [];\n\n setTag(key: string, value: string): this {\n this.tags[key] = value;\n return this;\n }\n\n setTags(tags: Record<string, string>): this {\n Object.assign(this.tags, tags);\n return this;\n }\n\n setUser(user: EventUser | null): this {\n this.user = user ?? undefined;\n return this;\n }\n\n setContext(name: string, context: Record<string, unknown> | null): this {\n if (context === null) {\n delete this.contexts[name];\n } else {\n this.contexts[name] = context;\n }\n return this;\n }\n\n setExtra(key: string, value: unknown): this {\n this.extra[key] = value;\n return this;\n }\n\n setExtras(extras: Record<string, unknown>): this {\n Object.assign(this.extra, extras);\n return this;\n }\n\n setLevel(level: Severity): this {\n this.level = level;\n return this;\n }\n\n setFingerprint(fingerprint: string[]): this {\n this.fingerprint = fingerprint;\n return this;\n }\n\n addBreadcrumb(crumb: BreadcrumbInput, maxBreadcrumbs: number): this {\n this.breadcrumbs.push({ timestamp: nowISO(), ...crumb });\n if (this.breadcrumbs.length > maxBreadcrumbs) {\n this.breadcrumbs.splice(0, this.breadcrumbs.length - maxBreadcrumbs);\n }\n return this;\n }\n\n clearBreadcrumbs(): this {\n this.breadcrumbs = [];\n return this;\n }\n\n clone(): Scope {\n const next = new Scope();\n next.tags = { ...this.tags };\n next.user = this.user ? { ...this.user } : undefined;\n next.contexts = Object.fromEntries(Object.entries(this.contexts).map(([k, v]) => [k, { ...v }]));\n next.extra = { ...this.extra };\n next.level = this.level;\n next.fingerprint = this.fingerprint ? [...this.fingerprint] : undefined;\n next.breadcrumbs = [...this.breadcrumbs];\n return next;\n }\n}\n","import type { SpanData, TransactionPayload } from './protocol';\nimport type { Client } from './client';\nimport { nowISO, uuid4 } from './utils';\n\nfunction spanId(): string {\n return uuid4().slice(0, 16);\n}\n\nexport class Span {\n readonly spanId = spanId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n endTimestamp?: string;\n data?: Record<string, unknown>;\n\n constructor(\n private readonly transaction: Transaction,\n readonly parentSpanId: string,\n readonly op?: string,\n readonly description?: string\n ) {}\n\n setStatus(status: string): this {\n this.status = status;\n return this;\n }\n\n setData(key: string, value: unknown): this {\n this.data = { ...this.data, [key]: value };\n return this;\n }\n\n /** Span aninhado (filho deste span). */\n startChild(op?: string, description?: string): Span {\n return this.transaction.createSpan(this.spanId, op, description);\n }\n\n finish(): void {\n if (!this.endTimestamp) this.endTimestamp = nowISO();\n }\n\n toJSON(): SpanData {\n return {\n span_id: this.spanId,\n parent_span_id: this.parentSpanId,\n op: this.op,\n description: this.description,\n status: this.status,\n start_timestamp: this.startTimestamp,\n timestamp: this.endTimestamp ?? nowISO(),\n data: this.data,\n };\n }\n}\n\n/**\n * Uma unidade de trabalho nomeada (ex.: uma execução de rotina, uma sincronização).\n * Spans filhos medem as etapas internas (chamadas HTTP, queries, etc.).\n */\nexport class Transaction {\n readonly eventId = uuid4();\n readonly spanId = spanId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n private readonly spans: Span[] = [];\n private readonly tags: Record<string, string> = {};\n private finished = false;\n\n constructor(\n private readonly client: Client | undefined,\n public name: string,\n readonly op?: string,\n private readonly sampled = true\n ) {}\n\n createSpan(parentSpanId: string, op?: string, description?: string): Span {\n const span = new Span(this, parentSpanId, op, description);\n this.spans.push(span);\n return span;\n }\n\n /** Span direto da transaction. */\n startChild(op?: string, description?: string): Span {\n return this.createSpan(this.spanId, op, description);\n }\n\n setTag(key: string, value: string): this {\n this.tags[key] = value;\n return this;\n }\n\n setStatus(status: string): this {\n this.status = status;\n return this;\n }\n\n setName(name: string): this {\n this.name = name;\n return this;\n }\n\n finish(): void {\n if (this.finished) return;\n this.finished = true;\n\n for (const span of this.spans) span.finish();\n\n if (!this.sampled || !this.client) return;\n const payload: TransactionPayload = {\n event_id: this.eventId,\n name: this.name,\n op: this.op,\n status: this.status,\n start_timestamp: this.startTimestamp,\n timestamp: nowISO(),\n spans: this.spans.map(span => span.toJSON()),\n tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,\n };\n this.client.sendTransaction(payload);\n }\n}\n","import type { CheckInStatus } from './protocol';\nimport type { Client } from './client';\nimport { uuid4 } from './utils';\n\nexport interface CheckInOptions {\n monitorSlug: string;\n status: CheckInStatus;\n /** Reutilize o id retornado pelo check-in 'in_progress' para fechar a execução */\n checkInId?: string;\n durationMs?: number;\n /** Expressão cron — cria/atualiza o monitor automaticamente no servidor */\n schedule?: string;\n timezone?: string;\n}\n\nexport function sendCheckIn(client: Client, options: CheckInOptions): string {\n const checkInId = options.checkInId ?? uuid4();\n client.sendCheckIn({\n check_in_id: checkInId,\n monitor_slug: options.monitorSlug,\n status: options.status,\n duration_ms: options.durationMs,\n schedule: options.schedule,\n timezone: options.timezone,\n });\n return checkInId;\n}\n\nexport interface WithMonitorOptions {\n schedule?: string;\n timezone?: string;\n}\n\n/** Envolve a execução de um job: in_progress → ok/error com duração medida. */\nexport async function withMonitorImpl<T>(\n client: Client,\n captureError: (error: unknown) => void,\n monitorSlug: string,\n fn: () => T | Promise<T>,\n options?: WithMonitorOptions\n): Promise<T> {\n const checkInId = sendCheckIn(client, {\n monitorSlug,\n status: 'in_progress',\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n const startedAt = Date.now();\n\n try {\n const result = await fn();\n sendCheckIn(client, {\n monitorSlug,\n status: 'ok',\n checkInId,\n durationMs: Date.now() - startedAt,\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n return result;\n } catch (error) {\n sendCheckIn(client, {\n monitorSlug,\n status: 'error',\n checkInId,\n durationMs: Date.now() - startedAt,\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n captureError(error);\n throw error;\n }\n}\n","import type { ManagerPollRequest, ManagerPollResponse, ManagerRunUpdateRequest } from './protocol';\nimport { sleep, type Logger } from '../utils';\n\nconst RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\n\nexport class ManagerApiError extends Error {\n constructor(\n message: string,\n readonly status: number\n ) {\n super(message);\n this.name = 'ManagerApiError';\n }\n}\n\nexport interface ManagerApiOptions {\n baseUrl: string;\n key: string;\n logger: Logger;\n}\n\n/** Cliente HTTP do agente — bearer auth, retry com backoff nos updates. */\nexport class ManagerApi {\n private readonly baseUrl: string;\n private readonly key: string;\n private readonly logger: Logger;\n\n constructor(options: ManagerApiOptions) {\n this.baseUrl = options.baseUrl;\n this.key = options.key;\n this.logger = options.logger;\n }\n\n private headers(): Record<string, string> {\n return {\n 'content-type': 'application/json',\n authorization: `Bearer ${this.key}`,\n };\n }\n\n /** Um request só — o loop de polling é quem decide o backoff entre tentativas. */\n async poll(request: ManagerPollRequest, signal?: AbortSignal): Promise<ManagerPollResponse> {\n const response = await fetch(`${this.baseUrl}/poll`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal,\n });\n if (!response.ok) {\n throw new ManagerApiError(`poll falhou (HTTP ${response.status})`, response.status);\n }\n return (await response.json()) as ManagerPollResponse;\n }\n\n /**\n * PATCH de status/logs com retry em falha de rede/5xx/429.\n * 4xx é definitivo e vira ManagerApiError imediato (409 = run cancelada/transição inválida).\n */\n async updateRun(runId: string, update: ManagerRunUpdateRequest): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n let retriable: unknown;\n try {\n const response = await fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}`, {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(update),\n });\n if (response.ok) return;\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n throw new ManagerApiError(`update rejeitado (HTTP ${response.status})`, response.status);\n }\n retriable = new Error(`HTTP ${response.status}`);\n } catch (error) {\n if (error instanceof ManagerApiError) throw error;\n retriable = error;\n }\n\n const delay = RETRY_DELAYS_MS[attempt];\n if (delay === undefined) {\n throw new Error(`update da run ${runId} descartado após retries: ${String(retriable)}`);\n }\n this.logger.warn(`falha no update da run ${runId} (${String(retriable)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n }\n}\n","import type { ManagerRunError, ManagerRunUpdateRequest, RunLogEntry, RunLogLevel } from './protocol';\nimport type { RunContext } from './types';\nimport { ManagerApi, ManagerApiError } from './api';\nimport { nowISO, unrefTimer, type Logger } from '../utils';\n\nconst DEFAULT_LOG_FLUSH_INTERVAL_MS = 2_000;\nconst MAX_LOG_MESSAGE_CHARS = 10_000;\nconst MAX_LOGS_PER_RUN = 500;\nconst MAX_LOGS_PER_PATCH = 100;\nconst FLUSH_AT_BUFFERED = 20;\n\n/**\n * Reporter de uma run: bufferiza logs (flush incremental com throttle) e encadeia\n * todos os PATCHes numa fila única — a ordem running → logs → terminal é garantida.\n * Um 409/404 mata o reporter (run cancelada no app): o handler não pode ser morto,\n * mas todo reporte posterior é suprimido e ctx.signal dispara para abort cooperativo.\n */\nexport class RunReporter {\n readonly context: RunContext;\n\n private buffer: RunLogEntry[] = [];\n private loggedCount = 0;\n private droppedCount = 0;\n private dead = false;\n private chain: Promise<void> = Promise.resolve();\n private timer: ReturnType<typeof setTimeout> | undefined;\n private readonly abortController = new AbortController();\n private readonly flushIntervalMs: number;\n\n constructor(\n private readonly api: ManagerApi,\n private readonly runId: string,\n task: string,\n private readonly logger: Logger,\n flushIntervalMs?: number\n ) {\n this.flushIntervalMs = flushIntervalMs ?? DEFAULT_LOG_FLUSH_INTERVAL_MS;\n this.context = {\n runId,\n task,\n log: (level, message) => this.log(level, message),\n signal: this.abortController.signal,\n };\n }\n\n get isDead(): boolean {\n return this.dead;\n }\n\n /** Aborta o ctx.signal sem matar o reporter (timeout/shutdown ainda reportam o terminal). */\n abort(): void {\n if (!this.abortController.signal.aborted) this.abortController.abort();\n }\n\n private log(level: RunLogLevel, message: string): void {\n if (this.dead) return;\n if (this.loggedCount >= MAX_LOGS_PER_RUN) {\n this.droppedCount++;\n return;\n }\n this.loggedCount++;\n const truncated =\n message.length > MAX_LOG_MESSAGE_CHARS ? `${message.slice(0, MAX_LOG_MESSAGE_CHARS)}… [truncado]` : message;\n this.buffer.push({ ts: nowISO(), level, message: truncated });\n\n if (this.buffer.length >= FLUSH_AT_BUFFERED) {\n this.flushLogs();\n } else {\n this.scheduleFlush();\n }\n }\n\n private scheduleFlush(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n this.flushLogs();\n }, this.flushIntervalMs);\n unrefTimer(this.timer);\n }\n\n private clearFlushTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n }\n\n private takeLogs(): RunLogEntry[] {\n const logs = this.buffer.splice(0, this.buffer.length);\n if (this.droppedCount > 0) {\n logs.push({\n ts: nowISO(),\n level: 'warning',\n message: `${this.droppedCount} logs descartados (limite de ${MAX_LOGS_PER_RUN} por execução)`,\n });\n this.droppedCount = 0;\n }\n return logs;\n }\n\n /** Flush incremental: envia o buffer como status 'running' (em chunks). */\n private flushLogs(): void {\n this.clearFlushTimer();\n if (this.dead || this.buffer.length === 0) return;\n const logs = this.buffer.splice(0, this.buffer.length);\n for (let i = 0; i < logs.length; i += MAX_LOGS_PER_PATCH) {\n this.enqueue({ status: 'running', logs: logs.slice(i, i + MAX_LOGS_PER_PATCH) });\n }\n }\n\n /** Primeiro PATCH (claimed → running). Retorna false se a run já morreu (cancelada). */\n async reportRunning(): Promise<boolean> {\n this.enqueue({ status: 'running' });\n await this.chain;\n return !this.dead;\n }\n\n reportSuccess(): void {\n this.clearFlushTimer();\n this.enqueue({ status: 'succeeded', logs: this.takeLogs() });\n }\n\n reportFailure(error: ManagerRunError): void {\n this.clearFlushTimer();\n this.enqueue({ status: 'failed', error, logs: this.takeLogs() });\n }\n\n /** Aguarda a fila de PATCHes esvaziar (chame depois do terminal). */\n finalize(): Promise<void> {\n return this.chain;\n }\n\n private enqueue(update: ManagerRunUpdateRequest): void {\n if (this.dead) return;\n this.chain = this.chain.then(async () => {\n if (this.dead) return;\n const payload = update.logs && update.logs.length === 0 ? { ...update, logs: undefined } : update;\n try {\n await this.api.updateRun(this.runId, payload);\n } catch (error) {\n if (error instanceof ManagerApiError && (error.status === 409 || error.status === 404)) {\n this.dead = true;\n this.abort();\n this.buffer = [];\n this.logger.warn(`run ${this.runId} cancelada/removida no servidor — reporte suprimido`);\n return;\n }\n this.logger.error(`update da run ${this.runId} perdido:`, error);\n }\n });\n }\n}\n","import type { ManagerRunDescriptor, ManagerRunError } from './protocol';\nimport type { ManagerAgentOptions, ManagerTaskHandler } from './types';\nimport { ManagerApi, ManagerApiError } from './api';\nimport { RunReporter } from './context';\nimport { resolveConfig } from '../config';\nimport { isNode, makeLogger, sleep, SDK_VERSION, type Logger } from '../utils';\n\nconst DEFAULT_POLL_INTERVAL_MS = 5_000;\nconst MIN_POLL_INTERVAL_MS = 1_000;\nconst MAX_CONCURRENCY = 5;\nconst POLL_RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\nconst AUTH_FAILURE_INTERVAL_MS = 30_000;\n\ntype AgentState = 'idle' | 'started' | 'stopping';\n\n/** Hostname da máquina — telemetria (campo `host`), distinto da identidade do agente. */\nfunction hostname(): string | undefined {\n if (!isNode()) return undefined;\n return process.env.HOSTNAME || process.env.COMPUTERNAME || undefined;\n}\n\n/**\n * Loop de polling do Manager: busca runs pendentes, executa os handlers registrados\n * e reporta status/logs/result. Ao contrário do Monitor, o timer de polling NÃO é\n * unref'd — um agente iniciado mantém o processo vivo até stop().\n */\nexport class ManagerAgent {\n readonly logger: Logger;\n\n private readonly api: ManagerApi;\n private readonly pollIntervalMs: number;\n private readonly concurrency: number;\n private readonly instanceId: string;\n private readonly taskTimeoutMs?: number;\n private readonly logFlushIntervalMs?: number;\n\n private state: AgentState = 'idle';\n private timer: ReturnType<typeof setTimeout> | undefined;\n private pollAbort: AbortController | undefined;\n private consecutiveFailures = 0;\n private consecutiveAuthFailures = 0;\n private readonly activeRuns = new Set<Promise<void>>();\n private readonly reporters = new Set<RunReporter>();\n\n constructor(\n private readonly options: ManagerAgentOptions,\n private readonly registry: Map<string, ManagerTaskHandler>\n ) {\n this.logger = makeLogger(options.debug ?? false, '[hobots-manager]');\n const config = resolveConfig(options, '[hobots-manager]');\n this.api = new ManagerApi({ baseUrl: config.managerBaseUrl, key: config.key, logger: this.logger });\n this.pollIntervalMs = Math.max(MIN_POLL_INTERVAL_MS, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n this.concurrency = Math.min(MAX_CONCURRENCY, Math.max(1, options.concurrency ?? 1));\n this.instanceId = options.instanceId;\n this.taskTimeoutMs = options.taskTimeoutMs;\n this.logFlushIntervalMs = options.logFlushIntervalMs;\n this.logger.debug('agente configurado', { baseUrl: config.managerBaseUrl });\n }\n\n get activeCount(): number {\n return this.activeRuns.size;\n }\n\n start(): void {\n if (this.state === 'started') return;\n if (this.state === 'stopping') {\n throw new Error('[hobots-manager] start() chamado durante stop() — aguarde o stop terminar');\n }\n if (this.registry.size === 0) {\n throw new Error('[hobots-manager] nenhuma task registrada — chame register() antes de start()');\n }\n this.state = 'started';\n this.logger.debug(`polling iniciado (tasks: ${[...this.registry.keys()].join(', ')})`);\n this.schedule(0);\n }\n\n /** Para o polling e aguarda as runs ativas (até timeoutMs). Retorna true se tudo terminou a tempo. */\n async stop(timeoutMs = 30_000): Promise<boolean> {\n if (this.state === 'idle') return true;\n this.state = 'stopping';\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n this.pollAbort?.abort();\n\n const all = Promise.allSettled([...this.activeRuns]).then(() => true);\n const finished = timeoutMs > 0 ? await Promise.race([all, sleep(timeoutMs).then(() => false)]) : false;\n if (!finished && this.activeRuns.size > 0) {\n this.logger.warn(`${this.activeRuns.size} run(s) ainda em execução após ${timeoutMs}ms — abandonando a espera`);\n for (const reporter of this.reporters) reporter.abort();\n }\n this.state = 'idle';\n return finished;\n }\n\n /** Timer intencionalmente NÃO unref'd: o agente é a razão do processo existir. */\n private schedule(delayMs: number): void {\n if (this.state !== 'started' || this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n void this.tick();\n }, delayMs);\n }\n\n private async tick(): Promise<void> {\n if (this.state !== 'started') return;\n if (this.activeRuns.size >= this.concurrency) {\n this.schedule(this.pollIntervalMs);\n return;\n }\n\n this.pollAbort = new AbortController();\n try {\n const response = await this.api.poll(\n {\n agent: {\n // identidade canônica do agente no painel — o mesmo instanceId do\n // heartbeat do Monitor, então os dois canais convergem em um agente\n instance_id: this.instanceId,\n version: SDK_VERSION,\n host: hostname(),\n tasks: [...this.registry.keys()],\n },\n max: Math.min(MAX_CONCURRENCY, this.concurrency - this.activeRuns.size),\n tasks: [...this.registry.keys()],\n },\n this.pollAbort.signal\n );\n this.consecutiveFailures = 0;\n this.consecutiveAuthFailures = 0;\n\n for (const run of response.runs) {\n this.dispatch(run);\n }\n // com trabalho entregue, re-poll imediato (modo drain); sem trabalho, espera o intervalo\n this.schedule(response.runs.length > 0 ? 0 : this.pollIntervalMs);\n } catch (error) {\n if (this.state !== 'started') return; // stop() abortou o poll\n this.schedule(this.delayAfterPollError(error));\n } finally {\n this.pollAbort = undefined;\n }\n }\n\n private delayAfterPollError(error: unknown): number {\n if (error instanceof ManagerApiError && error.status === 401) {\n // chave desativada/rotacionada — continua tentando devagar (pode ser reativada)\n this.consecutiveAuthFailures++;\n if (this.consecutiveAuthFailures === 1 || this.consecutiveAuthFailures % 10 === 0) {\n this.logger.error('chave rejeitada (401) — verifique o Client Secret do projeto em Configurações → Projetos');\n }\n return Math.max(this.pollIntervalMs, AUTH_FAILURE_INTERVAL_MS);\n }\n this.consecutiveFailures++;\n const ladder = POLL_RETRY_DELAYS_MS[Math.min(this.consecutiveFailures - 1, POLL_RETRY_DELAYS_MS.length - 1)]!;\n const delay = Math.min(Math.max(ladder, 0), Math.max(this.pollIntervalMs, 16_000));\n this.logger.warn(`poll falhou (${String(error)}), próxima tentativa em ${delay}ms`);\n return delay;\n }\n\n private dispatch(run: ManagerRunDescriptor): void {\n const promise = this.executeRun(run)\n .catch(error => this.logger.error(`erro inesperado na run ${run.id}:`, error))\n .finally(() => {\n this.activeRuns.delete(promise);\n if (this.state === 'started') this.schedule(0);\n });\n this.activeRuns.add(promise);\n }\n\n private async executeRun(run: ManagerRunDescriptor): Promise<void> {\n const reporter = new RunReporter(this.api, run.id, run.task, this.logger, this.logFlushIntervalMs);\n this.reporters.add(reporter);\n try {\n const handler = this.registry.get(run.task);\n if (!handler) {\n // claim veio para uma task sem handler (corrida rara) — falha direto, sem 'running'\n reporter.reportFailure({\n type: 'HandlerNotFound',\n message: `tarefa não registrada no agente: ${run.task}`,\n });\n await reporter.finalize();\n return;\n }\n\n const ok = await reporter.reportRunning();\n if (!ok) {\n this.logger.debug(`run ${run.id} cancelada antes de iniciar — handler não executado`);\n return;\n }\n\n this.logger.debug(`executando run ${run.id} (${run.task})`);\n try {\n await this.invokeWithTimeout(handler, run, reporter);\n reporter.reportSuccess();\n this.logger.debug(`run ${run.id} concluída`);\n } catch (error) {\n reporter.reportFailure(toRunError(error));\n this.logger.debug(`run ${run.id} falhou: ${String(error)}`);\n }\n await reporter.finalize();\n } finally {\n this.reporters.delete(reporter);\n }\n }\n\n private async invokeWithTimeout(\n handler: ManagerTaskHandler,\n run: ManagerRunDescriptor,\n reporter: RunReporter\n ): Promise<void> {\n const invocation = Promise.resolve().then(() => handler(run.params, reporter.context));\n if (!this.taskTimeoutMs || this.taskTimeoutMs <= 0) {\n await invocation;\n return;\n }\n\n const timeoutMs = this.taskTimeoutMs;\n const timeout = sleep(timeoutMs).then(() => TIMEOUT_SENTINEL);\n const outcome = await Promise.race([invocation, timeout]);\n if (outcome !== TIMEOUT_SENTINEL) return;\n\n // não dá para matar o código do usuário — reporta, aborta o signal e libera o slot\n reporter.abort();\n invocation\n .then(() => this.logger.warn(`run ${run.id} terminou depois do timeout de ${timeoutMs}ms`))\n .catch(() => this.logger.warn(`run ${run.id} falhou depois do timeout de ${timeoutMs}ms (erro descartado)`));\n throw Object.assign(new Error(`timeout após ${timeoutMs}ms (o handler pode continuar em background)`), {\n name: 'TaskTimeout',\n });\n }\n}\n\nconst TIMEOUT_SENTINEL = Symbol('task-timeout');\n\nconst MAX_ERROR_MESSAGE_CHARS = 10_000;\nconst MAX_ERROR_STACK_CHARS = 20_000;\n\nfunction truncate(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max)}… [truncado]` : value;\n}\n\nfunction toRunError(error: unknown): ManagerRunError {\n if (error instanceof Error) {\n return {\n type: error.name,\n message: truncate(error.message, MAX_ERROR_MESSAGE_CHARS),\n stack: error.stack ? truncate(error.stack, MAX_ERROR_STACK_CHARS) : undefined,\n };\n }\n return { message: truncate(String(error), MAX_ERROR_MESSAGE_CHARS) };\n}\n","import type { EventUser, Severity } from './protocol';\nimport type { CaptureHint, InitOptions } from './types';\nimport { Client } from './client';\nimport { Heartbeat } from './heartbeat';\nimport { installGlobalHandlers } from './instrument';\nimport { Scope, type BreadcrumbInput } from './scope';\nimport { Transaction } from './transaction';\nimport { sendCheckIn, withMonitorImpl, type CheckInOptions, type WithMonitorOptions } from './checkin';\nimport { ManagerAgent } from './manager/agent';\nimport type { ManagerTaskHandler } from './manager/types';\n\nconst DEFAULT_MAX_BREADCRUMBS = 100;\n\nlet client: Client | undefined;\nlet scope = new Scope();\nlet heartbeat: Heartbeat | undefined;\nlet agent: ManagerAgent | undefined;\nconst registry = new Map<string, ManagerTaskHandler>();\nlet warnedManagerDisabled = false;\n\n/** Inicializa o SDK. Chame uma vez, o mais cedo possível no programa. */\nexport function init(options: InitOptions): void {\n if (client) {\n client.logger.warn('init() chamado mais de uma vez — substituindo o client anterior');\n heartbeat?.stop();\n heartbeat = undefined;\n }\n if (agent) {\n void agent.stop(0);\n agent = undefined;\n }\n warnedManagerDisabled = false;\n\n client = new Client(options);\n\n if (options.captureUnhandled !== false) {\n installGlobalHandlers(client, () => scope);\n }\n\n if (options.heartbeat) {\n const heartbeatOptions = options.heartbeat === true ? {} : options.heartbeat;\n heartbeat = new Heartbeat(client, heartbeatOptions, options.instanceId);\n heartbeat.start();\n }\n\n if (options.manager) {\n const managerOptions = options.manager === true ? {} : options.manager;\n agent = new ManagerAgent(\n { ...managerOptions, clientSecret: options.clientSecret, baseUrl: options.baseUrl, instanceId: options.instanceId, debug: options.debug },\n registry\n );\n }\n\n client.logger.debug('inicializado', { endpoint: client.config.ingestEndpoint });\n}\n\nexport function getClient(): Client | undefined {\n return client;\n}\n\n/** Captura uma exceção e retorna o event_id (undefined se o SDK não foi inicializado). */\nexport function captureException(error: unknown, hint?: CaptureHint): string | undefined {\n return client?.captureException(error, hint, scope);\n}\n\nexport function captureMessage(message: string, level: Severity = 'info', hint?: CaptureHint): string | undefined {\n return client?.captureMessage(message, level, hint, scope);\n}\n\n/** Registra um breadcrumb — anexado aos próximos eventos como trilha do que aconteceu antes. */\nexport function addBreadcrumb(crumb: BreadcrumbInput): void {\n scope.addBreadcrumb(crumb, client?.options.maxBreadcrumbs ?? DEFAULT_MAX_BREADCRUMBS);\n}\n\nexport function setTag(key: string, value: string): void {\n scope.setTag(key, value);\n}\n\nexport function setTags(tags: Record<string, string>): void {\n scope.setTags(tags);\n}\n\nexport function setUser(user: EventUser | null): void {\n scope.setUser(user);\n}\n\nexport function setContext(name: string, context: Record<string, unknown> | null): void {\n scope.setContext(name, context);\n}\n\nexport function setExtra(key: string, value: unknown): void {\n scope.setExtra(key, value);\n}\n\n/** Executa o callback com uma cópia isolada do scope (alterações não vazam para fora). */\nexport function withScope<T>(callback: (scope: Scope) => T): T {\n const previous = scope;\n scope = previous.clone();\n try {\n return callback(scope);\n } finally {\n scope = previous;\n }\n}\n\n/** Inicia uma transaction de performance. Chame .finish() para enviá-la. */\nexport function startTransaction(name: string, op?: string): Transaction {\n const rate = client?.options.tracesSampleRate ?? 1;\n const sampled = rate >= 1 || Math.random() < rate;\n return new Transaction(client, name, op, sampled);\n}\n\n/** Check-in manual de um monitor cron. Retorna o check_in_id para fechar a execução depois. */\nexport function checkIn(options: CheckInOptions): string | undefined {\n return client ? sendCheckIn(client, options) : undefined;\n}\n\n/** Envolve um job monitorado: envia in_progress → ok/error com duração e captura a exceção em caso de falha. */\nexport async function withMonitor<T>(\n monitorSlug: string,\n fn: () => T | Promise<T>,\n options?: WithMonitorOptions\n): Promise<T> {\n if (!client) return fn();\n return withMonitorImpl(\n client,\n error => captureException(error, { tags: { monitor: monitorSlug } }),\n monitorSlug,\n fn,\n options\n );\n}\n\n/** Aguarda o envio de tudo que está na fila (até timeoutMs). */\nexport function flush(timeoutMs?: number): Promise<boolean> {\n return client ? client.flush(timeoutMs) : Promise.resolve(true);\n}\n\n/** Registra o handler de uma task do Manager (o task_slug configurado no formulário do app). */\nexport function register<P = Record<string, unknown>>(task: string, handler: ManagerTaskHandler<P>): void {\n if (registry.has(task)) {\n (agent?.logger ?? client?.logger)?.warn(`register('${task}') sobrescreveu um handler existente`);\n }\n if (client && !agent && !warnedManagerDisabled) {\n warnedManagerDisabled = true;\n client.logger.warn(\n `register('${task}') com o Manager desabilitado — passe manager: true (ou opções) no init()`\n );\n }\n registry.set(task, handler as ManagerTaskHandler);\n}\n\n/**\n * Inicia o polling do Manager. O timer NÃO é unref'd: o processo fica vivo\n * aguardando trabalho até stop()/close() — o inverso deliberado do Monitor.\n */\nexport function start(): void {\n if (!agent) {\n throw new Error('[hobots] Manager não configurado — passe manager: true (ou opções) no init() antes de start()');\n }\n agent.start();\n}\n\n/** Para só o Manager: encerra o polling e aguarda as runs ativas (até timeoutMs). A telemetria continua. */\nexport function stop(timeoutMs?: number): Promise<boolean> {\n return agent ? agent.stop(timeoutMs) : Promise.resolve(true);\n}\n\n/**\n * Encerra tudo: para o Manager (aguardando runs em voo), o heartbeat e faz o\n * flush final do transport. Chame antes do processo terminar.\n */\nexport async function close(timeoutMs?: number): Promise<boolean> {\n const agentStopped = agent ? await agent.stop(timeoutMs) : true;\n heartbeat?.stop();\n heartbeat = undefined;\n const clientClosed = client ? await client.close(timeoutMs) : true;\n return agentStopped && clientClosed;\n}\n"],"mappings":"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","names":["scope","client","client","client","client","RETRY_DELAYS_MS","registry"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/stacktrace.ts","../src/utils.ts","../src/eventbuilder.ts","../src/transport.ts","../src/client.ts","../src/heartbeat.ts","../src/instrument.ts","../src/scope.ts","../src/transaction.ts","../src/checkin.ts","../src/manager/api.ts","../src/manager/context.ts","../src/manager/agent.ts","../src/core.ts"],"sourcesContent":["export {\n init,\n getClient,\n captureException,\n captureMessage,\n addBreadcrumb,\n setTag,\n setTags,\n setUser,\n setContext,\n setExtra,\n withScope,\n startTransaction,\n checkIn,\n withMonitor,\n flush,\n register,\n start,\n stop,\n close,\n} from './core';\n\nexport { Client } from './client';\nexport { Scope, type BreadcrumbInput } from './scope';\nexport { Transaction, Span } from './transaction';\nexport { resolveConfig, DEFAULT_BASE_URL, type ResolvedConfig } from './config';\nexport type { CheckInOptions, WithMonitorOptions } from './checkin';\nexport type { InitOptions, CaptureHint, HeartbeatOptions, ManagerOptions } from './types';\n\nexport { ManagerAgent } from './manager/agent';\nexport { ManagerApi, ManagerApiError } from './manager/api';\nexport type { ManagerTaskHandler, RunContext } from './manager/types';\n\nexport type {\n Severity,\n StackFrame,\n Breadcrumb,\n ExceptionData,\n EventUser,\n EventPayload,\n SpanData,\n TransactionPayload,\n CheckInStatus,\n CheckInPayload,\n HeartbeatPayload,\n EnvelopeItem,\n Envelope,\n} from './protocol';\n\nexport type {\n ManagerRunStatus,\n ManagerRunUpdateStatus,\n RunLogLevel,\n RunLogEntry,\n ManagerAgentInfo,\n ManagerPollRequest,\n ManagerRunDescriptor,\n ManagerPollResponse,\n ManagerRunError,\n ManagerRunUpdateRequest,\n ManagerRunUpdateResponse,\n} from './manager/protocol';\n","/** API oficial da Hobots — o SDK sempre fala com ela em produção. */\nexport const DEFAULT_BASE_URL = 'https://api2.hobots.app';\n\nexport interface ResolvedConfig {\n /** Client Secret do projeto (enviado como Authorization: Bearer, nunca na URL) */\n key: string;\n baseUrl: string;\n /** Ingestão do Monitor: <baseUrl>/v1/ingest */\n ingestEndpoint: string;\n /** API do Manager: <baseUrl>/v1/manager */\n managerBaseUrl: string;\n}\n\ninterface ConfigInput {\n clientSecret: string;\n}\n\n/**\n * Override de desenvolvimento via env HOBOTS_API_URL — a única forma de apontar\n * o SDK para outro host. Em produção a URL é sempre a API oficial.\n */\nfunction envBaseUrl(): string | undefined {\n // browser: `process` pode não existir\n if (typeof process === 'undefined' || !process.env) return undefined;\n return process.env.HOBOTS_API_URL?.trim() || undefined;\n}\n\n/** Resolve o clientSecret nos endpoints do Monitor e do Manager. */\nexport function resolveConfig(options: ConfigInput, prefix = '[hobots]'): ResolvedConfig {\n const key = options.clientSecret?.trim();\n if (!key) {\n throw new Error(`${prefix} clientSecret ausente — copie o Client Secret do projeto em Configurações → Projetos`);\n }\n\n const baseUrl = (envBaseUrl() ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n try {\n new URL(baseUrl);\n } catch {\n throw new Error(`${prefix} HOBOTS_API_URL inválida: \"${baseUrl}\" — esperado ex.: http://localhost:3001`);\n }\n\n return {\n key,\n baseUrl,\n ingestEndpoint: `${baseUrl}/v1/ingest`,\n managerBaseUrl: `${baseUrl}/v1/manager`,\n };\n}\n","import type { StackFrame } from './protocol';\n\nconst MAX_FRAMES = 50;\n\n// \" at fn (file:1:2)\" | \" at file:1:2\" | \" at async fn (file:1:2)\"\nconst FRAME_RE = /^\\s*at\\s+(?:async\\s+)?(?:(.+?)\\s+\\()?(.+?)\\)?$/;\nconst LOCATION_RE = /^(.*?):(\\d+):(\\d+)$/;\n\nfunction isInApp(filename: string | undefined): boolean {\n if (!filename) return false;\n if (filename.startsWith('node:')) return false;\n if (filename.startsWith('internal/')) return false;\n if (filename.includes('node_modules')) return false;\n if (filename === '<anonymous>') return false;\n return true;\n}\n\n/** Converte um `error.stack` do V8 em frames (ordem innermost-first, como o V8 imprime). */\nexport function parseStacktrace(stack: string | undefined | null): StackFrame[] {\n if (!stack) return [];\n\n const frames: StackFrame[] = [];\n for (const line of stack.split('\\n')) {\n if (frames.length >= MAX_FRAMES) break;\n const match = FRAME_RE.exec(line);\n if (!match || !line.trimStart().startsWith('at ')) continue;\n\n const [, fn, location] = match;\n const loc = LOCATION_RE.exec(location ?? '');\n const filename = loc ? loc[1] : location;\n frames.push({\n function: fn || '<anonymous>',\n filename: filename || undefined,\n lineno: loc?.[2] ? Number(loc[2]) : undefined,\n colno: loc?.[3] ? Number(loc[3]) : undefined,\n in_app: isInApp(filename),\n });\n }\n return frames;\n}\n","export const SDK_NAME = 'hobots';\nexport const SDK_VERSION = '1.0.0';\n\nexport function isNode(): boolean {\n return typeof process !== 'undefined' && typeof process.versions?.node === 'string';\n}\n\n/** uuid v4 sem hífens (32 hex). Fallback para contextos sem crypto.randomUUID. */\nexport function uuid4(): string {\n const cryptoRef = (globalThis as { crypto?: Crypto }).crypto;\n if (cryptoRef && typeof cryptoRef.randomUUID === 'function') {\n return cryptoRef.randomUUID().replace(/-/g, '');\n }\n let out = '';\n for (let i = 0; i < 32; i++) {\n out += Math.floor(Math.random() * 16).toString(16);\n }\n return out;\n}\n\nexport function nowISO(): string {\n return new Date().toISOString();\n}\n\n/** Timers não devem segurar o processo Node aberto. */\nexport function unrefTimer(timer: unknown): void {\n (timer as { unref?: () => void } | undefined)?.unref?.();\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, ms);\n unrefTimer(timer);\n });\n}\n\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\nconst PREFIX = '[hobots-monitor]';\n\nexport function makeLogger(enabled: boolean, prefix: string = PREFIX): Logger {\n return {\n debug: (...args) => enabled && console.debug(prefix, ...args),\n warn: (...args) => enabled && console.warn(prefix, ...args),\n error: (...args) => console.error(prefix, ...args),\n };\n}\n","import type { EventPayload, Severity } from './protocol';\nimport { parseStacktrace } from './stacktrace';\nimport { nowISO, uuid4 } from './utils';\n\nfunction safeString(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n const json = JSON.stringify(value);\n if (json && json !== '{}') return json;\n } catch {\n // objetos circulares etc. caem no String()\n }\n return String(value);\n}\n\nexport function eventFromException(error: unknown, level: Severity = 'error'): EventPayload {\n let type: string;\n let value: string;\n let frames = [] as ReturnType<typeof parseStacktrace>;\n\n if (error instanceof Error) {\n type = error.name || 'Error';\n value = error.message;\n frames = parseStacktrace(error.stack);\n } else {\n type = 'NonError';\n value = safeString(error);\n }\n\n return {\n event_id: uuid4(),\n timestamp: nowISO(),\n level,\n exception: {\n type,\n value,\n ...(frames.length > 0 ? { stacktrace: { frames } } : {}),\n },\n };\n}\n\nexport function eventFromMessage(message: string, level: Severity = 'info'): EventPayload {\n return {\n event_id: uuid4(),\n timestamp: nowISO(),\n level,\n message,\n };\n}\n","import type { Envelope, EnvelopeItem } from './protocol';\nimport { SDK_NAME, SDK_VERSION, nowISO, sleep, unrefTimer, type Logger } from './utils';\n\nconst RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\nconst DEFAULT_FLUSH_INTERVAL_MS = 2_000;\nconst DEFAULT_MAX_BATCH_SIZE = 10;\nconst DEFAULT_MAX_QUEUE_SIZE = 200;\n\nexport interface TransportOptions {\n endpoint: string;\n /** Chave secreta do projeto — enviada como Authorization: Bearer */\n key: string;\n logger: Logger;\n flushIntervalMs?: number;\n maxBatchSize?: number;\n maxQueueSize?: number;\n}\n\n/** Fila em memória com batch + retry. Envia envelopes via fetch (Node 18+/browser). */\nexport class Transport {\n private readonly endpoint: string;\n private readonly key: string;\n private readonly logger: Logger;\n private readonly flushIntervalMs: number;\n private readonly maxBatchSize: number;\n private readonly maxQueueSize: number;\n\n private buffer: EnvelopeItem[] = [];\n private timer: ReturnType<typeof setTimeout> | undefined;\n private pending = new Set<Promise<void>>();\n private closed = false;\n\n constructor(options: TransportOptions) {\n this.endpoint = options.endpoint;\n this.key = options.key;\n this.logger = options.logger;\n this.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.maxBatchSize = options.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;\n this.maxQueueSize = options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n }\n\n enqueue(item: EnvelopeItem): void {\n if (this.closed) {\n this.logger.warn('transport fechado, item descartado:', item.type);\n return;\n }\n if (this.buffer.length >= this.maxQueueSize) {\n this.buffer.shift();\n this.logger.warn('fila cheia, item mais antigo descartado');\n }\n this.buffer.push(item);\n\n if (this.buffer.length >= this.maxBatchSize) {\n void this.flushBuffer();\n } else {\n this.schedule();\n }\n }\n\n private schedule(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n void this.flushBuffer();\n }, this.flushIntervalMs);\n unrefTimer(this.timer);\n }\n\n private flushBuffer(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n if (this.buffer.length === 0) return Promise.resolve();\n\n const items = this.buffer.splice(0, this.buffer.length);\n const envelope: Envelope = {\n sdk: { name: SDK_NAME, version: SDK_VERSION },\n sent_at: nowISO(),\n items,\n };\n\n const request: Promise<void> = this.sendWithRetry(envelope).finally(() => {\n this.pending.delete(request);\n });\n this.pending.add(request);\n return request;\n }\n\n private async sendWithRetry(envelope: Envelope): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${this.key}` },\n body: JSON.stringify(envelope),\n });\n if (response.ok) {\n this.logger.debug(`envelope enviado (${envelope.items.length} itens)`);\n return;\n }\n // 4xx (exceto 429) não é recuperável — descarta sem retry\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n this.logger.error(`envelope rejeitado (HTTP ${response.status}), descartado`);\n return;\n }\n throw new Error(`HTTP ${response.status}`);\n } catch (error) {\n const delay = RETRY_DELAYS_MS[attempt];\n if (delay === undefined) {\n this.logger.error('envelope descartado após retries:', error);\n return;\n }\n this.logger.warn(`falha no envio (${String(error)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n }\n }\n\n /** Envia o que estiver na fila e aguarda envios em andamento (até timeoutMs). */\n async flush(timeoutMs = 5_000): Promise<boolean> {\n void this.flushBuffer();\n const all = Promise.allSettled([...this.pending]).then(() => true);\n return Promise.race([all, sleep(timeoutMs).then(() => false)]);\n }\n\n async close(timeoutMs = 5_000): Promise<boolean> {\n const result = await this.flush(timeoutMs);\n this.closed = true;\n return result;\n }\n}\n","import type { CheckInPayload, EventPayload, HeartbeatPayload, Severity, TransactionPayload } from './protocol';\nimport type { CaptureHint, InitOptions } from './types';\nimport { resolveConfig, type ResolvedConfig } from './config';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport type { Scope } from './scope';\nimport { Transport } from './transport';\nimport { isNode, makeLogger, type Logger } from './utils';\n\nfunction runtimeContexts(): Record<string, Record<string, unknown>> {\n if (isNode()) {\n return {\n runtime: { name: 'node', version: process.version },\n os: { name: process.platform, arch: process.arch },\n };\n }\n return { runtime: { name: 'browser' } };\n}\n\nexport class Client {\n readonly options: InitOptions;\n readonly config: ResolvedConfig;\n readonly logger: Logger;\n private readonly transport: Transport;\n\n constructor(options: InitOptions) {\n this.options = options;\n this.logger = makeLogger(!!options.debug);\n this.config = resolveConfig(options);\n this.transport = new Transport({\n endpoint: this.config.ingestEndpoint,\n key: this.config.key,\n logger: this.logger,\n flushIntervalMs: options.flushIntervalMs,\n maxBatchSize: options.maxBatchSize,\n });\n }\n\n captureException(error: unknown, hint: CaptureHint | undefined, scope: Scope): string {\n return this.captureEvent(eventFromException(error, hint?.level ?? 'error'), hint, scope);\n }\n\n captureMessage(message: string, level: Severity, hint: CaptureHint | undefined, scope: Scope): string {\n return this.captureEvent(eventFromMessage(message, level), hint, scope);\n }\n\n captureEvent(event: EventPayload, hint: CaptureHint | undefined, scope: Scope): string {\n const sampleRate = this.options.sampleRate ?? 1;\n if (sampleRate < 1 && Math.random() >= sampleRate) {\n this.logger.debug('evento descartado por sampleRate');\n return event.event_id;\n }\n\n const prepared = this.prepareEvent(event, hint, scope);\n const final = this.options.beforeSend ? this.options.beforeSend(prepared) : prepared;\n if (!final) {\n this.logger.debug('evento descartado por beforeSend');\n return event.event_id;\n }\n\n this.transport.enqueue({ type: 'event', payload: final });\n return final.event_id;\n }\n\n private prepareEvent(event: EventPayload, hint: CaptureHint | undefined, scope: Scope): EventPayload {\n const tags = { ...this.options.tags, ...scope.tags, ...event.tags, ...hint?.tags };\n const extra = { ...scope.extra, ...event.extra, ...hint?.extra };\n\n return {\n ...event,\n level: hint?.level ?? event.level ?? scope.level ?? 'error',\n release: event.release ?? this.options.release,\n environment: event.environment ?? this.options.environment ?? 'production',\n tags: Object.keys(tags).length > 0 ? tags : undefined,\n extra: Object.keys(extra).length > 0 ? extra : undefined,\n user: event.user ?? scope.user,\n contexts: { ...runtimeContexts(), ...scope.contexts, ...event.contexts },\n breadcrumbs: scope.breadcrumbs.length > 0 ? [...scope.breadcrumbs] : event.breadcrumbs,\n fingerprint: hint?.fingerprint ?? event.fingerprint ?? scope.fingerprint,\n };\n }\n\n sendTransaction(payload: TransactionPayload): void {\n this.transport.enqueue({\n type: 'transaction',\n payload: {\n ...payload,\n release: payload.release ?? this.options.release,\n environment: payload.environment ?? this.options.environment ?? 'production',\n tags: { ...this.options.tags, ...payload.tags },\n },\n });\n }\n\n sendCheckIn(payload: CheckInPayload): void {\n this.transport.enqueue({\n type: 'check_in',\n payload: {\n ...payload,\n release: payload.release ?? this.options.release,\n environment: payload.environment ?? this.options.environment ?? 'production',\n },\n });\n }\n\n sendHeartbeat(payload: HeartbeatPayload): void {\n this.transport.enqueue({\n type: 'heartbeat',\n payload: { ...payload, release: payload.release ?? this.options.release },\n });\n }\n\n flush(timeoutMs?: number): Promise<boolean> {\n return this.transport.flush(timeoutMs);\n }\n\n close(timeoutMs?: number): Promise<boolean> {\n return this.transport.close(timeoutMs);\n }\n}\n","import type { Client } from './client';\nimport type { HeartbeatOptions } from './types';\nimport { nowISO, unrefTimer } from './utils';\n\nconst DEFAULT_INTERVAL_MS = 30_000;\n\n/** Batimento periódico \"estou vivo\" — o servidor marca a instância offline quando ele para. */\nexport class Heartbeat {\n private readonly intervalMs: number;\n private readonly instanceId: string;\n private readonly name: string;\n private readonly metadata?: Record<string, unknown>;\n private timer: ReturnType<typeof setInterval> | undefined;\n\n constructor(\n private readonly client: Client,\n options: HeartbeatOptions = {},\n instanceId: string\n ) {\n this.intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;\n this.instanceId = instanceId;\n this.name = options.name ?? instanceId;\n this.metadata = options.metadata;\n }\n\n start(): void {\n if (this.timer) return;\n this.beat();\n this.timer = setInterval(() => this.beat(), this.intervalMs);\n unrefTimer(this.timer);\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n private beat(): void {\n this.client.sendHeartbeat({\n instance_id: this.instanceId,\n name: this.name,\n interval_ms: this.intervalMs,\n timestamp: nowISO(),\n metadata: this.metadata,\n });\n }\n}\n","import type { Client } from './client';\nimport type { Scope } from './scope';\nimport { isNode } from './utils';\n\nlet installed = false;\n\n/**\n * Registra handlers globais de erro.\n * Node: preserva a semântica padrão — após capturar e flushar um uncaughtException,\n * o processo encerra com código 1 (a menos que o programa tenha handler próprio).\n */\nexport function installGlobalHandlers(client: Client, getScope: () => Scope): void {\n if (installed) return;\n installed = true;\n\n if (isNode()) {\n process.on('uncaughtException', (error: Error) => {\n client.captureException(error, { level: 'fatal', tags: { mechanism: 'uncaughtException' } }, getScope());\n void client.flush(2_000).then(() => {\n if (process.listenerCount('uncaughtException') <= 1) {\n console.error(error);\n process.exit(1);\n }\n });\n });\n\n process.on('unhandledRejection', (reason: unknown) => {\n client.captureException(reason, { level: 'error', tags: { mechanism: 'unhandledRejection' } }, getScope());\n // fetch em andamento segura o processo aberto até o envio terminar\n void client.flush(2_000);\n });\n\n // rede de segurança: envia o que restou na fila quando o event loop esvazia\n process.on('beforeExit', () => {\n void client.flush(2_000);\n });\n return;\n }\n\n if (typeof window !== 'undefined') {\n window.addEventListener('error', event => {\n client.captureException(event.error ?? event.message, { tags: { mechanism: 'onerror' } }, getScope());\n });\n window.addEventListener('unhandledrejection', event => {\n client.captureException(event.reason, { tags: { mechanism: 'onunhandledrejection' } }, getScope());\n });\n window.addEventListener('pagehide', () => {\n void client.flush(1_000);\n });\n }\n}\n\n/** Apenas para testes internos. */\nexport function resetGlobalHandlersForTesting(): void {\n installed = false;\n}\n","import type { Breadcrumb, EventUser, Severity } from './protocol';\nimport { nowISO } from './utils';\n\nexport type BreadcrumbInput = Omit<Breadcrumb, 'timestamp'> & { timestamp?: string };\n\n/** Estado contextual anexado aos eventos: tags, usuário, contexts, extras e breadcrumbs. */\nexport class Scope {\n tags: Record<string, string> = {};\n user?: EventUser;\n contexts: Record<string, Record<string, unknown>> = {};\n extra: Record<string, unknown> = {};\n level?: Severity;\n fingerprint?: string[];\n breadcrumbs: Breadcrumb[] = [];\n\n setTag(key: string, value: string): this {\n this.tags[key] = value;\n return this;\n }\n\n setTags(tags: Record<string, string>): this {\n Object.assign(this.tags, tags);\n return this;\n }\n\n setUser(user: EventUser | null): this {\n this.user = user ?? undefined;\n return this;\n }\n\n setContext(name: string, context: Record<string, unknown> | null): this {\n if (context === null) {\n delete this.contexts[name];\n } else {\n this.contexts[name] = context;\n }\n return this;\n }\n\n setExtra(key: string, value: unknown): this {\n this.extra[key] = value;\n return this;\n }\n\n setExtras(extras: Record<string, unknown>): this {\n Object.assign(this.extra, extras);\n return this;\n }\n\n setLevel(level: Severity): this {\n this.level = level;\n return this;\n }\n\n setFingerprint(fingerprint: string[]): this {\n this.fingerprint = fingerprint;\n return this;\n }\n\n addBreadcrumb(crumb: BreadcrumbInput, maxBreadcrumbs: number): this {\n this.breadcrumbs.push({ timestamp: nowISO(), ...crumb });\n if (this.breadcrumbs.length > maxBreadcrumbs) {\n this.breadcrumbs.splice(0, this.breadcrumbs.length - maxBreadcrumbs);\n }\n return this;\n }\n\n clearBreadcrumbs(): this {\n this.breadcrumbs = [];\n return this;\n }\n\n clone(): Scope {\n const next = new Scope();\n next.tags = { ...this.tags };\n next.user = this.user ? { ...this.user } : undefined;\n next.contexts = Object.fromEntries(Object.entries(this.contexts).map(([k, v]) => [k, { ...v }]));\n next.extra = { ...this.extra };\n next.level = this.level;\n next.fingerprint = this.fingerprint ? [...this.fingerprint] : undefined;\n next.breadcrumbs = [...this.breadcrumbs];\n return next;\n }\n}\n","import type { SpanData, TransactionPayload } from './protocol';\nimport type { Client } from './client';\nimport { nowISO, uuid4 } from './utils';\n\nfunction spanId(): string {\n return uuid4().slice(0, 16);\n}\n\nexport class Span {\n readonly spanId = spanId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n endTimestamp?: string;\n data?: Record<string, unknown>;\n\n constructor(\n private readonly transaction: Transaction,\n readonly parentSpanId: string,\n readonly op?: string,\n readonly description?: string\n ) {}\n\n setStatus(status: string): this {\n this.status = status;\n return this;\n }\n\n setData(key: string, value: unknown): this {\n this.data = { ...this.data, [key]: value };\n return this;\n }\n\n /** Span aninhado (filho deste span). */\n startChild(op?: string, description?: string): Span {\n return this.transaction.createSpan(this.spanId, op, description);\n }\n\n finish(): void {\n if (!this.endTimestamp) this.endTimestamp = nowISO();\n }\n\n toJSON(): SpanData {\n return {\n span_id: this.spanId,\n parent_span_id: this.parentSpanId,\n op: this.op,\n description: this.description,\n status: this.status,\n start_timestamp: this.startTimestamp,\n timestamp: this.endTimestamp ?? nowISO(),\n data: this.data,\n };\n }\n}\n\n/**\n * Uma unidade de trabalho nomeada (ex.: uma execução de rotina, uma sincronização).\n * Spans filhos medem as etapas internas (chamadas HTTP, queries, etc.).\n */\nexport class Transaction {\n readonly eventId = uuid4();\n readonly spanId = spanId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n private readonly spans: Span[] = [];\n private readonly tags: Record<string, string> = {};\n private finished = false;\n\n constructor(\n private readonly client: Client | undefined,\n public name: string,\n readonly op?: string,\n private readonly sampled = true\n ) {}\n\n createSpan(parentSpanId: string, op?: string, description?: string): Span {\n const span = new Span(this, parentSpanId, op, description);\n this.spans.push(span);\n return span;\n }\n\n /** Span direto da transaction. */\n startChild(op?: string, description?: string): Span {\n return this.createSpan(this.spanId, op, description);\n }\n\n setTag(key: string, value: string): this {\n this.tags[key] = value;\n return this;\n }\n\n setStatus(status: string): this {\n this.status = status;\n return this;\n }\n\n setName(name: string): this {\n this.name = name;\n return this;\n }\n\n finish(): void {\n if (this.finished) return;\n this.finished = true;\n\n for (const span of this.spans) span.finish();\n\n if (!this.sampled || !this.client) return;\n const payload: TransactionPayload = {\n event_id: this.eventId,\n name: this.name,\n op: this.op,\n status: this.status,\n start_timestamp: this.startTimestamp,\n timestamp: nowISO(),\n spans: this.spans.map(span => span.toJSON()),\n tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,\n };\n this.client.sendTransaction(payload);\n }\n}\n","import type { CheckInStatus } from './protocol';\nimport type { Client } from './client';\nimport { uuid4 } from './utils';\n\nexport interface CheckInOptions {\n monitorSlug: string;\n status: CheckInStatus;\n /** Reutilize o id retornado pelo check-in 'in_progress' para fechar a execução */\n checkInId?: string;\n durationMs?: number;\n /** Expressão cron — cria/atualiza o monitor automaticamente no servidor */\n schedule?: string;\n timezone?: string;\n}\n\nexport function sendCheckIn(client: Client, options: CheckInOptions): string {\n const checkInId = options.checkInId ?? uuid4();\n client.sendCheckIn({\n check_in_id: checkInId,\n monitor_slug: options.monitorSlug,\n status: options.status,\n duration_ms: options.durationMs,\n schedule: options.schedule,\n timezone: options.timezone,\n });\n return checkInId;\n}\n\nexport interface WithMonitorOptions {\n schedule?: string;\n timezone?: string;\n}\n\n/** Envolve a execução de um job: in_progress → ok/error com duração medida. */\nexport async function withMonitorImpl<T>(\n client: Client,\n captureError: (error: unknown) => void,\n monitorSlug: string,\n fn: () => T | Promise<T>,\n options?: WithMonitorOptions\n): Promise<T> {\n const checkInId = sendCheckIn(client, {\n monitorSlug,\n status: 'in_progress',\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n const startedAt = Date.now();\n\n try {\n const result = await fn();\n sendCheckIn(client, {\n monitorSlug,\n status: 'ok',\n checkInId,\n durationMs: Date.now() - startedAt,\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n return result;\n } catch (error) {\n sendCheckIn(client, {\n monitorSlug,\n status: 'error',\n checkInId,\n durationMs: Date.now() - startedAt,\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n captureError(error);\n throw error;\n }\n}\n","import type { ManagerPollRequest, ManagerPollResponse, ManagerRunUpdateRequest } from './protocol';\nimport { sleep, type Logger } from '../utils';\n\nconst RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\n\nexport class ManagerApiError extends Error {\n constructor(\n message: string,\n readonly status: number\n ) {\n super(message);\n this.name = 'ManagerApiError';\n }\n}\n\nexport interface ManagerApiOptions {\n baseUrl: string;\n key: string;\n logger: Logger;\n}\n\n/** Cliente HTTP do agente — bearer auth, retry com backoff nos updates. */\nexport class ManagerApi {\n private readonly baseUrl: string;\n private readonly key: string;\n private readonly logger: Logger;\n\n constructor(options: ManagerApiOptions) {\n this.baseUrl = options.baseUrl;\n this.key = options.key;\n this.logger = options.logger;\n }\n\n private headers(): Record<string, string> {\n return {\n 'content-type': 'application/json',\n authorization: `Bearer ${this.key}`,\n };\n }\n\n /** Um request só — o loop de polling é quem decide o backoff entre tentativas. */\n async poll(request: ManagerPollRequest, signal?: AbortSignal): Promise<ManagerPollResponse> {\n const response = await fetch(`${this.baseUrl}/poll`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal,\n });\n if (!response.ok) {\n throw new ManagerApiError(`poll falhou (HTTP ${response.status})`, response.status);\n }\n return (await response.json()) as ManagerPollResponse;\n }\n\n /**\n * PATCH de status/logs com retry em falha de rede/5xx/429.\n * 4xx é definitivo e vira ManagerApiError imediato (409 = run cancelada/transição inválida).\n */\n async updateRun(runId: string, update: ManagerRunUpdateRequest): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n let retriable: unknown;\n try {\n const response = await fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}`, {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(update),\n });\n if (response.ok) return;\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n throw new ManagerApiError(`update rejeitado (HTTP ${response.status})`, response.status);\n }\n retriable = new Error(`HTTP ${response.status}`);\n } catch (error) {\n if (error instanceof ManagerApiError) throw error;\n retriable = error;\n }\n\n const delay = RETRY_DELAYS_MS[attempt];\n if (delay === undefined) {\n throw new Error(`update da run ${runId} descartado após retries: ${String(retriable)}`);\n }\n this.logger.warn(`falha no update da run ${runId} (${String(retriable)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n }\n}\n","import type { ManagerRunError, ManagerRunUpdateRequest, RunLogEntry, RunLogLevel } from './protocol';\nimport type { RunContext } from './types';\nimport { ManagerApi, ManagerApiError } from './api';\nimport { nowISO, unrefTimer, type Logger } from '../utils';\n\nconst DEFAULT_LOG_FLUSH_INTERVAL_MS = 2_000;\nconst MAX_LOG_MESSAGE_CHARS = 10_000;\nconst MAX_LOGS_PER_RUN = 500;\nconst MAX_LOGS_PER_PATCH = 100;\nconst FLUSH_AT_BUFFERED = 20;\n\n/**\n * Reporter de uma run: bufferiza logs (flush incremental com throttle) e encadeia\n * todos os PATCHes numa fila única — a ordem running → logs → terminal é garantida.\n * Um 409/404 mata o reporter (run cancelada no app): o handler não pode ser morto,\n * mas todo reporte posterior é suprimido e ctx.signal dispara para abort cooperativo.\n */\nexport class RunReporter {\n readonly context: RunContext;\n\n private buffer: RunLogEntry[] = [];\n private loggedCount = 0;\n private droppedCount = 0;\n private dead = false;\n private chain: Promise<void> = Promise.resolve();\n private timer: ReturnType<typeof setTimeout> | undefined;\n private readonly abortController = new AbortController();\n private readonly flushIntervalMs: number;\n\n constructor(\n private readonly api: ManagerApi,\n private readonly runId: string,\n task: string,\n private readonly logger: Logger,\n flushIntervalMs?: number\n ) {\n this.flushIntervalMs = flushIntervalMs ?? DEFAULT_LOG_FLUSH_INTERVAL_MS;\n this.context = {\n runId,\n task,\n log: (level, message) => this.log(level, message),\n signal: this.abortController.signal,\n };\n }\n\n get isDead(): boolean {\n return this.dead;\n }\n\n /** Aborta o ctx.signal sem matar o reporter (timeout/shutdown ainda reportam o terminal). */\n abort(): void {\n if (!this.abortController.signal.aborted) this.abortController.abort();\n }\n\n private log(level: RunLogLevel, message: string): void {\n if (this.dead) return;\n if (this.loggedCount >= MAX_LOGS_PER_RUN) {\n this.droppedCount++;\n return;\n }\n this.loggedCount++;\n const truncated =\n message.length > MAX_LOG_MESSAGE_CHARS ? `${message.slice(0, MAX_LOG_MESSAGE_CHARS)}… [truncado]` : message;\n this.buffer.push({ ts: nowISO(), level, message: truncated });\n\n if (this.buffer.length >= FLUSH_AT_BUFFERED) {\n this.flushLogs();\n } else {\n this.scheduleFlush();\n }\n }\n\n private scheduleFlush(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n this.flushLogs();\n }, this.flushIntervalMs);\n unrefTimer(this.timer);\n }\n\n private clearFlushTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n }\n\n private takeLogs(): RunLogEntry[] {\n const logs = this.buffer.splice(0, this.buffer.length);\n if (this.droppedCount > 0) {\n logs.push({\n ts: nowISO(),\n level: 'warning',\n message: `${this.droppedCount} logs descartados (limite de ${MAX_LOGS_PER_RUN} por execução)`,\n });\n this.droppedCount = 0;\n }\n return logs;\n }\n\n /** Flush incremental: envia o buffer como status 'running' (em chunks). */\n private flushLogs(): void {\n this.clearFlushTimer();\n if (this.dead || this.buffer.length === 0) return;\n const logs = this.buffer.splice(0, this.buffer.length);\n for (let i = 0; i < logs.length; i += MAX_LOGS_PER_PATCH) {\n this.enqueue({ status: 'running', logs: logs.slice(i, i + MAX_LOGS_PER_PATCH) });\n }\n }\n\n /** Primeiro PATCH (claimed → running). Retorna false se a run já morreu (cancelada). */\n async reportRunning(): Promise<boolean> {\n this.enqueue({ status: 'running' });\n await this.chain;\n return !this.dead;\n }\n\n reportSuccess(): void {\n this.clearFlushTimer();\n this.enqueue({ status: 'succeeded', logs: this.takeLogs() });\n }\n\n reportFailure(error: ManagerRunError): void {\n this.clearFlushTimer();\n this.enqueue({ status: 'failed', error, logs: this.takeLogs() });\n }\n\n /** Aguarda a fila de PATCHes esvaziar (chame depois do terminal). */\n finalize(): Promise<void> {\n return this.chain;\n }\n\n private enqueue(update: ManagerRunUpdateRequest): void {\n if (this.dead) return;\n this.chain = this.chain.then(async () => {\n if (this.dead) return;\n const payload = update.logs && update.logs.length === 0 ? { ...update, logs: undefined } : update;\n try {\n await this.api.updateRun(this.runId, payload);\n } catch (error) {\n if (error instanceof ManagerApiError && (error.status === 409 || error.status === 404)) {\n this.dead = true;\n this.abort();\n this.buffer = [];\n this.logger.warn(`run ${this.runId} cancelada/removida no servidor — reporte suprimido`);\n return;\n }\n this.logger.error(`update da run ${this.runId} perdido:`, error);\n }\n });\n }\n}\n","import type { ManagerRunDescriptor, ManagerRunError } from './protocol';\nimport type { ManagerAgentOptions, ManagerTaskHandler } from './types';\nimport { ManagerApi, ManagerApiError } from './api';\nimport { RunReporter } from './context';\nimport { resolveConfig } from '../config';\nimport { isNode, makeLogger, sleep, SDK_VERSION, type Logger } from '../utils';\n\nconst DEFAULT_POLL_INTERVAL_MS = 5_000;\nconst MIN_POLL_INTERVAL_MS = 1_000;\nconst MAX_CONCURRENCY = 5;\nconst POLL_RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\nconst AUTH_FAILURE_INTERVAL_MS = 30_000;\n\ntype AgentState = 'idle' | 'started' | 'stopping';\n\n/** Hostname da máquina — telemetria (campo `host`), distinto da identidade do agente. */\nfunction hostname(): string | undefined {\n if (!isNode()) return undefined;\n return process.env.HOSTNAME || process.env.COMPUTERNAME || undefined;\n}\n\n/**\n * Loop de polling do Manager: busca runs pendentes, executa os handlers registrados\n * e reporta status/logs/result. Ao contrário do Monitor, o timer de polling NÃO é\n * unref'd — um agente iniciado mantém o processo vivo até stop().\n */\nexport class ManagerAgent {\n readonly logger: Logger;\n\n private readonly api: ManagerApi;\n private readonly pollIntervalMs: number;\n private readonly concurrency: number;\n private readonly instanceId: string;\n private readonly taskTimeoutMs?: number;\n private readonly logFlushIntervalMs?: number;\n\n private state: AgentState = 'idle';\n private timer: ReturnType<typeof setTimeout> | undefined;\n private pollAbort: AbortController | undefined;\n private consecutiveFailures = 0;\n private consecutiveAuthFailures = 0;\n private readonly activeRuns = new Set<Promise<void>>();\n private readonly reporters = new Set<RunReporter>();\n\n constructor(\n private readonly options: ManagerAgentOptions,\n private readonly registry: Map<string, ManagerTaskHandler>\n ) {\n this.logger = makeLogger(options.debug ?? false, '[hobots-manager]');\n const config = resolveConfig(options, '[hobots-manager]');\n this.api = new ManagerApi({ baseUrl: config.managerBaseUrl, key: config.key, logger: this.logger });\n this.pollIntervalMs = Math.max(MIN_POLL_INTERVAL_MS, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n this.concurrency = Math.min(MAX_CONCURRENCY, Math.max(1, options.concurrency ?? 1));\n this.instanceId = options.instanceId;\n this.taskTimeoutMs = options.taskTimeoutMs;\n this.logFlushIntervalMs = options.logFlushIntervalMs;\n this.logger.debug('agente configurado', { baseUrl: config.managerBaseUrl });\n }\n\n get activeCount(): number {\n return this.activeRuns.size;\n }\n\n start(): void {\n if (this.state === 'started') return;\n if (this.state === 'stopping') {\n throw new Error('[hobots-manager] start() chamado durante stop() — aguarde o stop terminar');\n }\n if (this.registry.size === 0) {\n throw new Error('[hobots-manager] nenhuma task registrada — chame register() antes de start()');\n }\n this.state = 'started';\n this.logger.debug(`polling iniciado (tasks: ${[...this.registry.keys()].join(', ')})`);\n this.schedule(0);\n }\n\n /** Para o polling e aguarda as runs ativas (até timeoutMs). Retorna true se tudo terminou a tempo. */\n async stop(timeoutMs = 30_000): Promise<boolean> {\n if (this.state === 'idle') return true;\n this.state = 'stopping';\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n this.pollAbort?.abort();\n\n const all = Promise.allSettled([...this.activeRuns]).then(() => true);\n const finished = timeoutMs > 0 ? await Promise.race([all, sleep(timeoutMs).then(() => false)]) : false;\n if (!finished && this.activeRuns.size > 0) {\n this.logger.warn(`${this.activeRuns.size} run(s) ainda em execução após ${timeoutMs}ms — abandonando a espera`);\n for (const reporter of this.reporters) reporter.abort();\n }\n this.state = 'idle';\n return finished;\n }\n\n /** Timer intencionalmente NÃO unref'd: o agente é a razão do processo existir. */\n private schedule(delayMs: number): void {\n if (this.state !== 'started' || this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n void this.tick();\n }, delayMs);\n }\n\n private async tick(): Promise<void> {\n if (this.state !== 'started') return;\n if (this.activeRuns.size >= this.concurrency) {\n this.schedule(this.pollIntervalMs);\n return;\n }\n\n this.pollAbort = new AbortController();\n try {\n const response = await this.api.poll(\n {\n agent: {\n // identidade canônica do agente no painel — o mesmo instanceId do\n // heartbeat do Monitor, então os dois canais convergem em um agente\n instance_id: this.instanceId,\n version: SDK_VERSION,\n host: hostname(),\n tasks: [...this.registry.keys()],\n },\n max: Math.min(MAX_CONCURRENCY, this.concurrency - this.activeRuns.size),\n tasks: [...this.registry.keys()],\n },\n this.pollAbort.signal\n );\n this.consecutiveFailures = 0;\n this.consecutiveAuthFailures = 0;\n\n for (const run of response.runs) {\n this.dispatch(run);\n }\n // com trabalho entregue, re-poll imediato (modo drain); sem trabalho, espera o intervalo\n this.schedule(response.runs.length > 0 ? 0 : this.pollIntervalMs);\n } catch (error) {\n if (this.state !== 'started') return; // stop() abortou o poll\n this.schedule(this.delayAfterPollError(error));\n } finally {\n this.pollAbort = undefined;\n }\n }\n\n private delayAfterPollError(error: unknown): number {\n if (error instanceof ManagerApiError && error.status === 401) {\n // chave desativada/rotacionada — continua tentando devagar (pode ser reativada)\n this.consecutiveAuthFailures++;\n if (this.consecutiveAuthFailures === 1 || this.consecutiveAuthFailures % 10 === 0) {\n this.logger.error('chave rejeitada (401) — verifique o Client Secret do projeto em Configurações → Projetos');\n }\n return Math.max(this.pollIntervalMs, AUTH_FAILURE_INTERVAL_MS);\n }\n this.consecutiveFailures++;\n const ladder = POLL_RETRY_DELAYS_MS[Math.min(this.consecutiveFailures - 1, POLL_RETRY_DELAYS_MS.length - 1)]!;\n const delay = Math.min(Math.max(ladder, 0), Math.max(this.pollIntervalMs, 16_000));\n this.logger.warn(`poll falhou (${String(error)}), próxima tentativa em ${delay}ms`);\n return delay;\n }\n\n private dispatch(run: ManagerRunDescriptor): void {\n const promise = this.executeRun(run)\n .catch(error => this.logger.error(`erro inesperado na run ${run.id}:`, error))\n .finally(() => {\n this.activeRuns.delete(promise);\n if (this.state === 'started') this.schedule(0);\n });\n this.activeRuns.add(promise);\n }\n\n private async executeRun(run: ManagerRunDescriptor): Promise<void> {\n const reporter = new RunReporter(this.api, run.id, run.task, this.logger, this.logFlushIntervalMs);\n this.reporters.add(reporter);\n try {\n const handler = this.registry.get(run.task);\n if (!handler) {\n // claim veio para uma task sem handler (corrida rara) — falha direto, sem 'running'\n reporter.reportFailure({\n type: 'HandlerNotFound',\n message: `tarefa não registrada no agente: ${run.task}`,\n });\n await reporter.finalize();\n return;\n }\n\n const ok = await reporter.reportRunning();\n if (!ok) {\n this.logger.debug(`run ${run.id} cancelada antes de iniciar — handler não executado`);\n return;\n }\n\n this.logger.debug(`executando run ${run.id} (${run.task})`);\n try {\n await this.invokeWithTimeout(handler, run, reporter);\n reporter.reportSuccess();\n this.logger.debug(`run ${run.id} concluída`);\n } catch (error) {\n reporter.reportFailure(toRunError(error));\n this.logger.debug(`run ${run.id} falhou: ${String(error)}`);\n }\n await reporter.finalize();\n } finally {\n this.reporters.delete(reporter);\n }\n }\n\n private async invokeWithTimeout(\n handler: ManagerTaskHandler,\n run: ManagerRunDescriptor,\n reporter: RunReporter\n ): Promise<void> {\n const invocation = Promise.resolve().then(() => handler(run.params, reporter.context));\n if (!this.taskTimeoutMs || this.taskTimeoutMs <= 0) {\n await invocation;\n return;\n }\n\n const timeoutMs = this.taskTimeoutMs;\n const timeout = sleep(timeoutMs).then(() => TIMEOUT_SENTINEL);\n const outcome = await Promise.race([invocation, timeout]);\n if (outcome !== TIMEOUT_SENTINEL) return;\n\n // não dá para matar o código do usuário — reporta, aborta o signal e libera o slot\n reporter.abort();\n invocation\n .then(() => this.logger.warn(`run ${run.id} terminou depois do timeout de ${timeoutMs}ms`))\n .catch(() => this.logger.warn(`run ${run.id} falhou depois do timeout de ${timeoutMs}ms (erro descartado)`));\n throw Object.assign(new Error(`timeout após ${timeoutMs}ms (o handler pode continuar em background)`), {\n name: 'TaskTimeout',\n });\n }\n}\n\nconst TIMEOUT_SENTINEL = Symbol('task-timeout');\n\nconst MAX_ERROR_MESSAGE_CHARS = 10_000;\nconst MAX_ERROR_STACK_CHARS = 20_000;\n\nfunction truncate(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max)}… [truncado]` : value;\n}\n\nfunction toRunError(error: unknown): ManagerRunError {\n if (error instanceof Error) {\n return {\n type: error.name,\n message: truncate(error.message, MAX_ERROR_MESSAGE_CHARS),\n stack: error.stack ? truncate(error.stack, MAX_ERROR_STACK_CHARS) : undefined,\n };\n }\n return { message: truncate(String(error), MAX_ERROR_MESSAGE_CHARS) };\n}\n","import type { EventUser, Severity } from './protocol';\nimport type { CaptureHint, InitOptions } from './types';\nimport { Client } from './client';\nimport { Heartbeat } from './heartbeat';\nimport { installGlobalHandlers } from './instrument';\nimport { Scope, type BreadcrumbInput } from './scope';\nimport { Transaction } from './transaction';\nimport { sendCheckIn, withMonitorImpl, type CheckInOptions, type WithMonitorOptions } from './checkin';\nimport { ManagerAgent } from './manager/agent';\nimport type { ManagerTaskHandler } from './manager/types';\n\nconst DEFAULT_MAX_BREADCRUMBS = 100;\n\nlet client: Client | undefined;\nlet scope = new Scope();\nlet heartbeat: Heartbeat | undefined;\nlet agent: ManagerAgent | undefined;\nconst registry = new Map<string, ManagerTaskHandler>();\nlet warnedManagerDisabled = false;\n\n/** Inicializa o SDK. Chame uma vez, o mais cedo possível no programa. */\nexport function init(options: InitOptions): void {\n if (client) {\n client.logger.warn('init() chamado mais de uma vez — substituindo o client anterior');\n heartbeat?.stop();\n heartbeat = undefined;\n }\n if (agent) {\n void agent.stop(0);\n agent = undefined;\n }\n warnedManagerDisabled = false;\n\n client = new Client(options);\n\n if (options.captureUnhandled !== false) {\n installGlobalHandlers(client, () => scope);\n }\n\n if (options.heartbeat) {\n const heartbeatOptions = options.heartbeat === true ? {} : options.heartbeat;\n heartbeat = new Heartbeat(client, heartbeatOptions, options.instanceId);\n heartbeat.start();\n }\n\n if (options.manager) {\n const managerOptions = options.manager === true ? {} : options.manager;\n agent = new ManagerAgent(\n { ...managerOptions, clientSecret: options.clientSecret, instanceId: options.instanceId, debug: options.debug },\n registry\n );\n }\n\n client.logger.debug('inicializado', { endpoint: client.config.ingestEndpoint });\n}\n\nexport function getClient(): Client | undefined {\n return client;\n}\n\n/** Captura uma exceção e retorna o event_id (undefined se o SDK não foi inicializado). */\nexport function captureException(error: unknown, hint?: CaptureHint): string | undefined {\n return client?.captureException(error, hint, scope);\n}\n\nexport function captureMessage(message: string, level: Severity = 'info', hint?: CaptureHint): string | undefined {\n return client?.captureMessage(message, level, hint, scope);\n}\n\n/** Registra um breadcrumb — anexado aos próximos eventos como trilha do que aconteceu antes. */\nexport function addBreadcrumb(crumb: BreadcrumbInput): void {\n scope.addBreadcrumb(crumb, client?.options.maxBreadcrumbs ?? DEFAULT_MAX_BREADCRUMBS);\n}\n\nexport function setTag(key: string, value: string): void {\n scope.setTag(key, value);\n}\n\nexport function setTags(tags: Record<string, string>): void {\n scope.setTags(tags);\n}\n\nexport function setUser(user: EventUser | null): void {\n scope.setUser(user);\n}\n\nexport function setContext(name: string, context: Record<string, unknown> | null): void {\n scope.setContext(name, context);\n}\n\nexport function setExtra(key: string, value: unknown): void {\n scope.setExtra(key, value);\n}\n\n/** Executa o callback com uma cópia isolada do scope (alterações não vazam para fora). */\nexport function withScope<T>(callback: (scope: Scope) => T): T {\n const previous = scope;\n scope = previous.clone();\n try {\n return callback(scope);\n } finally {\n scope = previous;\n }\n}\n\n/** Inicia uma transaction de performance. Chame .finish() para enviá-la. */\nexport function startTransaction(name: string, op?: string): Transaction {\n const rate = client?.options.tracesSampleRate ?? 1;\n const sampled = rate >= 1 || Math.random() < rate;\n return new Transaction(client, name, op, sampled);\n}\n\n/** Check-in manual de um monitor cron. Retorna o check_in_id para fechar a execução depois. */\nexport function checkIn(options: CheckInOptions): string | undefined {\n return client ? sendCheckIn(client, options) : undefined;\n}\n\n/** Envolve um job monitorado: envia in_progress → ok/error com duração e captura a exceção em caso de falha. */\nexport async function withMonitor<T>(\n monitorSlug: string,\n fn: () => T | Promise<T>,\n options?: WithMonitorOptions\n): Promise<T> {\n if (!client) return fn();\n return withMonitorImpl(\n client,\n error => captureException(error, { tags: { monitor: monitorSlug } }),\n monitorSlug,\n fn,\n options\n );\n}\n\n/** Aguarda o envio de tudo que está na fila (até timeoutMs). */\nexport function flush(timeoutMs?: number): Promise<boolean> {\n return client ? client.flush(timeoutMs) : Promise.resolve(true);\n}\n\n/** Registra o handler de uma task do Manager (o task_slug configurado no formulário do app). */\nexport function register<P = Record<string, unknown>>(task: string, handler: ManagerTaskHandler<P>): void {\n if (registry.has(task)) {\n (agent?.logger ?? client?.logger)?.warn(`register('${task}') sobrescreveu um handler existente`);\n }\n if (client && !agent && !warnedManagerDisabled) {\n warnedManagerDisabled = true;\n client.logger.warn(\n `register('${task}') com o Manager desabilitado — passe manager: true (ou opções) no init()`\n );\n }\n registry.set(task, handler as ManagerTaskHandler);\n}\n\n/**\n * Inicia o polling do Manager. O timer NÃO é unref'd: o processo fica vivo\n * aguardando trabalho até stop()/close() — o inverso deliberado do Monitor.\n */\nexport function start(): void {\n if (!agent) {\n throw new Error('[hobots] Manager não configurado — passe manager: true (ou opções) no init() antes de start()');\n }\n agent.start();\n}\n\n/** Para só o Manager: encerra o polling e aguarda as runs ativas (até timeoutMs). A telemetria continua. */\nexport function stop(timeoutMs?: number): Promise<boolean> {\n return agent ? agent.stop(timeoutMs) : Promise.resolve(true);\n}\n\n/**\n * Encerra tudo: para o Manager (aguardando runs em voo), o heartbeat e faz o\n * flush final do transport. Chame antes do processo terminar.\n */\nexport async function close(timeoutMs?: number): Promise<boolean> {\n const agentStopped = agent ? await agent.stop(timeoutMs) : true;\n heartbeat?.stop();\n heartbeat = undefined;\n const clientClosed = client ? await client.close(timeoutMs) : true;\n return agentStopped && clientClosed;\n}\n"],"mappings":"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","names":["scope","client","client","client","client","RETRY_DELAYS_MS","registry"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -21,8 +21,6 @@ interface ManagerOptions {
|
|
|
21
21
|
interface ManagerAgentOptions extends ManagerOptions {
|
|
22
22
|
/** O Client Secret do projeto — o mesmo do Monitor */
|
|
23
23
|
clientSecret: string;
|
|
24
|
-
/** Host do app Hobots — o mesmo do Monitor */
|
|
25
|
-
baseUrl?: string;
|
|
26
24
|
/** Identidade do agente no dashboard — o instanceId do init */
|
|
27
25
|
instanceId: string;
|
|
28
26
|
/** Loga atividade do SDK no console */
|
|
@@ -49,8 +47,6 @@ interface HeartbeatOptions {
|
|
|
49
47
|
interface InitOptions {
|
|
50
48
|
/** O Client Secret do projeto (hb_…) — a mesma credencial para Monitor e Manager. Copie em Configurações → Projetos. */
|
|
51
49
|
clientSecret: string;
|
|
52
|
-
/** Host do app Hobots. Default: 'https://app.hobots.app' — sobrescreva apenas em desenvolvimento (ex.: http://localhost:3002) */
|
|
53
|
-
baseUrl?: string;
|
|
54
50
|
/** Default: 'production' */
|
|
55
51
|
environment?: string;
|
|
56
52
|
/** Versão do programa, ex.: 'robo-nfe@1.4.2' */
|
|
@@ -90,22 +86,21 @@ interface CaptureHint {
|
|
|
90
86
|
fingerprint?: string[];
|
|
91
87
|
}
|
|
92
88
|
|
|
93
|
-
/**
|
|
94
|
-
declare const DEFAULT_BASE_URL = "https://
|
|
89
|
+
/** API oficial da Hobots — o SDK sempre fala com ela em produção. */
|
|
90
|
+
declare const DEFAULT_BASE_URL = "https://api2.hobots.app";
|
|
95
91
|
interface ResolvedConfig {
|
|
96
92
|
/** Client Secret do projeto (enviado como Authorization: Bearer, nunca na URL) */
|
|
97
93
|
key: string;
|
|
98
94
|
baseUrl: string;
|
|
99
|
-
/** Ingestão do Monitor: <baseUrl>/
|
|
95
|
+
/** Ingestão do Monitor: <baseUrl>/v1/ingest */
|
|
100
96
|
ingestEndpoint: string;
|
|
101
|
-
/** API do Manager: <baseUrl>/
|
|
97
|
+
/** API do Manager: <baseUrl>/v1/manager */
|
|
102
98
|
managerBaseUrl: string;
|
|
103
99
|
}
|
|
104
100
|
interface ConfigInput {
|
|
105
101
|
clientSecret: string;
|
|
106
|
-
baseUrl?: string;
|
|
107
102
|
}
|
|
108
|
-
/** Resolve clientSecret
|
|
103
|
+
/** Resolve o clientSecret nos endpoints do Monitor e do Manager. */
|
|
109
104
|
declare function resolveConfig(options: ConfigInput, prefix?: string): ResolvedConfig;
|
|
110
105
|
|
|
111
106
|
type BreadcrumbInput = Omit<Breadcrumb, 'timestamp'> & {
|
package/dist/index.d.ts
CHANGED
|
@@ -21,8 +21,6 @@ interface ManagerOptions {
|
|
|
21
21
|
interface ManagerAgentOptions extends ManagerOptions {
|
|
22
22
|
/** O Client Secret do projeto — o mesmo do Monitor */
|
|
23
23
|
clientSecret: string;
|
|
24
|
-
/** Host do app Hobots — o mesmo do Monitor */
|
|
25
|
-
baseUrl?: string;
|
|
26
24
|
/** Identidade do agente no dashboard — o instanceId do init */
|
|
27
25
|
instanceId: string;
|
|
28
26
|
/** Loga atividade do SDK no console */
|
|
@@ -49,8 +47,6 @@ interface HeartbeatOptions {
|
|
|
49
47
|
interface InitOptions {
|
|
50
48
|
/** O Client Secret do projeto (hb_…) — a mesma credencial para Monitor e Manager. Copie em Configurações → Projetos. */
|
|
51
49
|
clientSecret: string;
|
|
52
|
-
/** Host do app Hobots. Default: 'https://app.hobots.app' — sobrescreva apenas em desenvolvimento (ex.: http://localhost:3002) */
|
|
53
|
-
baseUrl?: string;
|
|
54
50
|
/** Default: 'production' */
|
|
55
51
|
environment?: string;
|
|
56
52
|
/** Versão do programa, ex.: 'robo-nfe@1.4.2' */
|
|
@@ -90,22 +86,21 @@ interface CaptureHint {
|
|
|
90
86
|
fingerprint?: string[];
|
|
91
87
|
}
|
|
92
88
|
|
|
93
|
-
/**
|
|
94
|
-
declare const DEFAULT_BASE_URL = "https://
|
|
89
|
+
/** API oficial da Hobots — o SDK sempre fala com ela em produção. */
|
|
90
|
+
declare const DEFAULT_BASE_URL = "https://api2.hobots.app";
|
|
95
91
|
interface ResolvedConfig {
|
|
96
92
|
/** Client Secret do projeto (enviado como Authorization: Bearer, nunca na URL) */
|
|
97
93
|
key: string;
|
|
98
94
|
baseUrl: string;
|
|
99
|
-
/** Ingestão do Monitor: <baseUrl>/
|
|
95
|
+
/** Ingestão do Monitor: <baseUrl>/v1/ingest */
|
|
100
96
|
ingestEndpoint: string;
|
|
101
|
-
/** API do Manager: <baseUrl>/
|
|
97
|
+
/** API do Manager: <baseUrl>/v1/manager */
|
|
102
98
|
managerBaseUrl: string;
|
|
103
99
|
}
|
|
104
100
|
interface ConfigInput {
|
|
105
101
|
clientSecret: string;
|
|
106
|
-
baseUrl?: string;
|
|
107
102
|
}
|
|
108
|
-
/** Resolve clientSecret
|
|
103
|
+
/** Resolve o clientSecret nos endpoints do Monitor e do Manager. */
|
|
109
104
|
declare function resolveConfig(options: ConfigInput, prefix?: string): ResolvedConfig;
|
|
110
105
|
|
|
111
106
|
type BreadcrumbInput = Omit<Breadcrumb, 'timestamp'> & {
|
package/dist/index.js
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
|
-
var DEFAULT_BASE_URL = "https://
|
|
2
|
+
var DEFAULT_BASE_URL = "https://api2.hobots.app";
|
|
3
|
+
function envBaseUrl() {
|
|
4
|
+
if (typeof process === "undefined" || !process.env) return void 0;
|
|
5
|
+
return process.env.HOBOTS_API_URL?.trim() || void 0;
|
|
6
|
+
}
|
|
3
7
|
function resolveConfig(options, prefix = "[hobots]") {
|
|
4
8
|
const key = options.clientSecret?.trim();
|
|
5
9
|
if (!key) {
|
|
6
10
|
throw new Error(`${prefix} clientSecret ausente \u2014 copie o Client Secret do projeto em Configura\xE7\xF5es \u2192 Projetos`);
|
|
7
11
|
}
|
|
8
|
-
const baseUrl = (
|
|
12
|
+
const baseUrl = (envBaseUrl() ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
9
13
|
try {
|
|
10
14
|
new URL(baseUrl);
|
|
11
15
|
} catch {
|
|
12
|
-
throw new Error(`${prefix}
|
|
16
|
+
throw new Error(`${prefix} HOBOTS_API_URL inv\xE1lida: "${baseUrl}" \u2014 esperado ex.: http://localhost:3001`);
|
|
13
17
|
}
|
|
14
18
|
return {
|
|
15
19
|
key,
|
|
16
20
|
baseUrl,
|
|
17
|
-
ingestEndpoint: `${baseUrl}/
|
|
18
|
-
managerBaseUrl: `${baseUrl}/
|
|
21
|
+
ingestEndpoint: `${baseUrl}/v1/ingest`,
|
|
22
|
+
managerBaseUrl: `${baseUrl}/v1/manager`
|
|
19
23
|
};
|
|
20
24
|
}
|
|
21
25
|
|
|
@@ -1052,7 +1056,7 @@ function init(options) {
|
|
|
1052
1056
|
if (options.manager) {
|
|
1053
1057
|
const managerOptions = options.manager === true ? {} : options.manager;
|
|
1054
1058
|
agent = new ManagerAgent(
|
|
1055
|
-
{ ...managerOptions, clientSecret: options.clientSecret,
|
|
1059
|
+
{ ...managerOptions, clientSecret: options.clientSecret, instanceId: options.instanceId, debug: options.debug },
|
|
1056
1060
|
registry
|
|
1057
1061
|
);
|
|
1058
1062
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/stacktrace.ts","../src/utils.ts","../src/eventbuilder.ts","../src/transport.ts","../src/client.ts","../src/heartbeat.ts","../src/instrument.ts","../src/scope.ts","../src/transaction.ts","../src/checkin.ts","../src/manager/api.ts","../src/manager/context.ts","../src/manager/agent.ts","../src/core.ts"],"sourcesContent":["/** Host SaaS da Hobots — o SDK sempre fala com ele, salvo override de baseUrl (dev). */\nexport const DEFAULT_BASE_URL = 'https://app.hobots.app';\n\nexport interface ResolvedConfig {\n /** Client Secret do projeto (enviado como Authorization: Bearer, nunca na URL) */\n key: string;\n baseUrl: string;\n /** Ingestão do Monitor: <baseUrl>/api/ingest */\n ingestEndpoint: string;\n /** API do Manager: <baseUrl>/api/manager */\n managerBaseUrl: string;\n}\n\ninterface ConfigInput {\n clientSecret: string;\n baseUrl?: string;\n}\n\n/** Resolve clientSecret + baseUrl nos endpoints do Monitor e do Manager. */\nexport function resolveConfig(options: ConfigInput, prefix = '[hobots]'): ResolvedConfig {\n const key = options.clientSecret?.trim();\n if (!key) {\n throw new Error(`${prefix} clientSecret ausente — copie o Client Secret do projeto em Configurações → Projetos`);\n }\n\n const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n try {\n new URL(baseUrl);\n } catch {\n throw new Error(`${prefix} baseUrl inválida: \"${baseUrl}\" — esperado ex.: https://app.hobots.app`);\n }\n\n return {\n key,\n baseUrl,\n ingestEndpoint: `${baseUrl}/api/ingest`,\n managerBaseUrl: `${baseUrl}/api/manager`,\n };\n}\n","import type { StackFrame } from './protocol';\n\nconst MAX_FRAMES = 50;\n\n// \" at fn (file:1:2)\" | \" at file:1:2\" | \" at async fn (file:1:2)\"\nconst FRAME_RE = /^\\s*at\\s+(?:async\\s+)?(?:(.+?)\\s+\\()?(.+?)\\)?$/;\nconst LOCATION_RE = /^(.*?):(\\d+):(\\d+)$/;\n\nfunction isInApp(filename: string | undefined): boolean {\n if (!filename) return false;\n if (filename.startsWith('node:')) return false;\n if (filename.startsWith('internal/')) return false;\n if (filename.includes('node_modules')) return false;\n if (filename === '<anonymous>') return false;\n return true;\n}\n\n/** Converte um `error.stack` do V8 em frames (ordem innermost-first, como o V8 imprime). */\nexport function parseStacktrace(stack: string | undefined | null): StackFrame[] {\n if (!stack) return [];\n\n const frames: StackFrame[] = [];\n for (const line of stack.split('\\n')) {\n if (frames.length >= MAX_FRAMES) break;\n const match = FRAME_RE.exec(line);\n if (!match || !line.trimStart().startsWith('at ')) continue;\n\n const [, fn, location] = match;\n const loc = LOCATION_RE.exec(location ?? '');\n const filename = loc ? loc[1] : location;\n frames.push({\n function: fn || '<anonymous>',\n filename: filename || undefined,\n lineno: loc?.[2] ? Number(loc[2]) : undefined,\n colno: loc?.[3] ? Number(loc[3]) : undefined,\n in_app: isInApp(filename),\n });\n }\n return frames;\n}\n","export const SDK_NAME = 'hobots';\nexport const SDK_VERSION = '1.0.0';\n\nexport function isNode(): boolean {\n return typeof process !== 'undefined' && typeof process.versions?.node === 'string';\n}\n\n/** uuid v4 sem hífens (32 hex). Fallback para contextos sem crypto.randomUUID. */\nexport function uuid4(): string {\n const cryptoRef = (globalThis as { crypto?: Crypto }).crypto;\n if (cryptoRef && typeof cryptoRef.randomUUID === 'function') {\n return cryptoRef.randomUUID().replace(/-/g, '');\n }\n let out = '';\n for (let i = 0; i < 32; i++) {\n out += Math.floor(Math.random() * 16).toString(16);\n }\n return out;\n}\n\nexport function nowISO(): string {\n return new Date().toISOString();\n}\n\n/** Timers não devem segurar o processo Node aberto. */\nexport function unrefTimer(timer: unknown): void {\n (timer as { unref?: () => void } | undefined)?.unref?.();\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, ms);\n unrefTimer(timer);\n });\n}\n\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\nconst PREFIX = '[hobots-monitor]';\n\nexport function makeLogger(enabled: boolean, prefix: string = PREFIX): Logger {\n return {\n debug: (...args) => enabled && console.debug(prefix, ...args),\n warn: (...args) => enabled && console.warn(prefix, ...args),\n error: (...args) => console.error(prefix, ...args),\n };\n}\n","import type { EventPayload, Severity } from './protocol';\nimport { parseStacktrace } from './stacktrace';\nimport { nowISO, uuid4 } from './utils';\n\nfunction safeString(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n const json = JSON.stringify(value);\n if (json && json !== '{}') return json;\n } catch {\n // objetos circulares etc. caem no String()\n }\n return String(value);\n}\n\nexport function eventFromException(error: unknown, level: Severity = 'error'): EventPayload {\n let type: string;\n let value: string;\n let frames = [] as ReturnType<typeof parseStacktrace>;\n\n if (error instanceof Error) {\n type = error.name || 'Error';\n value = error.message;\n frames = parseStacktrace(error.stack);\n } else {\n type = 'NonError';\n value = safeString(error);\n }\n\n return {\n event_id: uuid4(),\n timestamp: nowISO(),\n level,\n exception: {\n type,\n value,\n ...(frames.length > 0 ? { stacktrace: { frames } } : {}),\n },\n };\n}\n\nexport function eventFromMessage(message: string, level: Severity = 'info'): EventPayload {\n return {\n event_id: uuid4(),\n timestamp: nowISO(),\n level,\n message,\n };\n}\n","import type { Envelope, EnvelopeItem } from './protocol';\nimport { SDK_NAME, SDK_VERSION, nowISO, sleep, unrefTimer, type Logger } from './utils';\n\nconst RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\nconst DEFAULT_FLUSH_INTERVAL_MS = 2_000;\nconst DEFAULT_MAX_BATCH_SIZE = 10;\nconst DEFAULT_MAX_QUEUE_SIZE = 200;\n\nexport interface TransportOptions {\n endpoint: string;\n /** Chave secreta do projeto — enviada como Authorization: Bearer */\n key: string;\n logger: Logger;\n flushIntervalMs?: number;\n maxBatchSize?: number;\n maxQueueSize?: number;\n}\n\n/** Fila em memória com batch + retry. Envia envelopes via fetch (Node 18+/browser). */\nexport class Transport {\n private readonly endpoint: string;\n private readonly key: string;\n private readonly logger: Logger;\n private readonly flushIntervalMs: number;\n private readonly maxBatchSize: number;\n private readonly maxQueueSize: number;\n\n private buffer: EnvelopeItem[] = [];\n private timer: ReturnType<typeof setTimeout> | undefined;\n private pending = new Set<Promise<void>>();\n private closed = false;\n\n constructor(options: TransportOptions) {\n this.endpoint = options.endpoint;\n this.key = options.key;\n this.logger = options.logger;\n this.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.maxBatchSize = options.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;\n this.maxQueueSize = options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n }\n\n enqueue(item: EnvelopeItem): void {\n if (this.closed) {\n this.logger.warn('transport fechado, item descartado:', item.type);\n return;\n }\n if (this.buffer.length >= this.maxQueueSize) {\n this.buffer.shift();\n this.logger.warn('fila cheia, item mais antigo descartado');\n }\n this.buffer.push(item);\n\n if (this.buffer.length >= this.maxBatchSize) {\n void this.flushBuffer();\n } else {\n this.schedule();\n }\n }\n\n private schedule(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n void this.flushBuffer();\n }, this.flushIntervalMs);\n unrefTimer(this.timer);\n }\n\n private flushBuffer(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n if (this.buffer.length === 0) return Promise.resolve();\n\n const items = this.buffer.splice(0, this.buffer.length);\n const envelope: Envelope = {\n sdk: { name: SDK_NAME, version: SDK_VERSION },\n sent_at: nowISO(),\n items,\n };\n\n const request: Promise<void> = this.sendWithRetry(envelope).finally(() => {\n this.pending.delete(request);\n });\n this.pending.add(request);\n return request;\n }\n\n private async sendWithRetry(envelope: Envelope): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${this.key}` },\n body: JSON.stringify(envelope),\n });\n if (response.ok) {\n this.logger.debug(`envelope enviado (${envelope.items.length} itens)`);\n return;\n }\n // 4xx (exceto 429) não é recuperável — descarta sem retry\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n this.logger.error(`envelope rejeitado (HTTP ${response.status}), descartado`);\n return;\n }\n throw new Error(`HTTP ${response.status}`);\n } catch (error) {\n const delay = RETRY_DELAYS_MS[attempt];\n if (delay === undefined) {\n this.logger.error('envelope descartado após retries:', error);\n return;\n }\n this.logger.warn(`falha no envio (${String(error)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n }\n }\n\n /** Envia o que estiver na fila e aguarda envios em andamento (até timeoutMs). */\n async flush(timeoutMs = 5_000): Promise<boolean> {\n void this.flushBuffer();\n const all = Promise.allSettled([...this.pending]).then(() => true);\n return Promise.race([all, sleep(timeoutMs).then(() => false)]);\n }\n\n async close(timeoutMs = 5_000): Promise<boolean> {\n const result = await this.flush(timeoutMs);\n this.closed = true;\n return result;\n }\n}\n","import type { CheckInPayload, EventPayload, HeartbeatPayload, Severity, TransactionPayload } from './protocol';\nimport type { CaptureHint, InitOptions } from './types';\nimport { resolveConfig, type ResolvedConfig } from './config';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport type { Scope } from './scope';\nimport { Transport } from './transport';\nimport { isNode, makeLogger, type Logger } from './utils';\n\nfunction runtimeContexts(): Record<string, Record<string, unknown>> {\n if (isNode()) {\n return {\n runtime: { name: 'node', version: process.version },\n os: { name: process.platform, arch: process.arch },\n };\n }\n return { runtime: { name: 'browser' } };\n}\n\nexport class Client {\n readonly options: InitOptions;\n readonly config: ResolvedConfig;\n readonly logger: Logger;\n private readonly transport: Transport;\n\n constructor(options: InitOptions) {\n this.options = options;\n this.logger = makeLogger(!!options.debug);\n this.config = resolveConfig(options);\n this.transport = new Transport({\n endpoint: this.config.ingestEndpoint,\n key: this.config.key,\n logger: this.logger,\n flushIntervalMs: options.flushIntervalMs,\n maxBatchSize: options.maxBatchSize,\n });\n }\n\n captureException(error: unknown, hint: CaptureHint | undefined, scope: Scope): string {\n return this.captureEvent(eventFromException(error, hint?.level ?? 'error'), hint, scope);\n }\n\n captureMessage(message: string, level: Severity, hint: CaptureHint | undefined, scope: Scope): string {\n return this.captureEvent(eventFromMessage(message, level), hint, scope);\n }\n\n captureEvent(event: EventPayload, hint: CaptureHint | undefined, scope: Scope): string {\n const sampleRate = this.options.sampleRate ?? 1;\n if (sampleRate < 1 && Math.random() >= sampleRate) {\n this.logger.debug('evento descartado por sampleRate');\n return event.event_id;\n }\n\n const prepared = this.prepareEvent(event, hint, scope);\n const final = this.options.beforeSend ? this.options.beforeSend(prepared) : prepared;\n if (!final) {\n this.logger.debug('evento descartado por beforeSend');\n return event.event_id;\n }\n\n this.transport.enqueue({ type: 'event', payload: final });\n return final.event_id;\n }\n\n private prepareEvent(event: EventPayload, hint: CaptureHint | undefined, scope: Scope): EventPayload {\n const tags = { ...this.options.tags, ...scope.tags, ...event.tags, ...hint?.tags };\n const extra = { ...scope.extra, ...event.extra, ...hint?.extra };\n\n return {\n ...event,\n level: hint?.level ?? event.level ?? scope.level ?? 'error',\n release: event.release ?? this.options.release,\n environment: event.environment ?? this.options.environment ?? 'production',\n tags: Object.keys(tags).length > 0 ? tags : undefined,\n extra: Object.keys(extra).length > 0 ? extra : undefined,\n user: event.user ?? scope.user,\n contexts: { ...runtimeContexts(), ...scope.contexts, ...event.contexts },\n breadcrumbs: scope.breadcrumbs.length > 0 ? [...scope.breadcrumbs] : event.breadcrumbs,\n fingerprint: hint?.fingerprint ?? event.fingerprint ?? scope.fingerprint,\n };\n }\n\n sendTransaction(payload: TransactionPayload): void {\n this.transport.enqueue({\n type: 'transaction',\n payload: {\n ...payload,\n release: payload.release ?? this.options.release,\n environment: payload.environment ?? this.options.environment ?? 'production',\n tags: { ...this.options.tags, ...payload.tags },\n },\n });\n }\n\n sendCheckIn(payload: CheckInPayload): void {\n this.transport.enqueue({\n type: 'check_in',\n payload: {\n ...payload,\n release: payload.release ?? this.options.release,\n environment: payload.environment ?? this.options.environment ?? 'production',\n },\n });\n }\n\n sendHeartbeat(payload: HeartbeatPayload): void {\n this.transport.enqueue({\n type: 'heartbeat',\n payload: { ...payload, release: payload.release ?? this.options.release },\n });\n }\n\n flush(timeoutMs?: number): Promise<boolean> {\n return this.transport.flush(timeoutMs);\n }\n\n close(timeoutMs?: number): Promise<boolean> {\n return this.transport.close(timeoutMs);\n }\n}\n","import type { Client } from './client';\nimport type { HeartbeatOptions } from './types';\nimport { nowISO, unrefTimer } from './utils';\n\nconst DEFAULT_INTERVAL_MS = 30_000;\n\n/** Batimento periódico \"estou vivo\" — o servidor marca a instância offline quando ele para. */\nexport class Heartbeat {\n private readonly intervalMs: number;\n private readonly instanceId: string;\n private readonly name: string;\n private readonly metadata?: Record<string, unknown>;\n private timer: ReturnType<typeof setInterval> | undefined;\n\n constructor(\n private readonly client: Client,\n options: HeartbeatOptions = {},\n instanceId: string\n ) {\n this.intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;\n this.instanceId = instanceId;\n this.name = options.name ?? instanceId;\n this.metadata = options.metadata;\n }\n\n start(): void {\n if (this.timer) return;\n this.beat();\n this.timer = setInterval(() => this.beat(), this.intervalMs);\n unrefTimer(this.timer);\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n private beat(): void {\n this.client.sendHeartbeat({\n instance_id: this.instanceId,\n name: this.name,\n interval_ms: this.intervalMs,\n timestamp: nowISO(),\n metadata: this.metadata,\n });\n }\n}\n","import type { Client } from './client';\nimport type { Scope } from './scope';\nimport { isNode } from './utils';\n\nlet installed = false;\n\n/**\n * Registra handlers globais de erro.\n * Node: preserva a semântica padrão — após capturar e flushar um uncaughtException,\n * o processo encerra com código 1 (a menos que o programa tenha handler próprio).\n */\nexport function installGlobalHandlers(client: Client, getScope: () => Scope): void {\n if (installed) return;\n installed = true;\n\n if (isNode()) {\n process.on('uncaughtException', (error: Error) => {\n client.captureException(error, { level: 'fatal', tags: { mechanism: 'uncaughtException' } }, getScope());\n void client.flush(2_000).then(() => {\n if (process.listenerCount('uncaughtException') <= 1) {\n console.error(error);\n process.exit(1);\n }\n });\n });\n\n process.on('unhandledRejection', (reason: unknown) => {\n client.captureException(reason, { level: 'error', tags: { mechanism: 'unhandledRejection' } }, getScope());\n // fetch em andamento segura o processo aberto até o envio terminar\n void client.flush(2_000);\n });\n\n // rede de segurança: envia o que restou na fila quando o event loop esvazia\n process.on('beforeExit', () => {\n void client.flush(2_000);\n });\n return;\n }\n\n if (typeof window !== 'undefined') {\n window.addEventListener('error', event => {\n client.captureException(event.error ?? event.message, { tags: { mechanism: 'onerror' } }, getScope());\n });\n window.addEventListener('unhandledrejection', event => {\n client.captureException(event.reason, { tags: { mechanism: 'onunhandledrejection' } }, getScope());\n });\n window.addEventListener('pagehide', () => {\n void client.flush(1_000);\n });\n }\n}\n\n/** Apenas para testes internos. */\nexport function resetGlobalHandlersForTesting(): void {\n installed = false;\n}\n","import type { Breadcrumb, EventUser, Severity } from './protocol';\nimport { nowISO } from './utils';\n\nexport type BreadcrumbInput = Omit<Breadcrumb, 'timestamp'> & { timestamp?: string };\n\n/** Estado contextual anexado aos eventos: tags, usuário, contexts, extras e breadcrumbs. */\nexport class Scope {\n tags: Record<string, string> = {};\n user?: EventUser;\n contexts: Record<string, Record<string, unknown>> = {};\n extra: Record<string, unknown> = {};\n level?: Severity;\n fingerprint?: string[];\n breadcrumbs: Breadcrumb[] = [];\n\n setTag(key: string, value: string): this {\n this.tags[key] = value;\n return this;\n }\n\n setTags(tags: Record<string, string>): this {\n Object.assign(this.tags, tags);\n return this;\n }\n\n setUser(user: EventUser | null): this {\n this.user = user ?? undefined;\n return this;\n }\n\n setContext(name: string, context: Record<string, unknown> | null): this {\n if (context === null) {\n delete this.contexts[name];\n } else {\n this.contexts[name] = context;\n }\n return this;\n }\n\n setExtra(key: string, value: unknown): this {\n this.extra[key] = value;\n return this;\n }\n\n setExtras(extras: Record<string, unknown>): this {\n Object.assign(this.extra, extras);\n return this;\n }\n\n setLevel(level: Severity): this {\n this.level = level;\n return this;\n }\n\n setFingerprint(fingerprint: string[]): this {\n this.fingerprint = fingerprint;\n return this;\n }\n\n addBreadcrumb(crumb: BreadcrumbInput, maxBreadcrumbs: number): this {\n this.breadcrumbs.push({ timestamp: nowISO(), ...crumb });\n if (this.breadcrumbs.length > maxBreadcrumbs) {\n this.breadcrumbs.splice(0, this.breadcrumbs.length - maxBreadcrumbs);\n }\n return this;\n }\n\n clearBreadcrumbs(): this {\n this.breadcrumbs = [];\n return this;\n }\n\n clone(): Scope {\n const next = new Scope();\n next.tags = { ...this.tags };\n next.user = this.user ? { ...this.user } : undefined;\n next.contexts = Object.fromEntries(Object.entries(this.contexts).map(([k, v]) => [k, { ...v }]));\n next.extra = { ...this.extra };\n next.level = this.level;\n next.fingerprint = this.fingerprint ? [...this.fingerprint] : undefined;\n next.breadcrumbs = [...this.breadcrumbs];\n return next;\n }\n}\n","import type { SpanData, TransactionPayload } from './protocol';\nimport type { Client } from './client';\nimport { nowISO, uuid4 } from './utils';\n\nfunction spanId(): string {\n return uuid4().slice(0, 16);\n}\n\nexport class Span {\n readonly spanId = spanId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n endTimestamp?: string;\n data?: Record<string, unknown>;\n\n constructor(\n private readonly transaction: Transaction,\n readonly parentSpanId: string,\n readonly op?: string,\n readonly description?: string\n ) {}\n\n setStatus(status: string): this {\n this.status = status;\n return this;\n }\n\n setData(key: string, value: unknown): this {\n this.data = { ...this.data, [key]: value };\n return this;\n }\n\n /** Span aninhado (filho deste span). */\n startChild(op?: string, description?: string): Span {\n return this.transaction.createSpan(this.spanId, op, description);\n }\n\n finish(): void {\n if (!this.endTimestamp) this.endTimestamp = nowISO();\n }\n\n toJSON(): SpanData {\n return {\n span_id: this.spanId,\n parent_span_id: this.parentSpanId,\n op: this.op,\n description: this.description,\n status: this.status,\n start_timestamp: this.startTimestamp,\n timestamp: this.endTimestamp ?? nowISO(),\n data: this.data,\n };\n }\n}\n\n/**\n * Uma unidade de trabalho nomeada (ex.: uma execução de rotina, uma sincronização).\n * Spans filhos medem as etapas internas (chamadas HTTP, queries, etc.).\n */\nexport class Transaction {\n readonly eventId = uuid4();\n readonly spanId = spanId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n private readonly spans: Span[] = [];\n private readonly tags: Record<string, string> = {};\n private finished = false;\n\n constructor(\n private readonly client: Client | undefined,\n public name: string,\n readonly op?: string,\n private readonly sampled = true\n ) {}\n\n createSpan(parentSpanId: string, op?: string, description?: string): Span {\n const span = new Span(this, parentSpanId, op, description);\n this.spans.push(span);\n return span;\n }\n\n /** Span direto da transaction. */\n startChild(op?: string, description?: string): Span {\n return this.createSpan(this.spanId, op, description);\n }\n\n setTag(key: string, value: string): this {\n this.tags[key] = value;\n return this;\n }\n\n setStatus(status: string): this {\n this.status = status;\n return this;\n }\n\n setName(name: string): this {\n this.name = name;\n return this;\n }\n\n finish(): void {\n if (this.finished) return;\n this.finished = true;\n\n for (const span of this.spans) span.finish();\n\n if (!this.sampled || !this.client) return;\n const payload: TransactionPayload = {\n event_id: this.eventId,\n name: this.name,\n op: this.op,\n status: this.status,\n start_timestamp: this.startTimestamp,\n timestamp: nowISO(),\n spans: this.spans.map(span => span.toJSON()),\n tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,\n };\n this.client.sendTransaction(payload);\n }\n}\n","import type { CheckInStatus } from './protocol';\nimport type { Client } from './client';\nimport { uuid4 } from './utils';\n\nexport interface CheckInOptions {\n monitorSlug: string;\n status: CheckInStatus;\n /** Reutilize o id retornado pelo check-in 'in_progress' para fechar a execução */\n checkInId?: string;\n durationMs?: number;\n /** Expressão cron — cria/atualiza o monitor automaticamente no servidor */\n schedule?: string;\n timezone?: string;\n}\n\nexport function sendCheckIn(client: Client, options: CheckInOptions): string {\n const checkInId = options.checkInId ?? uuid4();\n client.sendCheckIn({\n check_in_id: checkInId,\n monitor_slug: options.monitorSlug,\n status: options.status,\n duration_ms: options.durationMs,\n schedule: options.schedule,\n timezone: options.timezone,\n });\n return checkInId;\n}\n\nexport interface WithMonitorOptions {\n schedule?: string;\n timezone?: string;\n}\n\n/** Envolve a execução de um job: in_progress → ok/error com duração medida. */\nexport async function withMonitorImpl<T>(\n client: Client,\n captureError: (error: unknown) => void,\n monitorSlug: string,\n fn: () => T | Promise<T>,\n options?: WithMonitorOptions\n): Promise<T> {\n const checkInId = sendCheckIn(client, {\n monitorSlug,\n status: 'in_progress',\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n const startedAt = Date.now();\n\n try {\n const result = await fn();\n sendCheckIn(client, {\n monitorSlug,\n status: 'ok',\n checkInId,\n durationMs: Date.now() - startedAt,\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n return result;\n } catch (error) {\n sendCheckIn(client, {\n monitorSlug,\n status: 'error',\n checkInId,\n durationMs: Date.now() - startedAt,\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n captureError(error);\n throw error;\n }\n}\n","import type { ManagerPollRequest, ManagerPollResponse, ManagerRunUpdateRequest } from './protocol';\nimport { sleep, type Logger } from '../utils';\n\nconst RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\n\nexport class ManagerApiError extends Error {\n constructor(\n message: string,\n readonly status: number\n ) {\n super(message);\n this.name = 'ManagerApiError';\n }\n}\n\nexport interface ManagerApiOptions {\n baseUrl: string;\n key: string;\n logger: Logger;\n}\n\n/** Cliente HTTP do agente — bearer auth, retry com backoff nos updates. */\nexport class ManagerApi {\n private readonly baseUrl: string;\n private readonly key: string;\n private readonly logger: Logger;\n\n constructor(options: ManagerApiOptions) {\n this.baseUrl = options.baseUrl;\n this.key = options.key;\n this.logger = options.logger;\n }\n\n private headers(): Record<string, string> {\n return {\n 'content-type': 'application/json',\n authorization: `Bearer ${this.key}`,\n };\n }\n\n /** Um request só — o loop de polling é quem decide o backoff entre tentativas. */\n async poll(request: ManagerPollRequest, signal?: AbortSignal): Promise<ManagerPollResponse> {\n const response = await fetch(`${this.baseUrl}/poll`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal,\n });\n if (!response.ok) {\n throw new ManagerApiError(`poll falhou (HTTP ${response.status})`, response.status);\n }\n return (await response.json()) as ManagerPollResponse;\n }\n\n /**\n * PATCH de status/logs com retry em falha de rede/5xx/429.\n * 4xx é definitivo e vira ManagerApiError imediato (409 = run cancelada/transição inválida).\n */\n async updateRun(runId: string, update: ManagerRunUpdateRequest): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n let retriable: unknown;\n try {\n const response = await fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}`, {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(update),\n });\n if (response.ok) return;\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n throw new ManagerApiError(`update rejeitado (HTTP ${response.status})`, response.status);\n }\n retriable = new Error(`HTTP ${response.status}`);\n } catch (error) {\n if (error instanceof ManagerApiError) throw error;\n retriable = error;\n }\n\n const delay = RETRY_DELAYS_MS[attempt];\n if (delay === undefined) {\n throw new Error(`update da run ${runId} descartado após retries: ${String(retriable)}`);\n }\n this.logger.warn(`falha no update da run ${runId} (${String(retriable)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n }\n}\n","import type { ManagerRunError, ManagerRunUpdateRequest, RunLogEntry, RunLogLevel } from './protocol';\nimport type { RunContext } from './types';\nimport { ManagerApi, ManagerApiError } from './api';\nimport { nowISO, unrefTimer, type Logger } from '../utils';\n\nconst DEFAULT_LOG_FLUSH_INTERVAL_MS = 2_000;\nconst MAX_LOG_MESSAGE_CHARS = 10_000;\nconst MAX_LOGS_PER_RUN = 500;\nconst MAX_LOGS_PER_PATCH = 100;\nconst FLUSH_AT_BUFFERED = 20;\n\n/**\n * Reporter de uma run: bufferiza logs (flush incremental com throttle) e encadeia\n * todos os PATCHes numa fila única — a ordem running → logs → terminal é garantida.\n * Um 409/404 mata o reporter (run cancelada no app): o handler não pode ser morto,\n * mas todo reporte posterior é suprimido e ctx.signal dispara para abort cooperativo.\n */\nexport class RunReporter {\n readonly context: RunContext;\n\n private buffer: RunLogEntry[] = [];\n private loggedCount = 0;\n private droppedCount = 0;\n private dead = false;\n private chain: Promise<void> = Promise.resolve();\n private timer: ReturnType<typeof setTimeout> | undefined;\n private readonly abortController = new AbortController();\n private readonly flushIntervalMs: number;\n\n constructor(\n private readonly api: ManagerApi,\n private readonly runId: string,\n task: string,\n private readonly logger: Logger,\n flushIntervalMs?: number\n ) {\n this.flushIntervalMs = flushIntervalMs ?? DEFAULT_LOG_FLUSH_INTERVAL_MS;\n this.context = {\n runId,\n task,\n log: (level, message) => this.log(level, message),\n signal: this.abortController.signal,\n };\n }\n\n get isDead(): boolean {\n return this.dead;\n }\n\n /** Aborta o ctx.signal sem matar o reporter (timeout/shutdown ainda reportam o terminal). */\n abort(): void {\n if (!this.abortController.signal.aborted) this.abortController.abort();\n }\n\n private log(level: RunLogLevel, message: string): void {\n if (this.dead) return;\n if (this.loggedCount >= MAX_LOGS_PER_RUN) {\n this.droppedCount++;\n return;\n }\n this.loggedCount++;\n const truncated =\n message.length > MAX_LOG_MESSAGE_CHARS ? `${message.slice(0, MAX_LOG_MESSAGE_CHARS)}… [truncado]` : message;\n this.buffer.push({ ts: nowISO(), level, message: truncated });\n\n if (this.buffer.length >= FLUSH_AT_BUFFERED) {\n this.flushLogs();\n } else {\n this.scheduleFlush();\n }\n }\n\n private scheduleFlush(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n this.flushLogs();\n }, this.flushIntervalMs);\n unrefTimer(this.timer);\n }\n\n private clearFlushTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n }\n\n private takeLogs(): RunLogEntry[] {\n const logs = this.buffer.splice(0, this.buffer.length);\n if (this.droppedCount > 0) {\n logs.push({\n ts: nowISO(),\n level: 'warning',\n message: `${this.droppedCount} logs descartados (limite de ${MAX_LOGS_PER_RUN} por execução)`,\n });\n this.droppedCount = 0;\n }\n return logs;\n }\n\n /** Flush incremental: envia o buffer como status 'running' (em chunks). */\n private flushLogs(): void {\n this.clearFlushTimer();\n if (this.dead || this.buffer.length === 0) return;\n const logs = this.buffer.splice(0, this.buffer.length);\n for (let i = 0; i < logs.length; i += MAX_LOGS_PER_PATCH) {\n this.enqueue({ status: 'running', logs: logs.slice(i, i + MAX_LOGS_PER_PATCH) });\n }\n }\n\n /** Primeiro PATCH (claimed → running). Retorna false se a run já morreu (cancelada). */\n async reportRunning(): Promise<boolean> {\n this.enqueue({ status: 'running' });\n await this.chain;\n return !this.dead;\n }\n\n reportSuccess(): void {\n this.clearFlushTimer();\n this.enqueue({ status: 'succeeded', logs: this.takeLogs() });\n }\n\n reportFailure(error: ManagerRunError): void {\n this.clearFlushTimer();\n this.enqueue({ status: 'failed', error, logs: this.takeLogs() });\n }\n\n /** Aguarda a fila de PATCHes esvaziar (chame depois do terminal). */\n finalize(): Promise<void> {\n return this.chain;\n }\n\n private enqueue(update: ManagerRunUpdateRequest): void {\n if (this.dead) return;\n this.chain = this.chain.then(async () => {\n if (this.dead) return;\n const payload = update.logs && update.logs.length === 0 ? { ...update, logs: undefined } : update;\n try {\n await this.api.updateRun(this.runId, payload);\n } catch (error) {\n if (error instanceof ManagerApiError && (error.status === 409 || error.status === 404)) {\n this.dead = true;\n this.abort();\n this.buffer = [];\n this.logger.warn(`run ${this.runId} cancelada/removida no servidor — reporte suprimido`);\n return;\n }\n this.logger.error(`update da run ${this.runId} perdido:`, error);\n }\n });\n }\n}\n","import type { ManagerRunDescriptor, ManagerRunError } from './protocol';\nimport type { ManagerAgentOptions, ManagerTaskHandler } from './types';\nimport { ManagerApi, ManagerApiError } from './api';\nimport { RunReporter } from './context';\nimport { resolveConfig } from '../config';\nimport { isNode, makeLogger, sleep, SDK_VERSION, type Logger } from '../utils';\n\nconst DEFAULT_POLL_INTERVAL_MS = 5_000;\nconst MIN_POLL_INTERVAL_MS = 1_000;\nconst MAX_CONCURRENCY = 5;\nconst POLL_RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\nconst AUTH_FAILURE_INTERVAL_MS = 30_000;\n\ntype AgentState = 'idle' | 'started' | 'stopping';\n\n/** Hostname da máquina — telemetria (campo `host`), distinto da identidade do agente. */\nfunction hostname(): string | undefined {\n if (!isNode()) return undefined;\n return process.env.HOSTNAME || process.env.COMPUTERNAME || undefined;\n}\n\n/**\n * Loop de polling do Manager: busca runs pendentes, executa os handlers registrados\n * e reporta status/logs/result. Ao contrário do Monitor, o timer de polling NÃO é\n * unref'd — um agente iniciado mantém o processo vivo até stop().\n */\nexport class ManagerAgent {\n readonly logger: Logger;\n\n private readonly api: ManagerApi;\n private readonly pollIntervalMs: number;\n private readonly concurrency: number;\n private readonly instanceId: string;\n private readonly taskTimeoutMs?: number;\n private readonly logFlushIntervalMs?: number;\n\n private state: AgentState = 'idle';\n private timer: ReturnType<typeof setTimeout> | undefined;\n private pollAbort: AbortController | undefined;\n private consecutiveFailures = 0;\n private consecutiveAuthFailures = 0;\n private readonly activeRuns = new Set<Promise<void>>();\n private readonly reporters = new Set<RunReporter>();\n\n constructor(\n private readonly options: ManagerAgentOptions,\n private readonly registry: Map<string, ManagerTaskHandler>\n ) {\n this.logger = makeLogger(options.debug ?? false, '[hobots-manager]');\n const config = resolveConfig(options, '[hobots-manager]');\n this.api = new ManagerApi({ baseUrl: config.managerBaseUrl, key: config.key, logger: this.logger });\n this.pollIntervalMs = Math.max(MIN_POLL_INTERVAL_MS, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n this.concurrency = Math.min(MAX_CONCURRENCY, Math.max(1, options.concurrency ?? 1));\n this.instanceId = options.instanceId;\n this.taskTimeoutMs = options.taskTimeoutMs;\n this.logFlushIntervalMs = options.logFlushIntervalMs;\n this.logger.debug('agente configurado', { baseUrl: config.managerBaseUrl });\n }\n\n get activeCount(): number {\n return this.activeRuns.size;\n }\n\n start(): void {\n if (this.state === 'started') return;\n if (this.state === 'stopping') {\n throw new Error('[hobots-manager] start() chamado durante stop() — aguarde o stop terminar');\n }\n if (this.registry.size === 0) {\n throw new Error('[hobots-manager] nenhuma task registrada — chame register() antes de start()');\n }\n this.state = 'started';\n this.logger.debug(`polling iniciado (tasks: ${[...this.registry.keys()].join(', ')})`);\n this.schedule(0);\n }\n\n /** Para o polling e aguarda as runs ativas (até timeoutMs). Retorna true se tudo terminou a tempo. */\n async stop(timeoutMs = 30_000): Promise<boolean> {\n if (this.state === 'idle') return true;\n this.state = 'stopping';\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n this.pollAbort?.abort();\n\n const all = Promise.allSettled([...this.activeRuns]).then(() => true);\n const finished = timeoutMs > 0 ? await Promise.race([all, sleep(timeoutMs).then(() => false)]) : false;\n if (!finished && this.activeRuns.size > 0) {\n this.logger.warn(`${this.activeRuns.size} run(s) ainda em execução após ${timeoutMs}ms — abandonando a espera`);\n for (const reporter of this.reporters) reporter.abort();\n }\n this.state = 'idle';\n return finished;\n }\n\n /** Timer intencionalmente NÃO unref'd: o agente é a razão do processo existir. */\n private schedule(delayMs: number): void {\n if (this.state !== 'started' || this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n void this.tick();\n }, delayMs);\n }\n\n private async tick(): Promise<void> {\n if (this.state !== 'started') return;\n if (this.activeRuns.size >= this.concurrency) {\n this.schedule(this.pollIntervalMs);\n return;\n }\n\n this.pollAbort = new AbortController();\n try {\n const response = await this.api.poll(\n {\n agent: {\n // identidade canônica do agente no painel — o mesmo instanceId do\n // heartbeat do Monitor, então os dois canais convergem em um agente\n instance_id: this.instanceId,\n version: SDK_VERSION,\n host: hostname(),\n tasks: [...this.registry.keys()],\n },\n max: Math.min(MAX_CONCURRENCY, this.concurrency - this.activeRuns.size),\n tasks: [...this.registry.keys()],\n },\n this.pollAbort.signal\n );\n this.consecutiveFailures = 0;\n this.consecutiveAuthFailures = 0;\n\n for (const run of response.runs) {\n this.dispatch(run);\n }\n // com trabalho entregue, re-poll imediato (modo drain); sem trabalho, espera o intervalo\n this.schedule(response.runs.length > 0 ? 0 : this.pollIntervalMs);\n } catch (error) {\n if (this.state !== 'started') return; // stop() abortou o poll\n this.schedule(this.delayAfterPollError(error));\n } finally {\n this.pollAbort = undefined;\n }\n }\n\n private delayAfterPollError(error: unknown): number {\n if (error instanceof ManagerApiError && error.status === 401) {\n // chave desativada/rotacionada — continua tentando devagar (pode ser reativada)\n this.consecutiveAuthFailures++;\n if (this.consecutiveAuthFailures === 1 || this.consecutiveAuthFailures % 10 === 0) {\n this.logger.error('chave rejeitada (401) — verifique o Client Secret do projeto em Configurações → Projetos');\n }\n return Math.max(this.pollIntervalMs, AUTH_FAILURE_INTERVAL_MS);\n }\n this.consecutiveFailures++;\n const ladder = POLL_RETRY_DELAYS_MS[Math.min(this.consecutiveFailures - 1, POLL_RETRY_DELAYS_MS.length - 1)]!;\n const delay = Math.min(Math.max(ladder, 0), Math.max(this.pollIntervalMs, 16_000));\n this.logger.warn(`poll falhou (${String(error)}), próxima tentativa em ${delay}ms`);\n return delay;\n }\n\n private dispatch(run: ManagerRunDescriptor): void {\n const promise = this.executeRun(run)\n .catch(error => this.logger.error(`erro inesperado na run ${run.id}:`, error))\n .finally(() => {\n this.activeRuns.delete(promise);\n if (this.state === 'started') this.schedule(0);\n });\n this.activeRuns.add(promise);\n }\n\n private async executeRun(run: ManagerRunDescriptor): Promise<void> {\n const reporter = new RunReporter(this.api, run.id, run.task, this.logger, this.logFlushIntervalMs);\n this.reporters.add(reporter);\n try {\n const handler = this.registry.get(run.task);\n if (!handler) {\n // claim veio para uma task sem handler (corrida rara) — falha direto, sem 'running'\n reporter.reportFailure({\n type: 'HandlerNotFound',\n message: `tarefa não registrada no agente: ${run.task}`,\n });\n await reporter.finalize();\n return;\n }\n\n const ok = await reporter.reportRunning();\n if (!ok) {\n this.logger.debug(`run ${run.id} cancelada antes de iniciar — handler não executado`);\n return;\n }\n\n this.logger.debug(`executando run ${run.id} (${run.task})`);\n try {\n await this.invokeWithTimeout(handler, run, reporter);\n reporter.reportSuccess();\n this.logger.debug(`run ${run.id} concluída`);\n } catch (error) {\n reporter.reportFailure(toRunError(error));\n this.logger.debug(`run ${run.id} falhou: ${String(error)}`);\n }\n await reporter.finalize();\n } finally {\n this.reporters.delete(reporter);\n }\n }\n\n private async invokeWithTimeout(\n handler: ManagerTaskHandler,\n run: ManagerRunDescriptor,\n reporter: RunReporter\n ): Promise<void> {\n const invocation = Promise.resolve().then(() => handler(run.params, reporter.context));\n if (!this.taskTimeoutMs || this.taskTimeoutMs <= 0) {\n await invocation;\n return;\n }\n\n const timeoutMs = this.taskTimeoutMs;\n const timeout = sleep(timeoutMs).then(() => TIMEOUT_SENTINEL);\n const outcome = await Promise.race([invocation, timeout]);\n if (outcome !== TIMEOUT_SENTINEL) return;\n\n // não dá para matar o código do usuário — reporta, aborta o signal e libera o slot\n reporter.abort();\n invocation\n .then(() => this.logger.warn(`run ${run.id} terminou depois do timeout de ${timeoutMs}ms`))\n .catch(() => this.logger.warn(`run ${run.id} falhou depois do timeout de ${timeoutMs}ms (erro descartado)`));\n throw Object.assign(new Error(`timeout após ${timeoutMs}ms (o handler pode continuar em background)`), {\n name: 'TaskTimeout',\n });\n }\n}\n\nconst TIMEOUT_SENTINEL = Symbol('task-timeout');\n\nconst MAX_ERROR_MESSAGE_CHARS = 10_000;\nconst MAX_ERROR_STACK_CHARS = 20_000;\n\nfunction truncate(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max)}… [truncado]` : value;\n}\n\nfunction toRunError(error: unknown): ManagerRunError {\n if (error instanceof Error) {\n return {\n type: error.name,\n message: truncate(error.message, MAX_ERROR_MESSAGE_CHARS),\n stack: error.stack ? truncate(error.stack, MAX_ERROR_STACK_CHARS) : undefined,\n };\n }\n return { message: truncate(String(error), MAX_ERROR_MESSAGE_CHARS) };\n}\n","import type { EventUser, Severity } from './protocol';\nimport type { CaptureHint, InitOptions } from './types';\nimport { Client } from './client';\nimport { Heartbeat } from './heartbeat';\nimport { installGlobalHandlers } from './instrument';\nimport { Scope, type BreadcrumbInput } from './scope';\nimport { Transaction } from './transaction';\nimport { sendCheckIn, withMonitorImpl, type CheckInOptions, type WithMonitorOptions } from './checkin';\nimport { ManagerAgent } from './manager/agent';\nimport type { ManagerTaskHandler } from './manager/types';\n\nconst DEFAULT_MAX_BREADCRUMBS = 100;\n\nlet client: Client | undefined;\nlet scope = new Scope();\nlet heartbeat: Heartbeat | undefined;\nlet agent: ManagerAgent | undefined;\nconst registry = new Map<string, ManagerTaskHandler>();\nlet warnedManagerDisabled = false;\n\n/** Inicializa o SDK. Chame uma vez, o mais cedo possível no programa. */\nexport function init(options: InitOptions): void {\n if (client) {\n client.logger.warn('init() chamado mais de uma vez — substituindo o client anterior');\n heartbeat?.stop();\n heartbeat = undefined;\n }\n if (agent) {\n void agent.stop(0);\n agent = undefined;\n }\n warnedManagerDisabled = false;\n\n client = new Client(options);\n\n if (options.captureUnhandled !== false) {\n installGlobalHandlers(client, () => scope);\n }\n\n if (options.heartbeat) {\n const heartbeatOptions = options.heartbeat === true ? {} : options.heartbeat;\n heartbeat = new Heartbeat(client, heartbeatOptions, options.instanceId);\n heartbeat.start();\n }\n\n if (options.manager) {\n const managerOptions = options.manager === true ? {} : options.manager;\n agent = new ManagerAgent(\n { ...managerOptions, clientSecret: options.clientSecret, baseUrl: options.baseUrl, instanceId: options.instanceId, debug: options.debug },\n registry\n );\n }\n\n client.logger.debug('inicializado', { endpoint: client.config.ingestEndpoint });\n}\n\nexport function getClient(): Client | undefined {\n return client;\n}\n\n/** Captura uma exceção e retorna o event_id (undefined se o SDK não foi inicializado). */\nexport function captureException(error: unknown, hint?: CaptureHint): string | undefined {\n return client?.captureException(error, hint, scope);\n}\n\nexport function captureMessage(message: string, level: Severity = 'info', hint?: CaptureHint): string | undefined {\n return client?.captureMessage(message, level, hint, scope);\n}\n\n/** Registra um breadcrumb — anexado aos próximos eventos como trilha do que aconteceu antes. */\nexport function addBreadcrumb(crumb: BreadcrumbInput): void {\n scope.addBreadcrumb(crumb, client?.options.maxBreadcrumbs ?? DEFAULT_MAX_BREADCRUMBS);\n}\n\nexport function setTag(key: string, value: string): void {\n scope.setTag(key, value);\n}\n\nexport function setTags(tags: Record<string, string>): void {\n scope.setTags(tags);\n}\n\nexport function setUser(user: EventUser | null): void {\n scope.setUser(user);\n}\n\nexport function setContext(name: string, context: Record<string, unknown> | null): void {\n scope.setContext(name, context);\n}\n\nexport function setExtra(key: string, value: unknown): void {\n scope.setExtra(key, value);\n}\n\n/** Executa o callback com uma cópia isolada do scope (alterações não vazam para fora). */\nexport function withScope<T>(callback: (scope: Scope) => T): T {\n const previous = scope;\n scope = previous.clone();\n try {\n return callback(scope);\n } finally {\n scope = previous;\n }\n}\n\n/** Inicia uma transaction de performance. Chame .finish() para enviá-la. */\nexport function startTransaction(name: string, op?: string): Transaction {\n const rate = client?.options.tracesSampleRate ?? 1;\n const sampled = rate >= 1 || Math.random() < rate;\n return new Transaction(client, name, op, sampled);\n}\n\n/** Check-in manual de um monitor cron. Retorna o check_in_id para fechar a execução depois. */\nexport function checkIn(options: CheckInOptions): string | undefined {\n return client ? sendCheckIn(client, options) : undefined;\n}\n\n/** Envolve um job monitorado: envia in_progress → ok/error com duração e captura a exceção em caso de falha. */\nexport async function withMonitor<T>(\n monitorSlug: string,\n fn: () => T | Promise<T>,\n options?: WithMonitorOptions\n): Promise<T> {\n if (!client) return fn();\n return withMonitorImpl(\n client,\n error => captureException(error, { tags: { monitor: monitorSlug } }),\n monitorSlug,\n fn,\n options\n );\n}\n\n/** Aguarda o envio de tudo que está na fila (até timeoutMs). */\nexport function flush(timeoutMs?: number): Promise<boolean> {\n return client ? client.flush(timeoutMs) : Promise.resolve(true);\n}\n\n/** Registra o handler de uma task do Manager (o task_slug configurado no formulário do app). */\nexport function register<P = Record<string, unknown>>(task: string, handler: ManagerTaskHandler<P>): void {\n if (registry.has(task)) {\n (agent?.logger ?? client?.logger)?.warn(`register('${task}') sobrescreveu um handler existente`);\n }\n if (client && !agent && !warnedManagerDisabled) {\n warnedManagerDisabled = true;\n client.logger.warn(\n `register('${task}') com o Manager desabilitado — passe manager: true (ou opções) no init()`\n );\n }\n registry.set(task, handler as ManagerTaskHandler);\n}\n\n/**\n * Inicia o polling do Manager. O timer NÃO é unref'd: o processo fica vivo\n * aguardando trabalho até stop()/close() — o inverso deliberado do Monitor.\n */\nexport function start(): void {\n if (!agent) {\n throw new Error('[hobots] Manager não configurado — passe manager: true (ou opções) no init() antes de start()');\n }\n agent.start();\n}\n\n/** Para só o Manager: encerra o polling e aguarda as runs ativas (até timeoutMs). A telemetria continua. */\nexport function stop(timeoutMs?: number): Promise<boolean> {\n return agent ? agent.stop(timeoutMs) : Promise.resolve(true);\n}\n\n/**\n * Encerra tudo: para o Manager (aguardando runs em voo), o heartbeat e faz o\n * flush final do transport. Chame antes do processo terminar.\n */\nexport async function close(timeoutMs?: number): Promise<boolean> {\n const agentStopped = agent ? await agent.stop(timeoutMs) : true;\n heartbeat?.stop();\n heartbeat = undefined;\n const clientClosed = client ? await client.close(timeoutMs) : true;\n return agentStopped && clientClosed;\n}\n"],"mappings":";AACO,IAAM,mBAAmB;AAkBzB,SAAS,cAAc,SAAsB,SAAS,YAA4B;AACvF,QAAM,MAAM,QAAQ,cAAc,KAAK;AACvC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,GAAG,MAAM,sGAAsF;AAAA,EACjH;AAEA,QAAM,WAAW,QAAQ,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACxE,MAAI;AACF,QAAI,IAAI,OAAO;AAAA,EACjB,QAAQ;AACN,UAAM,IAAI,MAAM,GAAG,MAAM,0BAAuB,OAAO,+CAA0C;AAAA,EACnG;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAgB,GAAG,OAAO;AAAA,IAC1B,gBAAgB,GAAG,OAAO;AAAA,EAC5B;AACF;;;ACpCA,IAAM,aAAa;AAGnB,IAAM,WAAW;AACjB,IAAM,cAAc;AAEpB,SAAS,QAAQ,UAAuC;AACtD,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,SAAS,WAAW,OAAO,EAAG,QAAO;AACzC,MAAI,SAAS,WAAW,WAAW,EAAG,QAAO;AAC7C,MAAI,SAAS,SAAS,cAAc,EAAG,QAAO;AAC9C,MAAI,aAAa,cAAe,QAAO;AACvC,SAAO;AACT;AAGO,SAAS,gBAAgB,OAAgD;AAC9E,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,QAAM,SAAuB,CAAC;AAC9B,aAAW,QAAQ,MAAM,MAAM,IAAI,GAAG;AACpC,QAAI,OAAO,UAAU,WAAY;AACjC,UAAM,QAAQ,SAAS,KAAK,IAAI;AAChC,QAAI,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE,WAAW,KAAK,EAAG;AAEnD,UAAM,CAAC,EAAE,IAAI,QAAQ,IAAI;AACzB,UAAM,MAAM,YAAY,KAAK,YAAY,EAAE;AAC3C,UAAM,WAAW,MAAM,IAAI,CAAC,IAAI;AAChC,WAAO,KAAK;AAAA,MACV,UAAU,MAAM;AAAA,MAChB,UAAU,YAAY;AAAA,MACtB,QAAQ,MAAM,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,IAAI;AAAA,MACpC,OAAO,MAAM,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,IAAI;AAAA,MACnC,QAAQ,QAAQ,QAAQ;AAAA,IAC1B,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ACvCO,IAAM,WAAW;AACjB,IAAM,cAAc;AAEpB,SAAS,SAAkB;AAChC,SAAO,OAAO,YAAY,eAAe,OAAO,QAAQ,UAAU,SAAS;AAC7E;AAGO,SAAS,QAAgB;AAC9B,QAAM,YAAa,WAAmC;AACtD,MAAI,aAAa,OAAO,UAAU,eAAe,YAAY;AAC3D,WAAO,UAAU,WAAW,EAAE,QAAQ,MAAM,EAAE;AAAA,EAChD;AACA,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,WAAO,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE,EAAE,SAAS,EAAE;AAAA,EACnD;AACA,SAAO;AACT;AAEO,SAAS,SAAiB;AAC/B,UAAO,oBAAI,KAAK,GAAE,YAAY;AAChC;AAGO,SAAS,WAAW,OAAsB;AAC/C,EAAC,OAA8C,QAAQ;AACzD;AAEO,SAAS,MAAM,IAA2B;AAC/C,SAAO,IAAI,QAAQ,aAAW;AAC5B,UAAM,QAAQ,WAAW,SAAS,EAAE;AACpC,eAAW,KAAK;AAAA,EAClB,CAAC;AACH;AAQA,IAAM,SAAS;AAER,SAAS,WAAW,SAAkB,SAAiB,QAAgB;AAC5E,SAAO;AAAA,IACL,OAAO,IAAI,SAAS,WAAW,QAAQ,MAAM,QAAQ,GAAG,IAAI;AAAA,IAC5D,MAAM,IAAI,SAAS,WAAW,QAAQ,KAAK,QAAQ,GAAG,IAAI;AAAA,IAC1D,OAAO,IAAI,SAAS,QAAQ,MAAM,QAAQ,GAAG,IAAI;AAAA,EACnD;AACF;;;AC9CA,SAAS,WAAW,OAAwB;AAC1C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI;AACF,UAAM,OAAO,KAAK,UAAU,KAAK;AACjC,QAAI,QAAQ,SAAS,KAAM,QAAO;AAAA,EACpC,QAAQ;AAAA,EAER;AACA,SAAO,OAAO,KAAK;AACrB;AAEO,SAAS,mBAAmB,OAAgB,QAAkB,SAAuB;AAC1F,MAAI;AACJ,MAAI;AACJ,MAAI,SAAS,CAAC;AAEd,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM,QAAQ;AACrB,YAAQ,MAAM;AACd,aAAS,gBAAgB,MAAM,KAAK;AAAA,EACtC,OAAO;AACL,WAAO;AACP,YAAQ,WAAW,KAAK;AAAA,EAC1B;AAEA,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,WAAW,OAAO;AAAA,IAClB;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,MACA,GAAI,OAAO,SAAS,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACxD;AAAA,EACF;AACF;AAEO,SAAS,iBAAiB,SAAiB,QAAkB,QAAsB;AACxF,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,WAAW,OAAO;AAAA,IAClB;AAAA,IACA;AAAA,EACF;AACF;;;AC7CA,IAAM,kBAAkB,CAAC,KAAO,KAAO,IAAM;AAC7C,IAAM,4BAA4B;AAClC,IAAM,yBAAyB;AAC/B,IAAM,yBAAyB;AAaxB,IAAM,YAAN,MAAgB;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,SAAyB,CAAC;AAAA,EAC1B;AAAA,EACA,UAAU,oBAAI,IAAmB;AAAA,EACjC,SAAS;AAAA,EAEjB,YAAY,SAA2B;AACrC,SAAK,WAAW,QAAQ;AACxB,SAAK,MAAM,QAAQ;AACnB,SAAK,SAAS,QAAQ;AACtB,SAAK,kBAAkB,QAAQ,mBAAmB;AAClD,SAAK,eAAe,QAAQ,gBAAgB;AAC5C,SAAK,eAAe,QAAQ,gBAAgB;AAAA,EAC9C;AAAA,EAEA,QAAQ,MAA0B;AAChC,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,KAAK,uCAAuC,KAAK,IAAI;AACjE;AAAA,IACF;AACA,QAAI,KAAK,OAAO,UAAU,KAAK,cAAc;AAC3C,WAAK,OAAO,MAAM;AAClB,WAAK,OAAO,KAAK,yCAAyC;AAAA,IAC5D;AACA,SAAK,OAAO,KAAK,IAAI;AAErB,QAAI,KAAK,OAAO,UAAU,KAAK,cAAc;AAC3C,WAAK,KAAK,YAAY;AAAA,IACxB,OAAO;AACL,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,WAAiB;AACvB,QAAI,KAAK,MAAO;AAChB,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,QAAQ;AACb,WAAK,KAAK,YAAY;AAAA,IACxB,GAAG,KAAK,eAAe;AACvB,eAAW,KAAK,KAAK;AAAA,EACvB;AAAA,EAEQ,cAA6B;AACnC,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AACA,QAAI,KAAK,OAAO,WAAW,EAAG,QAAO,QAAQ,QAAQ;AAErD,UAAM,QAAQ,KAAK,OAAO,OAAO,GAAG,KAAK,OAAO,MAAM;AACtD,UAAM,WAAqB;AAAA,MACzB,KAAK,EAAE,MAAM,UAAU,SAAS,YAAY;AAAA,MAC5C,SAAS,OAAO;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,UAAyB,KAAK,cAAc,QAAQ,EAAE,QAAQ,MAAM;AACxE,WAAK,QAAQ,OAAO,OAAO;AAAA,IAC7B,CAAC;AACD,SAAK,QAAQ,IAAI,OAAO;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,UAAmC;AAC7D,aAAS,UAAU,KAAK,WAAW;AACjC,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,KAAK,UAAU;AAAA,UAC1C,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,KAAK,GAAG,GAAG;AAAA,UACnF,MAAM,KAAK,UAAU,QAAQ;AAAA,QAC/B,CAAC;AACD,YAAI,SAAS,IAAI;AACf,eAAK,OAAO,MAAM,qBAAqB,SAAS,MAAM,MAAM,SAAS;AACrE;AAAA,QACF;AAEA,YAAI,SAAS,UAAU,OAAO,SAAS,SAAS,OAAO,SAAS,WAAW,KAAK;AAC9E,eAAK,OAAO,MAAM,4BAA4B,SAAS,MAAM,eAAe;AAC5E;AAAA,QACF;AACA,cAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE;AAAA,MAC3C,SAAS,OAAO;AACd,cAAM,QAAQ,gBAAgB,OAAO;AACrC,YAAI,UAAU,QAAW;AACvB,eAAK,OAAO,MAAM,wCAAqC,KAAK;AAC5D;AAAA,QACF;AACA,aAAK,OAAO,KAAK,mBAAmB,OAAO,KAAK,CAAC,eAAe,KAAK,IAAI;AACzE,cAAM,MAAM,KAAK;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,MAAM,YAAY,KAAyB;AAC/C,SAAK,KAAK,YAAY;AACtB,UAAM,MAAM,QAAQ,WAAW,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE,KAAK,MAAM,IAAI;AACjE,WAAO,QAAQ,KAAK,CAAC,KAAK,MAAM,SAAS,EAAE,KAAK,MAAM,KAAK,CAAC,CAAC;AAAA,EAC/D;AAAA,EAEA,MAAM,MAAM,YAAY,KAAyB;AAC/C,UAAM,SAAS,MAAM,KAAK,MAAM,SAAS;AACzC,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AACF;;;AC3HA,SAAS,kBAA2D;AAClE,MAAI,OAAO,GAAG;AACZ,WAAO;AAAA,MACL,SAAS,EAAE,MAAM,QAAQ,SAAS,QAAQ,QAAQ;AAAA,MAClD,IAAI,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,KAAK;AAAA,IACnD;AAAA,EACF;AACA,SAAO,EAAE,SAAS,EAAE,MAAM,UAAU,EAAE;AACxC;AAEO,IAAM,SAAN,MAAa;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACQ;AAAA,EAEjB,YAAY,SAAsB;AAChC,SAAK,UAAU;AACf,SAAK,SAAS,WAAW,CAAC,CAAC,QAAQ,KAAK;AACxC,SAAK,SAAS,cAAc,OAAO;AACnC,SAAK,YAAY,IAAI,UAAU;AAAA,MAC7B,UAAU,KAAK,OAAO;AAAA,MACtB,KAAK,KAAK,OAAO;AAAA,MACjB,QAAQ,KAAK;AAAA,MACb,iBAAiB,QAAQ;AAAA,MACzB,cAAc,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,iBAAiB,OAAgB,MAA+BA,QAAsB;AACpF,WAAO,KAAK,aAAa,mBAAmB,OAAO,MAAM,SAAS,OAAO,GAAG,MAAMA,MAAK;AAAA,EACzF;AAAA,EAEA,eAAe,SAAiB,OAAiB,MAA+BA,QAAsB;AACpG,WAAO,KAAK,aAAa,iBAAiB,SAAS,KAAK,GAAG,MAAMA,MAAK;AAAA,EACxE;AAAA,EAEA,aAAa,OAAqB,MAA+BA,QAAsB;AACrF,UAAM,aAAa,KAAK,QAAQ,cAAc;AAC9C,QAAI,aAAa,KAAK,KAAK,OAAO,KAAK,YAAY;AACjD,WAAK,OAAO,MAAM,kCAAkC;AACpD,aAAO,MAAM;AAAA,IACf;AAEA,UAAM,WAAW,KAAK,aAAa,OAAO,MAAMA,MAAK;AACrD,UAAM,QAAQ,KAAK,QAAQ,aAAa,KAAK,QAAQ,WAAW,QAAQ,IAAI;AAC5E,QAAI,CAAC,OAAO;AACV,WAAK,OAAO,MAAM,kCAAkC;AACpD,aAAO,MAAM;AAAA,IACf;AAEA,SAAK,UAAU,QAAQ,EAAE,MAAM,SAAS,SAAS,MAAM,CAAC;AACxD,WAAO,MAAM;AAAA,EACf;AAAA,EAEQ,aAAa,OAAqB,MAA+BA,QAA4B;AACnG,UAAM,OAAO,EAAE,GAAG,KAAK,QAAQ,MAAM,GAAGA,OAAM,MAAM,GAAG,MAAM,MAAM,GAAG,MAAM,KAAK;AACjF,UAAM,QAAQ,EAAE,GAAGA,OAAM,OAAO,GAAG,MAAM,OAAO,GAAG,MAAM,MAAM;AAE/D,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,MAAM,SAAS,MAAM,SAASA,OAAM,SAAS;AAAA,MACpD,SAAS,MAAM,WAAW,KAAK,QAAQ;AAAA,MACvC,aAAa,MAAM,eAAe,KAAK,QAAQ,eAAe;AAAA,MAC9D,MAAM,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO;AAAA,MAC5C,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,QAAQ;AAAA,MAC/C,MAAM,MAAM,QAAQA,OAAM;AAAA,MAC1B,UAAU,EAAE,GAAG,gBAAgB,GAAG,GAAGA,OAAM,UAAU,GAAG,MAAM,SAAS;AAAA,MACvE,aAAaA,OAAM,YAAY,SAAS,IAAI,CAAC,GAAGA,OAAM,WAAW,IAAI,MAAM;AAAA,MAC3E,aAAa,MAAM,eAAe,MAAM,eAAeA,OAAM;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,gBAAgB,SAAmC;AACjD,SAAK,UAAU,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,GAAG;AAAA,QACH,SAAS,QAAQ,WAAW,KAAK,QAAQ;AAAA,QACzC,aAAa,QAAQ,eAAe,KAAK,QAAQ,eAAe;AAAA,QAChE,MAAM,EAAE,GAAG,KAAK,QAAQ,MAAM,GAAG,QAAQ,KAAK;AAAA,MAChD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,SAA+B;AACzC,SAAK,UAAU,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,GAAG;AAAA,QACH,SAAS,QAAQ,WAAW,KAAK,QAAQ;AAAA,QACzC,aAAa,QAAQ,eAAe,KAAK,QAAQ,eAAe;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,SAAiC;AAC7C,SAAK,UAAU,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,SAAS,EAAE,GAAG,SAAS,SAAS,QAAQ,WAAW,KAAK,QAAQ,QAAQ;AAAA,IAC1E,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAsC;AAC1C,WAAO,KAAK,UAAU,MAAM,SAAS;AAAA,EACvC;AAAA,EAEA,MAAM,WAAsC;AAC1C,WAAO,KAAK,UAAU,MAAM,SAAS;AAAA,EACvC;AACF;;;AClHA,IAAM,sBAAsB;AAGrB,IAAM,YAAN,MAAgB;AAAA,EAOrB,YACmBC,SACjB,UAA4B,CAAC,GAC7B,YACA;AAHiB,kBAAAA;AAIjB,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,aAAa;AAClB,SAAK,OAAO,QAAQ,QAAQ;AAC5B,SAAK,WAAW,QAAQ;AAAA,EAC1B;AAAA,EAfiB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EAaR,QAAc;AACZ,QAAI,KAAK,MAAO;AAChB,SAAK,KAAK;AACV,SAAK,QAAQ,YAAY,MAAM,KAAK,KAAK,GAAG,KAAK,UAAU;AAC3D,eAAW,KAAK,KAAK;AAAA,EACvB;AAAA,EAEA,OAAa;AACX,QAAI,KAAK,OAAO;AACd,oBAAc,KAAK,KAAK;AACxB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,OAAa;AACnB,SAAK,OAAO,cAAc;AAAA,MACxB,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,WAAW,OAAO;AAAA,MAClB,UAAU,KAAK;AAAA,IACjB,CAAC;AAAA,EACH;AACF;;;AC5CA,IAAI,YAAY;AAOT,SAAS,sBAAsBC,SAAgB,UAA6B;AACjF,MAAI,UAAW;AACf,cAAY;AAEZ,MAAI,OAAO,GAAG;AACZ,YAAQ,GAAG,qBAAqB,CAAC,UAAiB;AAChD,MAAAA,QAAO,iBAAiB,OAAO,EAAE,OAAO,SAAS,MAAM,EAAE,WAAW,oBAAoB,EAAE,GAAG,SAAS,CAAC;AACvG,WAAKA,QAAO,MAAM,GAAK,EAAE,KAAK,MAAM;AAClC,YAAI,QAAQ,cAAc,mBAAmB,KAAK,GAAG;AACnD,kBAAQ,MAAM,KAAK;AACnB,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,YAAQ,GAAG,sBAAsB,CAAC,WAAoB;AACpD,MAAAA,QAAO,iBAAiB,QAAQ,EAAE,OAAO,SAAS,MAAM,EAAE,WAAW,qBAAqB,EAAE,GAAG,SAAS,CAAC;AAEzG,WAAKA,QAAO,MAAM,GAAK;AAAA,IACzB,CAAC;AAGD,YAAQ,GAAG,cAAc,MAAM;AAC7B,WAAKA,QAAO,MAAM,GAAK;AAAA,IACzB,CAAC;AACD;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,iBAAiB,SAAS,WAAS;AACxC,MAAAA,QAAO,iBAAiB,MAAM,SAAS,MAAM,SAAS,EAAE,MAAM,EAAE,WAAW,UAAU,EAAE,GAAG,SAAS,CAAC;AAAA,IACtG,CAAC;AACD,WAAO,iBAAiB,sBAAsB,WAAS;AACrD,MAAAA,QAAO,iBAAiB,MAAM,QAAQ,EAAE,MAAM,EAAE,WAAW,uBAAuB,EAAE,GAAG,SAAS,CAAC;AAAA,IACnG,CAAC;AACD,WAAO,iBAAiB,YAAY,MAAM;AACxC,WAAKA,QAAO,MAAM,GAAK;AAAA,IACzB,CAAC;AAAA,EACH;AACF;;;AC5CO,IAAM,QAAN,MAAM,OAAM;AAAA,EACjB,OAA+B,CAAC;AAAA,EAChC;AAAA,EACA,WAAoD,CAAC;AAAA,EACrD,QAAiC,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA,cAA4B,CAAC;AAAA,EAE7B,OAAO,KAAa,OAAqB;AACvC,SAAK,KAAK,GAAG,IAAI;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAAoC;AAC1C,WAAO,OAAO,KAAK,MAAM,IAAI;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAA8B;AACpC,SAAK,OAAO,QAAQ;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,MAAc,SAA+C;AACtE,QAAI,YAAY,MAAM;AACpB,aAAO,KAAK,SAAS,IAAI;AAAA,IAC3B,OAAO;AACL,WAAK,SAAS,IAAI,IAAI;AAAA,IACxB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,KAAa,OAAsB;AAC1C,SAAK,MAAM,GAAG,IAAI;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,QAAuC;AAC/C,WAAO,OAAO,KAAK,OAAO,MAAM;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAAuB;AAC9B,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,aAA6B;AAC1C,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,OAAwB,gBAA8B;AAClE,SAAK,YAAY,KAAK,EAAE,WAAW,OAAO,GAAG,GAAG,MAAM,CAAC;AACvD,QAAI,KAAK,YAAY,SAAS,gBAAgB;AAC5C,WAAK,YAAY,OAAO,GAAG,KAAK,YAAY,SAAS,cAAc;AAAA,IACrE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAAyB;AACvB,SAAK,cAAc,CAAC;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,QAAe;AACb,UAAM,OAAO,IAAI,OAAM;AACvB,SAAK,OAAO,EAAE,GAAG,KAAK,KAAK;AAC3B,SAAK,OAAO,KAAK,OAAO,EAAE,GAAG,KAAK,KAAK,IAAI;AAC3C,SAAK,WAAW,OAAO,YAAY,OAAO,QAAQ,KAAK,QAAQ,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC/F,SAAK,QAAQ,EAAE,GAAG,KAAK,MAAM;AAC7B,SAAK,QAAQ,KAAK;AAClB,SAAK,cAAc,KAAK,cAAc,CAAC,GAAG,KAAK,WAAW,IAAI;AAC9D,SAAK,cAAc,CAAC,GAAG,KAAK,WAAW;AACvC,WAAO;AAAA,EACT;AACF;;;AC/EA,SAAS,SAAiB;AACxB,SAAO,MAAM,EAAE,MAAM,GAAG,EAAE;AAC5B;AAEO,IAAM,OAAN,MAAW;AAAA,EAOhB,YACmB,aACR,cACA,IACA,aACT;AAJiB;AACR;AACA;AACA;AAAA,EACR;AAAA,EAXM,SAAS,OAAO;AAAA,EAChB,iBAAiB,OAAO;AAAA,EACjC,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EASA,UAAU,QAAsB;AAC9B,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,KAAa,OAAsB;AACzC,SAAK,OAAO,EAAE,GAAG,KAAK,MAAM,CAAC,GAAG,GAAG,MAAM;AACzC,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,IAAa,aAA4B;AAClD,WAAO,KAAK,YAAY,WAAW,KAAK,QAAQ,IAAI,WAAW;AAAA,EACjE;AAAA,EAEA,SAAe;AACb,QAAI,CAAC,KAAK,aAAc,MAAK,eAAe,OAAO;AAAA,EACrD;AAAA,EAEA,SAAmB;AACjB,WAAO;AAAA,MACL,SAAS,KAAK;AAAA,MACd,gBAAgB,KAAK;AAAA,MACrB,IAAI,KAAK;AAAA,MACT,aAAa,KAAK;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,iBAAiB,KAAK;AAAA,MACtB,WAAW,KAAK,gBAAgB,OAAO;AAAA,MACvC,MAAM,KAAK;AAAA,IACb;AAAA,EACF;AACF;AAMO,IAAM,cAAN,MAAkB;AAAA,EASvB,YACmBC,SACV,MACE,IACQ,UAAU,MAC3B;AAJiB,kBAAAA;AACV;AACE;AACQ;AAAA,EAChB;AAAA,EAbM,UAAU,MAAM;AAAA,EAChB,SAAS,OAAO;AAAA,EAChB,iBAAiB,OAAO;AAAA,EACjC,SAAS;AAAA,EACQ,QAAgB,CAAC;AAAA,EACjB,OAA+B,CAAC;AAAA,EACzC,WAAW;AAAA,EASnB,WAAW,cAAsB,IAAa,aAA4B;AACxE,UAAM,OAAO,IAAI,KAAK,MAAM,cAAc,IAAI,WAAW;AACzD,SAAK,MAAM,KAAK,IAAI;AACpB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,IAAa,aAA4B;AAClD,WAAO,KAAK,WAAW,KAAK,QAAQ,IAAI,WAAW;AAAA,EACrD;AAAA,EAEA,OAAO,KAAa,OAAqB;AACvC,SAAK,KAAK,GAAG,IAAI;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,QAAsB;AAC9B,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAAoB;AAC1B,SAAK,OAAO;AACZ,WAAO;AAAA,EACT;AAAA,EAEA,SAAe;AACb,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAEhB,eAAW,QAAQ,KAAK,MAAO,MAAK,OAAO;AAE3C,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,OAAQ;AACnC,UAAM,UAA8B;AAAA,MAClC,UAAU,KAAK;AAAA,MACf,MAAM,KAAK;AAAA,MACX,IAAI,KAAK;AAAA,MACT,QAAQ,KAAK;AAAA,MACb,iBAAiB,KAAK;AAAA,MACtB,WAAW,OAAO;AAAA,MAClB,OAAO,KAAK,MAAM,IAAI,UAAQ,KAAK,OAAO,CAAC;AAAA,MAC3C,MAAM,OAAO,KAAK,KAAK,IAAI,EAAE,SAAS,IAAI,KAAK,OAAO;AAAA,IACxD;AACA,SAAK,OAAO,gBAAgB,OAAO;AAAA,EACrC;AACF;;;ACzGO,SAAS,YAAYC,SAAgB,SAAiC;AAC3E,QAAM,YAAY,QAAQ,aAAa,MAAM;AAC7C,EAAAA,QAAO,YAAY;AAAA,IACjB,aAAa;AAAA,IACb,cAAc,QAAQ;AAAA,IACtB,QAAQ,QAAQ;AAAA,IAChB,aAAa,QAAQ;AAAA,IACrB,UAAU,QAAQ;AAAA,IAClB,UAAU,QAAQ;AAAA,EACpB,CAAC;AACD,SAAO;AACT;AAQA,eAAsB,gBACpBA,SACA,cACA,aACA,IACA,SACY;AACZ,QAAM,YAAY,YAAYA,SAAQ;AAAA,IACpC;AAAA,IACA,QAAQ;AAAA,IACR,UAAU,SAAS;AAAA,IACnB,UAAU,SAAS;AAAA,EACrB,CAAC;AACD,QAAM,YAAY,KAAK,IAAI;AAE3B,MAAI;AACF,UAAM,SAAS,MAAM,GAAG;AACxB,gBAAYA,SAAQ;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,IACrB,CAAC;AACD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,gBAAYA,SAAQ;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,IACrB,CAAC;AACD,iBAAa,KAAK;AAClB,UAAM;AAAA,EACR;AACF;;;ACrEA,IAAMC,mBAAkB,CAAC,KAAO,KAAO,IAAM;AAEtC,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACE,SACS,QACT;AACA,UAAM,OAAO;AAFJ;AAGT,SAAK,OAAO;AAAA,EACd;AACF;AASO,IAAM,aAAN,MAAiB;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAA4B;AACtC,SAAK,UAAU,QAAQ;AACvB,SAAK,MAAM,QAAQ;AACnB,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAEQ,UAAkC;AACxC,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK,GAAG;AAAA,IACnC;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,KAAK,SAA6B,QAAoD;AAC1F,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,SAAS;AAAA,MACnD,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,MACtB,MAAM,KAAK,UAAU,OAAO;AAAA,MAC5B;AAAA,IACF,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,gBAAgB,qBAAqB,SAAS,MAAM,KAAK,SAAS,MAAM;AAAA,IACpF;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU,OAAe,QAAgD;AAC7E,aAAS,UAAU,KAAK,WAAW;AACjC,UAAI;AACJ,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,SAAS,mBAAmB,KAAK,CAAC,IAAI;AAAA,UAChF,QAAQ;AAAA,UACR,SAAS,KAAK,QAAQ;AAAA,UACtB,MAAM,KAAK,UAAU,MAAM;AAAA,QAC7B,CAAC;AACD,YAAI,SAAS,GAAI;AACjB,YAAI,SAAS,UAAU,OAAO,SAAS,SAAS,OAAO,SAAS,WAAW,KAAK;AAC9E,gBAAM,IAAI,gBAAgB,0BAA0B,SAAS,MAAM,KAAK,SAAS,MAAM;AAAA,QACzF;AACA,oBAAY,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE;AAAA,MACjD,SAAS,OAAO;AACd,YAAI,iBAAiB,gBAAiB,OAAM;AAC5C,oBAAY;AAAA,MACd;AAEA,YAAM,QAAQA,iBAAgB,OAAO;AACrC,UAAI,UAAU,QAAW;AACvB,cAAM,IAAI,MAAM,iBAAiB,KAAK,gCAA6B,OAAO,SAAS,CAAC,EAAE;AAAA,MACxF;AACA,WAAK,OAAO,KAAK,0BAA0B,KAAK,KAAK,OAAO,SAAS,CAAC,eAAe,KAAK,IAAI;AAC9F,YAAM,MAAM,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;AChFA,IAAM,gCAAgC;AACtC,IAAM,wBAAwB;AAC9B,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAQnB,IAAM,cAAN,MAAkB;AAAA,EAYvB,YACmB,KACA,OACjB,MACiB,QACjB,iBACA;AALiB;AACA;AAEA;AAGjB,SAAK,kBAAkB,mBAAmB;AAC1C,SAAK,UAAU;AAAA,MACb;AAAA,MACA;AAAA,MACA,KAAK,CAAC,OAAO,YAAY,KAAK,IAAI,OAAO,OAAO;AAAA,MAChD,QAAQ,KAAK,gBAAgB;AAAA,IAC/B;AAAA,EACF;AAAA,EAzBS;AAAA,EAED,SAAwB,CAAC;AAAA,EACzB,cAAc;AAAA,EACd,eAAe;AAAA,EACf,OAAO;AAAA,EACP,QAAuB,QAAQ,QAAQ;AAAA,EACvC;AAAA,EACS,kBAAkB,IAAI,gBAAgB;AAAA,EACtC;AAAA,EAkBjB,IAAI,SAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,QAAc;AACZ,QAAI,CAAC,KAAK,gBAAgB,OAAO,QAAS,MAAK,gBAAgB,MAAM;AAAA,EACvE;AAAA,EAEQ,IAAI,OAAoB,SAAuB;AACrD,QAAI,KAAK,KAAM;AACf,QAAI,KAAK,eAAe,kBAAkB;AACxC,WAAK;AACL;AAAA,IACF;AACA,SAAK;AACL,UAAM,YACJ,QAAQ,SAAS,wBAAwB,GAAG,QAAQ,MAAM,GAAG,qBAAqB,CAAC,sBAAiB;AACtG,SAAK,OAAO,KAAK,EAAE,IAAI,OAAO,GAAG,OAAO,SAAS,UAAU,CAAC;AAE5D,QAAI,KAAK,OAAO,UAAU,mBAAmB;AAC3C,WAAK,UAAU;AAAA,IACjB,OAAO;AACL,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,MAAO;AAChB,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,QAAQ;AACb,WAAK,UAAU;AAAA,IACjB,GAAG,KAAK,eAAe;AACvB,eAAW,KAAK,KAAK;AAAA,EACvB;AAAA,EAEQ,kBAAwB;AAC9B,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,WAA0B;AAChC,UAAM,OAAO,KAAK,OAAO,OAAO,GAAG,KAAK,OAAO,MAAM;AACrD,QAAI,KAAK,eAAe,GAAG;AACzB,WAAK,KAAK;AAAA,QACR,IAAI,OAAO;AAAA,QACX,OAAO;AAAA,QACP,SAAS,GAAG,KAAK,YAAY,gCAAgC,gBAAgB;AAAA,MAC/E,CAAC;AACD,WAAK,eAAe;AAAA,IACtB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,YAAkB;AACxB,SAAK,gBAAgB;AACrB,QAAI,KAAK,QAAQ,KAAK,OAAO,WAAW,EAAG;AAC3C,UAAM,OAAO,KAAK,OAAO,OAAO,GAAG,KAAK,OAAO,MAAM;AACrD,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,oBAAoB;AACxD,WAAK,QAAQ,EAAE,QAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAAA,IACjF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,gBAAkC;AACtC,SAAK,QAAQ,EAAE,QAAQ,UAAU,CAAC;AAClC,UAAM,KAAK;AACX,WAAO,CAAC,KAAK;AAAA,EACf;AAAA,EAEA,gBAAsB;AACpB,SAAK,gBAAgB;AACrB,SAAK,QAAQ,EAAE,QAAQ,aAAa,MAAM,KAAK,SAAS,EAAE,CAAC;AAAA,EAC7D;AAAA,EAEA,cAAc,OAA8B;AAC1C,SAAK,gBAAgB;AACrB,SAAK,QAAQ,EAAE,QAAQ,UAAU,OAAO,MAAM,KAAK,SAAS,EAAE,CAAC;AAAA,EACjE;AAAA;AAAA,EAGA,WAA0B;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,QAAQ,QAAuC;AACrD,QAAI,KAAK,KAAM;AACf,SAAK,QAAQ,KAAK,MAAM,KAAK,YAAY;AACvC,UAAI,KAAK,KAAM;AACf,YAAM,UAAU,OAAO,QAAQ,OAAO,KAAK,WAAW,IAAI,EAAE,GAAG,QAAQ,MAAM,OAAU,IAAI;AAC3F,UAAI;AACF,cAAM,KAAK,IAAI,UAAU,KAAK,OAAO,OAAO;AAAA,MAC9C,SAAS,OAAO;AACd,YAAI,iBAAiB,oBAAoB,MAAM,WAAW,OAAO,MAAM,WAAW,MAAM;AACtF,eAAK,OAAO;AACZ,eAAK,MAAM;AACX,eAAK,SAAS,CAAC;AACf,eAAK,OAAO,KAAK,OAAO,KAAK,KAAK,0DAAqD;AACvF;AAAA,QACF;AACA,aAAK,OAAO,MAAM,iBAAiB,KAAK,KAAK,aAAa,KAAK;AAAA,MACjE;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACjJA,IAAM,2BAA2B;AACjC,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB;AACxB,IAAM,uBAAuB,CAAC,KAAO,KAAO,IAAM;AAClD,IAAM,2BAA2B;AAKjC,SAAS,WAA+B;AACtC,MAAI,CAAC,OAAO,EAAG,QAAO;AACtB,SAAO,QAAQ,IAAI,YAAY,QAAQ,IAAI,gBAAgB;AAC7D;AAOO,IAAM,eAAN,MAAmB;AAAA,EAkBxB,YACmB,SACAC,WACjB;AAFiB;AACA,oBAAAA;AAEjB,SAAK,SAAS,WAAW,QAAQ,SAAS,OAAO,kBAAkB;AACnE,UAAM,SAAS,cAAc,SAAS,kBAAkB;AACxD,SAAK,MAAM,IAAI,WAAW,EAAE,SAAS,OAAO,gBAAgB,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO,CAAC;AAClG,SAAK,iBAAiB,KAAK,IAAI,sBAAsB,QAAQ,kBAAkB,wBAAwB;AACvG,SAAK,cAAc,KAAK,IAAI,iBAAiB,KAAK,IAAI,GAAG,QAAQ,eAAe,CAAC,CAAC;AAClF,SAAK,aAAa,QAAQ;AAC1B,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,qBAAqB,QAAQ;AAClC,SAAK,OAAO,MAAM,sBAAsB,EAAE,SAAS,OAAO,eAAe,CAAC;AAAA,EAC5E;AAAA,EA9BS;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,QAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EACjB,aAAa,oBAAI,IAAmB;AAAA,EACpC,YAAY,oBAAI,IAAiB;AAAA,EAiBlD,IAAI,cAAsB;AACxB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,UAAU,UAAW;AAC9B,QAAI,KAAK,UAAU,YAAY;AAC7B,YAAM,IAAI,MAAM,gFAA2E;AAAA,IAC7F;AACA,QAAI,KAAK,SAAS,SAAS,GAAG;AAC5B,YAAM,IAAI,MAAM,mFAA8E;AAAA,IAChG;AACA,SAAK,QAAQ;AACb,SAAK,OAAO,MAAM,4BAA4B,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG;AACrF,SAAK,SAAS,CAAC;AAAA,EACjB;AAAA;AAAA,EAGA,MAAM,KAAK,YAAY,KAA0B;AAC/C,QAAI,KAAK,UAAU,OAAQ,QAAO;AAClC,SAAK,QAAQ;AACb,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AACA,SAAK,WAAW,MAAM;AAEtB,UAAM,MAAM,QAAQ,WAAW,CAAC,GAAG,KAAK,UAAU,CAAC,EAAE,KAAK,MAAM,IAAI;AACpE,UAAM,WAAW,YAAY,IAAI,MAAM,QAAQ,KAAK,CAAC,KAAK,MAAM,SAAS,EAAE,KAAK,MAAM,KAAK,CAAC,CAAC,IAAI;AACjG,QAAI,CAAC,YAAY,KAAK,WAAW,OAAO,GAAG;AACzC,WAAK,OAAO,KAAK,GAAG,KAAK,WAAW,IAAI,2CAAkC,SAAS,gCAA2B;AAC9G,iBAAW,YAAY,KAAK,UAAW,UAAS,MAAM;AAAA,IACxD;AACA,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,SAAS,SAAuB;AACtC,QAAI,KAAK,UAAU,aAAa,KAAK,MAAO;AAC5C,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,QAAQ;AACb,WAAK,KAAK,KAAK;AAAA,IACjB,GAAG,OAAO;AAAA,EACZ;AAAA,EAEA,MAAc,OAAsB;AAClC,QAAI,KAAK,UAAU,UAAW;AAC9B,QAAI,KAAK,WAAW,QAAQ,KAAK,aAAa;AAC5C,WAAK,SAAS,KAAK,cAAc;AACjC;AAAA,IACF;AAEA,SAAK,YAAY,IAAI,gBAAgB;AACrC,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,IAAI;AAAA,QAC9B;AAAA,UACE,OAAO;AAAA;AAAA;AAAA,YAGL,aAAa,KAAK;AAAA,YAClB,SAAS;AAAA,YACT,MAAM,SAAS;AAAA,YACf,OAAO,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,UACjC;AAAA,UACA,KAAK,KAAK,IAAI,iBAAiB,KAAK,cAAc,KAAK,WAAW,IAAI;AAAA,UACtE,OAAO,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,QACjC;AAAA,QACA,KAAK,UAAU;AAAA,MACjB;AACA,WAAK,sBAAsB;AAC3B,WAAK,0BAA0B;AAE/B,iBAAW,OAAO,SAAS,MAAM;AAC/B,aAAK,SAAS,GAAG;AAAA,MACnB;AAEA,WAAK,SAAS,SAAS,KAAK,SAAS,IAAI,IAAI,KAAK,cAAc;AAAA,IAClE,SAAS,OAAO;AACd,UAAI,KAAK,UAAU,UAAW;AAC9B,WAAK,SAAS,KAAK,oBAAoB,KAAK,CAAC;AAAA,IAC/C,UAAE;AACA,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,oBAAoB,OAAwB;AAClD,QAAI,iBAAiB,mBAAmB,MAAM,WAAW,KAAK;AAE5D,WAAK;AACL,UAAI,KAAK,4BAA4B,KAAK,KAAK,0BAA0B,OAAO,GAAG;AACjF,aAAK,OAAO,MAAM,0GAA0F;AAAA,MAC9G;AACA,aAAO,KAAK,IAAI,KAAK,gBAAgB,wBAAwB;AAAA,IAC/D;AACA,SAAK;AACL,UAAM,SAAS,qBAAqB,KAAK,IAAI,KAAK,sBAAsB,GAAG,qBAAqB,SAAS,CAAC,CAAC;AAC3G,UAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,QAAQ,CAAC,GAAG,KAAK,IAAI,KAAK,gBAAgB,IAAM,CAAC;AACjF,SAAK,OAAO,KAAK,gBAAgB,OAAO,KAAK,CAAC,8BAA2B,KAAK,IAAI;AAClF,WAAO;AAAA,EACT;AAAA,EAEQ,SAAS,KAAiC;AAChD,UAAM,UAAU,KAAK,WAAW,GAAG,EAChC,MAAM,WAAS,KAAK,OAAO,MAAM,0BAA0B,IAAI,EAAE,KAAK,KAAK,CAAC,EAC5E,QAAQ,MAAM;AACb,WAAK,WAAW,OAAO,OAAO;AAC9B,UAAI,KAAK,UAAU,UAAW,MAAK,SAAS,CAAC;AAAA,IAC/C,CAAC;AACH,SAAK,WAAW,IAAI,OAAO;AAAA,EAC7B;AAAA,EAEA,MAAc,WAAW,KAA0C;AACjE,UAAM,WAAW,IAAI,YAAY,KAAK,KAAK,IAAI,IAAI,IAAI,MAAM,KAAK,QAAQ,KAAK,kBAAkB;AACjG,SAAK,UAAU,IAAI,QAAQ;AAC3B,QAAI;AACF,YAAM,UAAU,KAAK,SAAS,IAAI,IAAI,IAAI;AAC1C,UAAI,CAAC,SAAS;AAEZ,iBAAS,cAAc;AAAA,UACrB,MAAM;AAAA,UACN,SAAS,uCAAoC,IAAI,IAAI;AAAA,QACvD,CAAC;AACD,cAAM,SAAS,SAAS;AACxB;AAAA,MACF;AAEA,YAAM,KAAK,MAAM,SAAS,cAAc;AACxC,UAAI,CAAC,IAAI;AACP,aAAK,OAAO,MAAM,OAAO,IAAI,EAAE,6DAAqD;AACpF;AAAA,MACF;AAEA,WAAK,OAAO,MAAM,kBAAkB,IAAI,EAAE,KAAK,IAAI,IAAI,GAAG;AAC1D,UAAI;AACF,cAAM,KAAK,kBAAkB,SAAS,KAAK,QAAQ;AACnD,iBAAS,cAAc;AACvB,aAAK,OAAO,MAAM,OAAO,IAAI,EAAE,eAAY;AAAA,MAC7C,SAAS,OAAO;AACd,iBAAS,cAAc,WAAW,KAAK,CAAC;AACxC,aAAK,OAAO,MAAM,OAAO,IAAI,EAAE,YAAY,OAAO,KAAK,CAAC,EAAE;AAAA,MAC5D;AACA,YAAM,SAAS,SAAS;AAAA,IAC1B,UAAE;AACA,WAAK,UAAU,OAAO,QAAQ;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAc,kBACZ,SACA,KACA,UACe;AACf,UAAM,aAAa,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,IAAI,QAAQ,SAAS,OAAO,CAAC;AACrF,QAAI,CAAC,KAAK,iBAAiB,KAAK,iBAAiB,GAAG;AAClD,YAAM;AACN;AAAA,IACF;AAEA,UAAM,YAAY,KAAK;AACvB,UAAM,UAAU,MAAM,SAAS,EAAE,KAAK,MAAM,gBAAgB;AAC5D,UAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,YAAY,OAAO,CAAC;AACxD,QAAI,YAAY,iBAAkB;AAGlC,aAAS,MAAM;AACf,eACG,KAAK,MAAM,KAAK,OAAO,KAAK,OAAO,IAAI,EAAE,kCAAkC,SAAS,IAAI,CAAC,EACzF,MAAM,MAAM,KAAK,OAAO,KAAK,OAAO,IAAI,EAAE,gCAAgC,SAAS,sBAAsB,CAAC;AAC7G,UAAM,OAAO,OAAO,IAAI,MAAM,mBAAgB,SAAS,6CAA6C,GAAG;AAAA,MACrG,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;AAEA,IAAM,mBAAmB,uBAAO,cAAc;AAE9C,IAAM,0BAA0B;AAChC,IAAM,wBAAwB;AAE9B,SAAS,SAAS,OAAe,KAAqB;AACpD,SAAO,MAAM,SAAS,MAAM,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC,sBAAiB;AACrE;AAEA,SAAS,WAAW,OAAiC;AACnD,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,SAAS,SAAS,MAAM,SAAS,uBAAuB;AAAA,MACxD,OAAO,MAAM,QAAQ,SAAS,MAAM,OAAO,qBAAqB,IAAI;AAAA,IACtE;AAAA,EACF;AACA,SAAO,EAAE,SAAS,SAAS,OAAO,KAAK,GAAG,uBAAuB,EAAE;AACrE;;;ACjPA,IAAM,0BAA0B;AAEhC,IAAI;AACJ,IAAI,QAAQ,IAAI,MAAM;AACtB,IAAI;AACJ,IAAI;AACJ,IAAM,WAAW,oBAAI,IAAgC;AACrD,IAAI,wBAAwB;AAGrB,SAAS,KAAK,SAA4B;AAC/C,MAAI,QAAQ;AACV,WAAO,OAAO,KAAK,sEAAiE;AACpF,eAAW,KAAK;AAChB,gBAAY;AAAA,EACd;AACA,MAAI,OAAO;AACT,SAAK,MAAM,KAAK,CAAC;AACjB,YAAQ;AAAA,EACV;AACA,0BAAwB;AAExB,WAAS,IAAI,OAAO,OAAO;AAE3B,MAAI,QAAQ,qBAAqB,OAAO;AACtC,0BAAsB,QAAQ,MAAM,KAAK;AAAA,EAC3C;AAEA,MAAI,QAAQ,WAAW;AACrB,UAAM,mBAAmB,QAAQ,cAAc,OAAO,CAAC,IAAI,QAAQ;AACnE,gBAAY,IAAI,UAAU,QAAQ,kBAAkB,QAAQ,UAAU;AACtE,cAAU,MAAM;AAAA,EAClB;AAEA,MAAI,QAAQ,SAAS;AACnB,UAAM,iBAAiB,QAAQ,YAAY,OAAO,CAAC,IAAI,QAAQ;AAC/D,YAAQ,IAAI;AAAA,MACV,EAAE,GAAG,gBAAgB,cAAc,QAAQ,cAAc,SAAS,QAAQ,SAAS,YAAY,QAAQ,YAAY,OAAO,QAAQ,MAAM;AAAA,MACxI;AAAA,IACF;AAAA,EACF;AAEA,SAAO,OAAO,MAAM,gBAAgB,EAAE,UAAU,OAAO,OAAO,eAAe,CAAC;AAChF;AAEO,SAAS,YAAgC;AAC9C,SAAO;AACT;AAGO,SAAS,iBAAiB,OAAgB,MAAwC;AACvF,SAAO,QAAQ,iBAAiB,OAAO,MAAM,KAAK;AACpD;AAEO,SAAS,eAAe,SAAiB,QAAkB,QAAQ,MAAwC;AAChH,SAAO,QAAQ,eAAe,SAAS,OAAO,MAAM,KAAK;AAC3D;AAGO,SAAS,cAAc,OAA8B;AAC1D,QAAM,cAAc,OAAO,QAAQ,QAAQ,kBAAkB,uBAAuB;AACtF;AAEO,SAAS,OAAO,KAAa,OAAqB;AACvD,QAAM,OAAO,KAAK,KAAK;AACzB;AAEO,SAAS,QAAQ,MAAoC;AAC1D,QAAM,QAAQ,IAAI;AACpB;AAEO,SAAS,QAAQ,MAA8B;AACpD,QAAM,QAAQ,IAAI;AACpB;AAEO,SAAS,WAAW,MAAc,SAA+C;AACtF,QAAM,WAAW,MAAM,OAAO;AAChC;AAEO,SAAS,SAAS,KAAa,OAAsB;AAC1D,QAAM,SAAS,KAAK,KAAK;AAC3B;AAGO,SAAS,UAAa,UAAkC;AAC7D,QAAM,WAAW;AACjB,UAAQ,SAAS,MAAM;AACvB,MAAI;AACF,WAAO,SAAS,KAAK;AAAA,EACvB,UAAE;AACA,YAAQ;AAAA,EACV;AACF;AAGO,SAAS,iBAAiB,MAAc,IAA0B;AACvE,QAAM,OAAO,QAAQ,QAAQ,oBAAoB;AACjD,QAAM,UAAU,QAAQ,KAAK,KAAK,OAAO,IAAI;AAC7C,SAAO,IAAI,YAAY,QAAQ,MAAM,IAAI,OAAO;AAClD;AAGO,SAAS,QAAQ,SAA6C;AACnE,SAAO,SAAS,YAAY,QAAQ,OAAO,IAAI;AACjD;AAGA,eAAsB,YACpB,aACA,IACA,SACY;AACZ,MAAI,CAAC,OAAQ,QAAO,GAAG;AACvB,SAAO;AAAA,IACL;AAAA,IACA,WAAS,iBAAiB,OAAO,EAAE,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;AAAA,IACnE;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,MAAM,WAAsC;AAC1D,SAAO,SAAS,OAAO,MAAM,SAAS,IAAI,QAAQ,QAAQ,IAAI;AAChE;AAGO,SAAS,SAAsC,MAAc,SAAsC;AACxG,MAAI,SAAS,IAAI,IAAI,GAAG;AACtB,KAAC,OAAO,UAAU,QAAQ,SAAS,KAAK,aAAa,IAAI,sCAAsC;AAAA,EACjG;AACA,MAAI,UAAU,CAAC,SAAS,CAAC,uBAAuB;AAC9C,4BAAwB;AACxB,WAAO,OAAO;AAAA,MACZ,aAAa,IAAI;AAAA,IACnB;AAAA,EACF;AACA,WAAS,IAAI,MAAM,OAA6B;AAClD;AAMO,SAAS,QAAc;AAC5B,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,6GAA+F;AAAA,EACjH;AACA,QAAM,MAAM;AACd;AAGO,SAAS,KAAK,WAAsC;AACzD,SAAO,QAAQ,MAAM,KAAK,SAAS,IAAI,QAAQ,QAAQ,IAAI;AAC7D;AAMA,eAAsB,MAAM,WAAsC;AAChE,QAAM,eAAe,QAAQ,MAAM,MAAM,KAAK,SAAS,IAAI;AAC3D,aAAW,KAAK;AAChB,cAAY;AACZ,QAAM,eAAe,SAAS,MAAM,OAAO,MAAM,SAAS,IAAI;AAC9D,SAAO,gBAAgB;AACzB;","names":["scope","client","client","client","client","RETRY_DELAYS_MS","registry"]}
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/stacktrace.ts","../src/utils.ts","../src/eventbuilder.ts","../src/transport.ts","../src/client.ts","../src/heartbeat.ts","../src/instrument.ts","../src/scope.ts","../src/transaction.ts","../src/checkin.ts","../src/manager/api.ts","../src/manager/context.ts","../src/manager/agent.ts","../src/core.ts"],"sourcesContent":["/** API oficial da Hobots — o SDK sempre fala com ela em produção. */\nexport const DEFAULT_BASE_URL = 'https://api2.hobots.app';\n\nexport interface ResolvedConfig {\n /** Client Secret do projeto (enviado como Authorization: Bearer, nunca na URL) */\n key: string;\n baseUrl: string;\n /** Ingestão do Monitor: <baseUrl>/v1/ingest */\n ingestEndpoint: string;\n /** API do Manager: <baseUrl>/v1/manager */\n managerBaseUrl: string;\n}\n\ninterface ConfigInput {\n clientSecret: string;\n}\n\n/**\n * Override de desenvolvimento via env HOBOTS_API_URL — a única forma de apontar\n * o SDK para outro host. Em produção a URL é sempre a API oficial.\n */\nfunction envBaseUrl(): string | undefined {\n // browser: `process` pode não existir\n if (typeof process === 'undefined' || !process.env) return undefined;\n return process.env.HOBOTS_API_URL?.trim() || undefined;\n}\n\n/** Resolve o clientSecret nos endpoints do Monitor e do Manager. */\nexport function resolveConfig(options: ConfigInput, prefix = '[hobots]'): ResolvedConfig {\n const key = options.clientSecret?.trim();\n if (!key) {\n throw new Error(`${prefix} clientSecret ausente — copie o Client Secret do projeto em Configurações → Projetos`);\n }\n\n const baseUrl = (envBaseUrl() ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n try {\n new URL(baseUrl);\n } catch {\n throw new Error(`${prefix} HOBOTS_API_URL inválida: \"${baseUrl}\" — esperado ex.: http://localhost:3001`);\n }\n\n return {\n key,\n baseUrl,\n ingestEndpoint: `${baseUrl}/v1/ingest`,\n managerBaseUrl: `${baseUrl}/v1/manager`,\n };\n}\n","import type { StackFrame } from './protocol';\n\nconst MAX_FRAMES = 50;\n\n// \" at fn (file:1:2)\" | \" at file:1:2\" | \" at async fn (file:1:2)\"\nconst FRAME_RE = /^\\s*at\\s+(?:async\\s+)?(?:(.+?)\\s+\\()?(.+?)\\)?$/;\nconst LOCATION_RE = /^(.*?):(\\d+):(\\d+)$/;\n\nfunction isInApp(filename: string | undefined): boolean {\n if (!filename) return false;\n if (filename.startsWith('node:')) return false;\n if (filename.startsWith('internal/')) return false;\n if (filename.includes('node_modules')) return false;\n if (filename === '<anonymous>') return false;\n return true;\n}\n\n/** Converte um `error.stack` do V8 em frames (ordem innermost-first, como o V8 imprime). */\nexport function parseStacktrace(stack: string | undefined | null): StackFrame[] {\n if (!stack) return [];\n\n const frames: StackFrame[] = [];\n for (const line of stack.split('\\n')) {\n if (frames.length >= MAX_FRAMES) break;\n const match = FRAME_RE.exec(line);\n if (!match || !line.trimStart().startsWith('at ')) continue;\n\n const [, fn, location] = match;\n const loc = LOCATION_RE.exec(location ?? '');\n const filename = loc ? loc[1] : location;\n frames.push({\n function: fn || '<anonymous>',\n filename: filename || undefined,\n lineno: loc?.[2] ? Number(loc[2]) : undefined,\n colno: loc?.[3] ? Number(loc[3]) : undefined,\n in_app: isInApp(filename),\n });\n }\n return frames;\n}\n","export const SDK_NAME = 'hobots';\nexport const SDK_VERSION = '1.0.0';\n\nexport function isNode(): boolean {\n return typeof process !== 'undefined' && typeof process.versions?.node === 'string';\n}\n\n/** uuid v4 sem hífens (32 hex). Fallback para contextos sem crypto.randomUUID. */\nexport function uuid4(): string {\n const cryptoRef = (globalThis as { crypto?: Crypto }).crypto;\n if (cryptoRef && typeof cryptoRef.randomUUID === 'function') {\n return cryptoRef.randomUUID().replace(/-/g, '');\n }\n let out = '';\n for (let i = 0; i < 32; i++) {\n out += Math.floor(Math.random() * 16).toString(16);\n }\n return out;\n}\n\nexport function nowISO(): string {\n return new Date().toISOString();\n}\n\n/** Timers não devem segurar o processo Node aberto. */\nexport function unrefTimer(timer: unknown): void {\n (timer as { unref?: () => void } | undefined)?.unref?.();\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n const timer = setTimeout(resolve, ms);\n unrefTimer(timer);\n });\n}\n\nexport interface Logger {\n debug: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n}\n\nconst PREFIX = '[hobots-monitor]';\n\nexport function makeLogger(enabled: boolean, prefix: string = PREFIX): Logger {\n return {\n debug: (...args) => enabled && console.debug(prefix, ...args),\n warn: (...args) => enabled && console.warn(prefix, ...args),\n error: (...args) => console.error(prefix, ...args),\n };\n}\n","import type { EventPayload, Severity } from './protocol';\nimport { parseStacktrace } from './stacktrace';\nimport { nowISO, uuid4 } from './utils';\n\nfunction safeString(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n const json = JSON.stringify(value);\n if (json && json !== '{}') return json;\n } catch {\n // objetos circulares etc. caem no String()\n }\n return String(value);\n}\n\nexport function eventFromException(error: unknown, level: Severity = 'error'): EventPayload {\n let type: string;\n let value: string;\n let frames = [] as ReturnType<typeof parseStacktrace>;\n\n if (error instanceof Error) {\n type = error.name || 'Error';\n value = error.message;\n frames = parseStacktrace(error.stack);\n } else {\n type = 'NonError';\n value = safeString(error);\n }\n\n return {\n event_id: uuid4(),\n timestamp: nowISO(),\n level,\n exception: {\n type,\n value,\n ...(frames.length > 0 ? { stacktrace: { frames } } : {}),\n },\n };\n}\n\nexport function eventFromMessage(message: string, level: Severity = 'info'): EventPayload {\n return {\n event_id: uuid4(),\n timestamp: nowISO(),\n level,\n message,\n };\n}\n","import type { Envelope, EnvelopeItem } from './protocol';\nimport { SDK_NAME, SDK_VERSION, nowISO, sleep, unrefTimer, type Logger } from './utils';\n\nconst RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\nconst DEFAULT_FLUSH_INTERVAL_MS = 2_000;\nconst DEFAULT_MAX_BATCH_SIZE = 10;\nconst DEFAULT_MAX_QUEUE_SIZE = 200;\n\nexport interface TransportOptions {\n endpoint: string;\n /** Chave secreta do projeto — enviada como Authorization: Bearer */\n key: string;\n logger: Logger;\n flushIntervalMs?: number;\n maxBatchSize?: number;\n maxQueueSize?: number;\n}\n\n/** Fila em memória com batch + retry. Envia envelopes via fetch (Node 18+/browser). */\nexport class Transport {\n private readonly endpoint: string;\n private readonly key: string;\n private readonly logger: Logger;\n private readonly flushIntervalMs: number;\n private readonly maxBatchSize: number;\n private readonly maxQueueSize: number;\n\n private buffer: EnvelopeItem[] = [];\n private timer: ReturnType<typeof setTimeout> | undefined;\n private pending = new Set<Promise<void>>();\n private closed = false;\n\n constructor(options: TransportOptions) {\n this.endpoint = options.endpoint;\n this.key = options.key;\n this.logger = options.logger;\n this.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.maxBatchSize = options.maxBatchSize ?? DEFAULT_MAX_BATCH_SIZE;\n this.maxQueueSize = options.maxQueueSize ?? DEFAULT_MAX_QUEUE_SIZE;\n }\n\n enqueue(item: EnvelopeItem): void {\n if (this.closed) {\n this.logger.warn('transport fechado, item descartado:', item.type);\n return;\n }\n if (this.buffer.length >= this.maxQueueSize) {\n this.buffer.shift();\n this.logger.warn('fila cheia, item mais antigo descartado');\n }\n this.buffer.push(item);\n\n if (this.buffer.length >= this.maxBatchSize) {\n void this.flushBuffer();\n } else {\n this.schedule();\n }\n }\n\n private schedule(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n void this.flushBuffer();\n }, this.flushIntervalMs);\n unrefTimer(this.timer);\n }\n\n private flushBuffer(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n if (this.buffer.length === 0) return Promise.resolve();\n\n const items = this.buffer.splice(0, this.buffer.length);\n const envelope: Envelope = {\n sdk: { name: SDK_NAME, version: SDK_VERSION },\n sent_at: nowISO(),\n items,\n };\n\n const request: Promise<void> = this.sendWithRetry(envelope).finally(() => {\n this.pending.delete(request);\n });\n this.pending.add(request);\n return request;\n }\n\n private async sendWithRetry(envelope: Envelope): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n try {\n const response = await fetch(this.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${this.key}` },\n body: JSON.stringify(envelope),\n });\n if (response.ok) {\n this.logger.debug(`envelope enviado (${envelope.items.length} itens)`);\n return;\n }\n // 4xx (exceto 429) não é recuperável — descarta sem retry\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n this.logger.error(`envelope rejeitado (HTTP ${response.status}), descartado`);\n return;\n }\n throw new Error(`HTTP ${response.status}`);\n } catch (error) {\n const delay = RETRY_DELAYS_MS[attempt];\n if (delay === undefined) {\n this.logger.error('envelope descartado após retries:', error);\n return;\n }\n this.logger.warn(`falha no envio (${String(error)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n }\n }\n\n /** Envia o que estiver na fila e aguarda envios em andamento (até timeoutMs). */\n async flush(timeoutMs = 5_000): Promise<boolean> {\n void this.flushBuffer();\n const all = Promise.allSettled([...this.pending]).then(() => true);\n return Promise.race([all, sleep(timeoutMs).then(() => false)]);\n }\n\n async close(timeoutMs = 5_000): Promise<boolean> {\n const result = await this.flush(timeoutMs);\n this.closed = true;\n return result;\n }\n}\n","import type { CheckInPayload, EventPayload, HeartbeatPayload, Severity, TransactionPayload } from './protocol';\nimport type { CaptureHint, InitOptions } from './types';\nimport { resolveConfig, type ResolvedConfig } from './config';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport type { Scope } from './scope';\nimport { Transport } from './transport';\nimport { isNode, makeLogger, type Logger } from './utils';\n\nfunction runtimeContexts(): Record<string, Record<string, unknown>> {\n if (isNode()) {\n return {\n runtime: { name: 'node', version: process.version },\n os: { name: process.platform, arch: process.arch },\n };\n }\n return { runtime: { name: 'browser' } };\n}\n\nexport class Client {\n readonly options: InitOptions;\n readonly config: ResolvedConfig;\n readonly logger: Logger;\n private readonly transport: Transport;\n\n constructor(options: InitOptions) {\n this.options = options;\n this.logger = makeLogger(!!options.debug);\n this.config = resolveConfig(options);\n this.transport = new Transport({\n endpoint: this.config.ingestEndpoint,\n key: this.config.key,\n logger: this.logger,\n flushIntervalMs: options.flushIntervalMs,\n maxBatchSize: options.maxBatchSize,\n });\n }\n\n captureException(error: unknown, hint: CaptureHint | undefined, scope: Scope): string {\n return this.captureEvent(eventFromException(error, hint?.level ?? 'error'), hint, scope);\n }\n\n captureMessage(message: string, level: Severity, hint: CaptureHint | undefined, scope: Scope): string {\n return this.captureEvent(eventFromMessage(message, level), hint, scope);\n }\n\n captureEvent(event: EventPayload, hint: CaptureHint | undefined, scope: Scope): string {\n const sampleRate = this.options.sampleRate ?? 1;\n if (sampleRate < 1 && Math.random() >= sampleRate) {\n this.logger.debug('evento descartado por sampleRate');\n return event.event_id;\n }\n\n const prepared = this.prepareEvent(event, hint, scope);\n const final = this.options.beforeSend ? this.options.beforeSend(prepared) : prepared;\n if (!final) {\n this.logger.debug('evento descartado por beforeSend');\n return event.event_id;\n }\n\n this.transport.enqueue({ type: 'event', payload: final });\n return final.event_id;\n }\n\n private prepareEvent(event: EventPayload, hint: CaptureHint | undefined, scope: Scope): EventPayload {\n const tags = { ...this.options.tags, ...scope.tags, ...event.tags, ...hint?.tags };\n const extra = { ...scope.extra, ...event.extra, ...hint?.extra };\n\n return {\n ...event,\n level: hint?.level ?? event.level ?? scope.level ?? 'error',\n release: event.release ?? this.options.release,\n environment: event.environment ?? this.options.environment ?? 'production',\n tags: Object.keys(tags).length > 0 ? tags : undefined,\n extra: Object.keys(extra).length > 0 ? extra : undefined,\n user: event.user ?? scope.user,\n contexts: { ...runtimeContexts(), ...scope.contexts, ...event.contexts },\n breadcrumbs: scope.breadcrumbs.length > 0 ? [...scope.breadcrumbs] : event.breadcrumbs,\n fingerprint: hint?.fingerprint ?? event.fingerprint ?? scope.fingerprint,\n };\n }\n\n sendTransaction(payload: TransactionPayload): void {\n this.transport.enqueue({\n type: 'transaction',\n payload: {\n ...payload,\n release: payload.release ?? this.options.release,\n environment: payload.environment ?? this.options.environment ?? 'production',\n tags: { ...this.options.tags, ...payload.tags },\n },\n });\n }\n\n sendCheckIn(payload: CheckInPayload): void {\n this.transport.enqueue({\n type: 'check_in',\n payload: {\n ...payload,\n release: payload.release ?? this.options.release,\n environment: payload.environment ?? this.options.environment ?? 'production',\n },\n });\n }\n\n sendHeartbeat(payload: HeartbeatPayload): void {\n this.transport.enqueue({\n type: 'heartbeat',\n payload: { ...payload, release: payload.release ?? this.options.release },\n });\n }\n\n flush(timeoutMs?: number): Promise<boolean> {\n return this.transport.flush(timeoutMs);\n }\n\n close(timeoutMs?: number): Promise<boolean> {\n return this.transport.close(timeoutMs);\n }\n}\n","import type { Client } from './client';\nimport type { HeartbeatOptions } from './types';\nimport { nowISO, unrefTimer } from './utils';\n\nconst DEFAULT_INTERVAL_MS = 30_000;\n\n/** Batimento periódico \"estou vivo\" — o servidor marca a instância offline quando ele para. */\nexport class Heartbeat {\n private readonly intervalMs: number;\n private readonly instanceId: string;\n private readonly name: string;\n private readonly metadata?: Record<string, unknown>;\n private timer: ReturnType<typeof setInterval> | undefined;\n\n constructor(\n private readonly client: Client,\n options: HeartbeatOptions = {},\n instanceId: string\n ) {\n this.intervalMs = options.intervalMs ?? DEFAULT_INTERVAL_MS;\n this.instanceId = instanceId;\n this.name = options.name ?? instanceId;\n this.metadata = options.metadata;\n }\n\n start(): void {\n if (this.timer) return;\n this.beat();\n this.timer = setInterval(() => this.beat(), this.intervalMs);\n unrefTimer(this.timer);\n }\n\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n private beat(): void {\n this.client.sendHeartbeat({\n instance_id: this.instanceId,\n name: this.name,\n interval_ms: this.intervalMs,\n timestamp: nowISO(),\n metadata: this.metadata,\n });\n }\n}\n","import type { Client } from './client';\nimport type { Scope } from './scope';\nimport { isNode } from './utils';\n\nlet installed = false;\n\n/**\n * Registra handlers globais de erro.\n * Node: preserva a semântica padrão — após capturar e flushar um uncaughtException,\n * o processo encerra com código 1 (a menos que o programa tenha handler próprio).\n */\nexport function installGlobalHandlers(client: Client, getScope: () => Scope): void {\n if (installed) return;\n installed = true;\n\n if (isNode()) {\n process.on('uncaughtException', (error: Error) => {\n client.captureException(error, { level: 'fatal', tags: { mechanism: 'uncaughtException' } }, getScope());\n void client.flush(2_000).then(() => {\n if (process.listenerCount('uncaughtException') <= 1) {\n console.error(error);\n process.exit(1);\n }\n });\n });\n\n process.on('unhandledRejection', (reason: unknown) => {\n client.captureException(reason, { level: 'error', tags: { mechanism: 'unhandledRejection' } }, getScope());\n // fetch em andamento segura o processo aberto até o envio terminar\n void client.flush(2_000);\n });\n\n // rede de segurança: envia o que restou na fila quando o event loop esvazia\n process.on('beforeExit', () => {\n void client.flush(2_000);\n });\n return;\n }\n\n if (typeof window !== 'undefined') {\n window.addEventListener('error', event => {\n client.captureException(event.error ?? event.message, { tags: { mechanism: 'onerror' } }, getScope());\n });\n window.addEventListener('unhandledrejection', event => {\n client.captureException(event.reason, { tags: { mechanism: 'onunhandledrejection' } }, getScope());\n });\n window.addEventListener('pagehide', () => {\n void client.flush(1_000);\n });\n }\n}\n\n/** Apenas para testes internos. */\nexport function resetGlobalHandlersForTesting(): void {\n installed = false;\n}\n","import type { Breadcrumb, EventUser, Severity } from './protocol';\nimport { nowISO } from './utils';\n\nexport type BreadcrumbInput = Omit<Breadcrumb, 'timestamp'> & { timestamp?: string };\n\n/** Estado contextual anexado aos eventos: tags, usuário, contexts, extras e breadcrumbs. */\nexport class Scope {\n tags: Record<string, string> = {};\n user?: EventUser;\n contexts: Record<string, Record<string, unknown>> = {};\n extra: Record<string, unknown> = {};\n level?: Severity;\n fingerprint?: string[];\n breadcrumbs: Breadcrumb[] = [];\n\n setTag(key: string, value: string): this {\n this.tags[key] = value;\n return this;\n }\n\n setTags(tags: Record<string, string>): this {\n Object.assign(this.tags, tags);\n return this;\n }\n\n setUser(user: EventUser | null): this {\n this.user = user ?? undefined;\n return this;\n }\n\n setContext(name: string, context: Record<string, unknown> | null): this {\n if (context === null) {\n delete this.contexts[name];\n } else {\n this.contexts[name] = context;\n }\n return this;\n }\n\n setExtra(key: string, value: unknown): this {\n this.extra[key] = value;\n return this;\n }\n\n setExtras(extras: Record<string, unknown>): this {\n Object.assign(this.extra, extras);\n return this;\n }\n\n setLevel(level: Severity): this {\n this.level = level;\n return this;\n }\n\n setFingerprint(fingerprint: string[]): this {\n this.fingerprint = fingerprint;\n return this;\n }\n\n addBreadcrumb(crumb: BreadcrumbInput, maxBreadcrumbs: number): this {\n this.breadcrumbs.push({ timestamp: nowISO(), ...crumb });\n if (this.breadcrumbs.length > maxBreadcrumbs) {\n this.breadcrumbs.splice(0, this.breadcrumbs.length - maxBreadcrumbs);\n }\n return this;\n }\n\n clearBreadcrumbs(): this {\n this.breadcrumbs = [];\n return this;\n }\n\n clone(): Scope {\n const next = new Scope();\n next.tags = { ...this.tags };\n next.user = this.user ? { ...this.user } : undefined;\n next.contexts = Object.fromEntries(Object.entries(this.contexts).map(([k, v]) => [k, { ...v }]));\n next.extra = { ...this.extra };\n next.level = this.level;\n next.fingerprint = this.fingerprint ? [...this.fingerprint] : undefined;\n next.breadcrumbs = [...this.breadcrumbs];\n return next;\n }\n}\n","import type { SpanData, TransactionPayload } from './protocol';\nimport type { Client } from './client';\nimport { nowISO, uuid4 } from './utils';\n\nfunction spanId(): string {\n return uuid4().slice(0, 16);\n}\n\nexport class Span {\n readonly spanId = spanId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n endTimestamp?: string;\n data?: Record<string, unknown>;\n\n constructor(\n private readonly transaction: Transaction,\n readonly parentSpanId: string,\n readonly op?: string,\n readonly description?: string\n ) {}\n\n setStatus(status: string): this {\n this.status = status;\n return this;\n }\n\n setData(key: string, value: unknown): this {\n this.data = { ...this.data, [key]: value };\n return this;\n }\n\n /** Span aninhado (filho deste span). */\n startChild(op?: string, description?: string): Span {\n return this.transaction.createSpan(this.spanId, op, description);\n }\n\n finish(): void {\n if (!this.endTimestamp) this.endTimestamp = nowISO();\n }\n\n toJSON(): SpanData {\n return {\n span_id: this.spanId,\n parent_span_id: this.parentSpanId,\n op: this.op,\n description: this.description,\n status: this.status,\n start_timestamp: this.startTimestamp,\n timestamp: this.endTimestamp ?? nowISO(),\n data: this.data,\n };\n }\n}\n\n/**\n * Uma unidade de trabalho nomeada (ex.: uma execução de rotina, uma sincronização).\n * Spans filhos medem as etapas internas (chamadas HTTP, queries, etc.).\n */\nexport class Transaction {\n readonly eventId = uuid4();\n readonly spanId = spanId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n private readonly spans: Span[] = [];\n private readonly tags: Record<string, string> = {};\n private finished = false;\n\n constructor(\n private readonly client: Client | undefined,\n public name: string,\n readonly op?: string,\n private readonly sampled = true\n ) {}\n\n createSpan(parentSpanId: string, op?: string, description?: string): Span {\n const span = new Span(this, parentSpanId, op, description);\n this.spans.push(span);\n return span;\n }\n\n /** Span direto da transaction. */\n startChild(op?: string, description?: string): Span {\n return this.createSpan(this.spanId, op, description);\n }\n\n setTag(key: string, value: string): this {\n this.tags[key] = value;\n return this;\n }\n\n setStatus(status: string): this {\n this.status = status;\n return this;\n }\n\n setName(name: string): this {\n this.name = name;\n return this;\n }\n\n finish(): void {\n if (this.finished) return;\n this.finished = true;\n\n for (const span of this.spans) span.finish();\n\n if (!this.sampled || !this.client) return;\n const payload: TransactionPayload = {\n event_id: this.eventId,\n name: this.name,\n op: this.op,\n status: this.status,\n start_timestamp: this.startTimestamp,\n timestamp: nowISO(),\n spans: this.spans.map(span => span.toJSON()),\n tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,\n };\n this.client.sendTransaction(payload);\n }\n}\n","import type { CheckInStatus } from './protocol';\nimport type { Client } from './client';\nimport { uuid4 } from './utils';\n\nexport interface CheckInOptions {\n monitorSlug: string;\n status: CheckInStatus;\n /** Reutilize o id retornado pelo check-in 'in_progress' para fechar a execução */\n checkInId?: string;\n durationMs?: number;\n /** Expressão cron — cria/atualiza o monitor automaticamente no servidor */\n schedule?: string;\n timezone?: string;\n}\n\nexport function sendCheckIn(client: Client, options: CheckInOptions): string {\n const checkInId = options.checkInId ?? uuid4();\n client.sendCheckIn({\n check_in_id: checkInId,\n monitor_slug: options.monitorSlug,\n status: options.status,\n duration_ms: options.durationMs,\n schedule: options.schedule,\n timezone: options.timezone,\n });\n return checkInId;\n}\n\nexport interface WithMonitorOptions {\n schedule?: string;\n timezone?: string;\n}\n\n/** Envolve a execução de um job: in_progress → ok/error com duração medida. */\nexport async function withMonitorImpl<T>(\n client: Client,\n captureError: (error: unknown) => void,\n monitorSlug: string,\n fn: () => T | Promise<T>,\n options?: WithMonitorOptions\n): Promise<T> {\n const checkInId = sendCheckIn(client, {\n monitorSlug,\n status: 'in_progress',\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n const startedAt = Date.now();\n\n try {\n const result = await fn();\n sendCheckIn(client, {\n monitorSlug,\n status: 'ok',\n checkInId,\n durationMs: Date.now() - startedAt,\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n return result;\n } catch (error) {\n sendCheckIn(client, {\n monitorSlug,\n status: 'error',\n checkInId,\n durationMs: Date.now() - startedAt,\n schedule: options?.schedule,\n timezone: options?.timezone,\n });\n captureError(error);\n throw error;\n }\n}\n","import type { ManagerPollRequest, ManagerPollResponse, ManagerRunUpdateRequest } from './protocol';\nimport { sleep, type Logger } from '../utils';\n\nconst RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\n\nexport class ManagerApiError extends Error {\n constructor(\n message: string,\n readonly status: number\n ) {\n super(message);\n this.name = 'ManagerApiError';\n }\n}\n\nexport interface ManagerApiOptions {\n baseUrl: string;\n key: string;\n logger: Logger;\n}\n\n/** Cliente HTTP do agente — bearer auth, retry com backoff nos updates. */\nexport class ManagerApi {\n private readonly baseUrl: string;\n private readonly key: string;\n private readonly logger: Logger;\n\n constructor(options: ManagerApiOptions) {\n this.baseUrl = options.baseUrl;\n this.key = options.key;\n this.logger = options.logger;\n }\n\n private headers(): Record<string, string> {\n return {\n 'content-type': 'application/json',\n authorization: `Bearer ${this.key}`,\n };\n }\n\n /** Um request só — o loop de polling é quem decide o backoff entre tentativas. */\n async poll(request: ManagerPollRequest, signal?: AbortSignal): Promise<ManagerPollResponse> {\n const response = await fetch(`${this.baseUrl}/poll`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal,\n });\n if (!response.ok) {\n throw new ManagerApiError(`poll falhou (HTTP ${response.status})`, response.status);\n }\n return (await response.json()) as ManagerPollResponse;\n }\n\n /**\n * PATCH de status/logs com retry em falha de rede/5xx/429.\n * 4xx é definitivo e vira ManagerApiError imediato (409 = run cancelada/transição inválida).\n */\n async updateRun(runId: string, update: ManagerRunUpdateRequest): Promise<void> {\n for (let attempt = 0; ; attempt++) {\n let retriable: unknown;\n try {\n const response = await fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}`, {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(update),\n });\n if (response.ok) return;\n if (response.status >= 400 && response.status < 500 && response.status !== 429) {\n throw new ManagerApiError(`update rejeitado (HTTP ${response.status})`, response.status);\n }\n retriable = new Error(`HTTP ${response.status}`);\n } catch (error) {\n if (error instanceof ManagerApiError) throw error;\n retriable = error;\n }\n\n const delay = RETRY_DELAYS_MS[attempt];\n if (delay === undefined) {\n throw new Error(`update da run ${runId} descartado após retries: ${String(retriable)}`);\n }\n this.logger.warn(`falha no update da run ${runId} (${String(retriable)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n }\n}\n","import type { ManagerRunError, ManagerRunUpdateRequest, RunLogEntry, RunLogLevel } from './protocol';\nimport type { RunContext } from './types';\nimport { ManagerApi, ManagerApiError } from './api';\nimport { nowISO, unrefTimer, type Logger } from '../utils';\n\nconst DEFAULT_LOG_FLUSH_INTERVAL_MS = 2_000;\nconst MAX_LOG_MESSAGE_CHARS = 10_000;\nconst MAX_LOGS_PER_RUN = 500;\nconst MAX_LOGS_PER_PATCH = 100;\nconst FLUSH_AT_BUFFERED = 20;\n\n/**\n * Reporter de uma run: bufferiza logs (flush incremental com throttle) e encadeia\n * todos os PATCHes numa fila única — a ordem running → logs → terminal é garantida.\n * Um 409/404 mata o reporter (run cancelada no app): o handler não pode ser morto,\n * mas todo reporte posterior é suprimido e ctx.signal dispara para abort cooperativo.\n */\nexport class RunReporter {\n readonly context: RunContext;\n\n private buffer: RunLogEntry[] = [];\n private loggedCount = 0;\n private droppedCount = 0;\n private dead = false;\n private chain: Promise<void> = Promise.resolve();\n private timer: ReturnType<typeof setTimeout> | undefined;\n private readonly abortController = new AbortController();\n private readonly flushIntervalMs: number;\n\n constructor(\n private readonly api: ManagerApi,\n private readonly runId: string,\n task: string,\n private readonly logger: Logger,\n flushIntervalMs?: number\n ) {\n this.flushIntervalMs = flushIntervalMs ?? DEFAULT_LOG_FLUSH_INTERVAL_MS;\n this.context = {\n runId,\n task,\n log: (level, message) => this.log(level, message),\n signal: this.abortController.signal,\n };\n }\n\n get isDead(): boolean {\n return this.dead;\n }\n\n /** Aborta o ctx.signal sem matar o reporter (timeout/shutdown ainda reportam o terminal). */\n abort(): void {\n if (!this.abortController.signal.aborted) this.abortController.abort();\n }\n\n private log(level: RunLogLevel, message: string): void {\n if (this.dead) return;\n if (this.loggedCount >= MAX_LOGS_PER_RUN) {\n this.droppedCount++;\n return;\n }\n this.loggedCount++;\n const truncated =\n message.length > MAX_LOG_MESSAGE_CHARS ? `${message.slice(0, MAX_LOG_MESSAGE_CHARS)}… [truncado]` : message;\n this.buffer.push({ ts: nowISO(), level, message: truncated });\n\n if (this.buffer.length >= FLUSH_AT_BUFFERED) {\n this.flushLogs();\n } else {\n this.scheduleFlush();\n }\n }\n\n private scheduleFlush(): void {\n if (this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n this.flushLogs();\n }, this.flushIntervalMs);\n unrefTimer(this.timer);\n }\n\n private clearFlushTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n }\n\n private takeLogs(): RunLogEntry[] {\n const logs = this.buffer.splice(0, this.buffer.length);\n if (this.droppedCount > 0) {\n logs.push({\n ts: nowISO(),\n level: 'warning',\n message: `${this.droppedCount} logs descartados (limite de ${MAX_LOGS_PER_RUN} por execução)`,\n });\n this.droppedCount = 0;\n }\n return logs;\n }\n\n /** Flush incremental: envia o buffer como status 'running' (em chunks). */\n private flushLogs(): void {\n this.clearFlushTimer();\n if (this.dead || this.buffer.length === 0) return;\n const logs = this.buffer.splice(0, this.buffer.length);\n for (let i = 0; i < logs.length; i += MAX_LOGS_PER_PATCH) {\n this.enqueue({ status: 'running', logs: logs.slice(i, i + MAX_LOGS_PER_PATCH) });\n }\n }\n\n /** Primeiro PATCH (claimed → running). Retorna false se a run já morreu (cancelada). */\n async reportRunning(): Promise<boolean> {\n this.enqueue({ status: 'running' });\n await this.chain;\n return !this.dead;\n }\n\n reportSuccess(): void {\n this.clearFlushTimer();\n this.enqueue({ status: 'succeeded', logs: this.takeLogs() });\n }\n\n reportFailure(error: ManagerRunError): void {\n this.clearFlushTimer();\n this.enqueue({ status: 'failed', error, logs: this.takeLogs() });\n }\n\n /** Aguarda a fila de PATCHes esvaziar (chame depois do terminal). */\n finalize(): Promise<void> {\n return this.chain;\n }\n\n private enqueue(update: ManagerRunUpdateRequest): void {\n if (this.dead) return;\n this.chain = this.chain.then(async () => {\n if (this.dead) return;\n const payload = update.logs && update.logs.length === 0 ? { ...update, logs: undefined } : update;\n try {\n await this.api.updateRun(this.runId, payload);\n } catch (error) {\n if (error instanceof ManagerApiError && (error.status === 409 || error.status === 404)) {\n this.dead = true;\n this.abort();\n this.buffer = [];\n this.logger.warn(`run ${this.runId} cancelada/removida no servidor — reporte suprimido`);\n return;\n }\n this.logger.error(`update da run ${this.runId} perdido:`, error);\n }\n });\n }\n}\n","import type { ManagerRunDescriptor, ManagerRunError } from './protocol';\nimport type { ManagerAgentOptions, ManagerTaskHandler } from './types';\nimport { ManagerApi, ManagerApiError } from './api';\nimport { RunReporter } from './context';\nimport { resolveConfig } from '../config';\nimport { isNode, makeLogger, sleep, SDK_VERSION, type Logger } from '../utils';\n\nconst DEFAULT_POLL_INTERVAL_MS = 5_000;\nconst MIN_POLL_INTERVAL_MS = 1_000;\nconst MAX_CONCURRENCY = 5;\nconst POLL_RETRY_DELAYS_MS = [1_000, 4_000, 16_000];\nconst AUTH_FAILURE_INTERVAL_MS = 30_000;\n\ntype AgentState = 'idle' | 'started' | 'stopping';\n\n/** Hostname da máquina — telemetria (campo `host`), distinto da identidade do agente. */\nfunction hostname(): string | undefined {\n if (!isNode()) return undefined;\n return process.env.HOSTNAME || process.env.COMPUTERNAME || undefined;\n}\n\n/**\n * Loop de polling do Manager: busca runs pendentes, executa os handlers registrados\n * e reporta status/logs/result. Ao contrário do Monitor, o timer de polling NÃO é\n * unref'd — um agente iniciado mantém o processo vivo até stop().\n */\nexport class ManagerAgent {\n readonly logger: Logger;\n\n private readonly api: ManagerApi;\n private readonly pollIntervalMs: number;\n private readonly concurrency: number;\n private readonly instanceId: string;\n private readonly taskTimeoutMs?: number;\n private readonly logFlushIntervalMs?: number;\n\n private state: AgentState = 'idle';\n private timer: ReturnType<typeof setTimeout> | undefined;\n private pollAbort: AbortController | undefined;\n private consecutiveFailures = 0;\n private consecutiveAuthFailures = 0;\n private readonly activeRuns = new Set<Promise<void>>();\n private readonly reporters = new Set<RunReporter>();\n\n constructor(\n private readonly options: ManagerAgentOptions,\n private readonly registry: Map<string, ManagerTaskHandler>\n ) {\n this.logger = makeLogger(options.debug ?? false, '[hobots-manager]');\n const config = resolveConfig(options, '[hobots-manager]');\n this.api = new ManagerApi({ baseUrl: config.managerBaseUrl, key: config.key, logger: this.logger });\n this.pollIntervalMs = Math.max(MIN_POLL_INTERVAL_MS, options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS);\n this.concurrency = Math.min(MAX_CONCURRENCY, Math.max(1, options.concurrency ?? 1));\n this.instanceId = options.instanceId;\n this.taskTimeoutMs = options.taskTimeoutMs;\n this.logFlushIntervalMs = options.logFlushIntervalMs;\n this.logger.debug('agente configurado', { baseUrl: config.managerBaseUrl });\n }\n\n get activeCount(): number {\n return this.activeRuns.size;\n }\n\n start(): void {\n if (this.state === 'started') return;\n if (this.state === 'stopping') {\n throw new Error('[hobots-manager] start() chamado durante stop() — aguarde o stop terminar');\n }\n if (this.registry.size === 0) {\n throw new Error('[hobots-manager] nenhuma task registrada — chame register() antes de start()');\n }\n this.state = 'started';\n this.logger.debug(`polling iniciado (tasks: ${[...this.registry.keys()].join(', ')})`);\n this.schedule(0);\n }\n\n /** Para o polling e aguarda as runs ativas (até timeoutMs). Retorna true se tudo terminou a tempo. */\n async stop(timeoutMs = 30_000): Promise<boolean> {\n if (this.state === 'idle') return true;\n this.state = 'stopping';\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = undefined;\n }\n this.pollAbort?.abort();\n\n const all = Promise.allSettled([...this.activeRuns]).then(() => true);\n const finished = timeoutMs > 0 ? await Promise.race([all, sleep(timeoutMs).then(() => false)]) : false;\n if (!finished && this.activeRuns.size > 0) {\n this.logger.warn(`${this.activeRuns.size} run(s) ainda em execução após ${timeoutMs}ms — abandonando a espera`);\n for (const reporter of this.reporters) reporter.abort();\n }\n this.state = 'idle';\n return finished;\n }\n\n /** Timer intencionalmente NÃO unref'd: o agente é a razão do processo existir. */\n private schedule(delayMs: number): void {\n if (this.state !== 'started' || this.timer) return;\n this.timer = setTimeout(() => {\n this.timer = undefined;\n void this.tick();\n }, delayMs);\n }\n\n private async tick(): Promise<void> {\n if (this.state !== 'started') return;\n if (this.activeRuns.size >= this.concurrency) {\n this.schedule(this.pollIntervalMs);\n return;\n }\n\n this.pollAbort = new AbortController();\n try {\n const response = await this.api.poll(\n {\n agent: {\n // identidade canônica do agente no painel — o mesmo instanceId do\n // heartbeat do Monitor, então os dois canais convergem em um agente\n instance_id: this.instanceId,\n version: SDK_VERSION,\n host: hostname(),\n tasks: [...this.registry.keys()],\n },\n max: Math.min(MAX_CONCURRENCY, this.concurrency - this.activeRuns.size),\n tasks: [...this.registry.keys()],\n },\n this.pollAbort.signal\n );\n this.consecutiveFailures = 0;\n this.consecutiveAuthFailures = 0;\n\n for (const run of response.runs) {\n this.dispatch(run);\n }\n // com trabalho entregue, re-poll imediato (modo drain); sem trabalho, espera o intervalo\n this.schedule(response.runs.length > 0 ? 0 : this.pollIntervalMs);\n } catch (error) {\n if (this.state !== 'started') return; // stop() abortou o poll\n this.schedule(this.delayAfterPollError(error));\n } finally {\n this.pollAbort = undefined;\n }\n }\n\n private delayAfterPollError(error: unknown): number {\n if (error instanceof ManagerApiError && error.status === 401) {\n // chave desativada/rotacionada — continua tentando devagar (pode ser reativada)\n this.consecutiveAuthFailures++;\n if (this.consecutiveAuthFailures === 1 || this.consecutiveAuthFailures % 10 === 0) {\n this.logger.error('chave rejeitada (401) — verifique o Client Secret do projeto em Configurações → Projetos');\n }\n return Math.max(this.pollIntervalMs, AUTH_FAILURE_INTERVAL_MS);\n }\n this.consecutiveFailures++;\n const ladder = POLL_RETRY_DELAYS_MS[Math.min(this.consecutiveFailures - 1, POLL_RETRY_DELAYS_MS.length - 1)]!;\n const delay = Math.min(Math.max(ladder, 0), Math.max(this.pollIntervalMs, 16_000));\n this.logger.warn(`poll falhou (${String(error)}), próxima tentativa em ${delay}ms`);\n return delay;\n }\n\n private dispatch(run: ManagerRunDescriptor): void {\n const promise = this.executeRun(run)\n .catch(error => this.logger.error(`erro inesperado na run ${run.id}:`, error))\n .finally(() => {\n this.activeRuns.delete(promise);\n if (this.state === 'started') this.schedule(0);\n });\n this.activeRuns.add(promise);\n }\n\n private async executeRun(run: ManagerRunDescriptor): Promise<void> {\n const reporter = new RunReporter(this.api, run.id, run.task, this.logger, this.logFlushIntervalMs);\n this.reporters.add(reporter);\n try {\n const handler = this.registry.get(run.task);\n if (!handler) {\n // claim veio para uma task sem handler (corrida rara) — falha direto, sem 'running'\n reporter.reportFailure({\n type: 'HandlerNotFound',\n message: `tarefa não registrada no agente: ${run.task}`,\n });\n await reporter.finalize();\n return;\n }\n\n const ok = await reporter.reportRunning();\n if (!ok) {\n this.logger.debug(`run ${run.id} cancelada antes de iniciar — handler não executado`);\n return;\n }\n\n this.logger.debug(`executando run ${run.id} (${run.task})`);\n try {\n await this.invokeWithTimeout(handler, run, reporter);\n reporter.reportSuccess();\n this.logger.debug(`run ${run.id} concluída`);\n } catch (error) {\n reporter.reportFailure(toRunError(error));\n this.logger.debug(`run ${run.id} falhou: ${String(error)}`);\n }\n await reporter.finalize();\n } finally {\n this.reporters.delete(reporter);\n }\n }\n\n private async invokeWithTimeout(\n handler: ManagerTaskHandler,\n run: ManagerRunDescriptor,\n reporter: RunReporter\n ): Promise<void> {\n const invocation = Promise.resolve().then(() => handler(run.params, reporter.context));\n if (!this.taskTimeoutMs || this.taskTimeoutMs <= 0) {\n await invocation;\n return;\n }\n\n const timeoutMs = this.taskTimeoutMs;\n const timeout = sleep(timeoutMs).then(() => TIMEOUT_SENTINEL);\n const outcome = await Promise.race([invocation, timeout]);\n if (outcome !== TIMEOUT_SENTINEL) return;\n\n // não dá para matar o código do usuário — reporta, aborta o signal e libera o slot\n reporter.abort();\n invocation\n .then(() => this.logger.warn(`run ${run.id} terminou depois do timeout de ${timeoutMs}ms`))\n .catch(() => this.logger.warn(`run ${run.id} falhou depois do timeout de ${timeoutMs}ms (erro descartado)`));\n throw Object.assign(new Error(`timeout após ${timeoutMs}ms (o handler pode continuar em background)`), {\n name: 'TaskTimeout',\n });\n }\n}\n\nconst TIMEOUT_SENTINEL = Symbol('task-timeout');\n\nconst MAX_ERROR_MESSAGE_CHARS = 10_000;\nconst MAX_ERROR_STACK_CHARS = 20_000;\n\nfunction truncate(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max)}… [truncado]` : value;\n}\n\nfunction toRunError(error: unknown): ManagerRunError {\n if (error instanceof Error) {\n return {\n type: error.name,\n message: truncate(error.message, MAX_ERROR_MESSAGE_CHARS),\n stack: error.stack ? truncate(error.stack, MAX_ERROR_STACK_CHARS) : undefined,\n };\n }\n return { message: truncate(String(error), MAX_ERROR_MESSAGE_CHARS) };\n}\n","import type { EventUser, Severity } from './protocol';\nimport type { CaptureHint, InitOptions } from './types';\nimport { Client } from './client';\nimport { Heartbeat } from './heartbeat';\nimport { installGlobalHandlers } from './instrument';\nimport { Scope, type BreadcrumbInput } from './scope';\nimport { Transaction } from './transaction';\nimport { sendCheckIn, withMonitorImpl, type CheckInOptions, type WithMonitorOptions } from './checkin';\nimport { ManagerAgent } from './manager/agent';\nimport type { ManagerTaskHandler } from './manager/types';\n\nconst DEFAULT_MAX_BREADCRUMBS = 100;\n\nlet client: Client | undefined;\nlet scope = new Scope();\nlet heartbeat: Heartbeat | undefined;\nlet agent: ManagerAgent | undefined;\nconst registry = new Map<string, ManagerTaskHandler>();\nlet warnedManagerDisabled = false;\n\n/** Inicializa o SDK. Chame uma vez, o mais cedo possível no programa. */\nexport function init(options: InitOptions): void {\n if (client) {\n client.logger.warn('init() chamado mais de uma vez — substituindo o client anterior');\n heartbeat?.stop();\n heartbeat = undefined;\n }\n if (agent) {\n void agent.stop(0);\n agent = undefined;\n }\n warnedManagerDisabled = false;\n\n client = new Client(options);\n\n if (options.captureUnhandled !== false) {\n installGlobalHandlers(client, () => scope);\n }\n\n if (options.heartbeat) {\n const heartbeatOptions = options.heartbeat === true ? {} : options.heartbeat;\n heartbeat = new Heartbeat(client, heartbeatOptions, options.instanceId);\n heartbeat.start();\n }\n\n if (options.manager) {\n const managerOptions = options.manager === true ? {} : options.manager;\n agent = new ManagerAgent(\n { ...managerOptions, clientSecret: options.clientSecret, instanceId: options.instanceId, debug: options.debug },\n registry\n );\n }\n\n client.logger.debug('inicializado', { endpoint: client.config.ingestEndpoint });\n}\n\nexport function getClient(): Client | undefined {\n return client;\n}\n\n/** Captura uma exceção e retorna o event_id (undefined se o SDK não foi inicializado). */\nexport function captureException(error: unknown, hint?: CaptureHint): string | undefined {\n return client?.captureException(error, hint, scope);\n}\n\nexport function captureMessage(message: string, level: Severity = 'info', hint?: CaptureHint): string | undefined {\n return client?.captureMessage(message, level, hint, scope);\n}\n\n/** Registra um breadcrumb — anexado aos próximos eventos como trilha do que aconteceu antes. */\nexport function addBreadcrumb(crumb: BreadcrumbInput): void {\n scope.addBreadcrumb(crumb, client?.options.maxBreadcrumbs ?? DEFAULT_MAX_BREADCRUMBS);\n}\n\nexport function setTag(key: string, value: string): void {\n scope.setTag(key, value);\n}\n\nexport function setTags(tags: Record<string, string>): void {\n scope.setTags(tags);\n}\n\nexport function setUser(user: EventUser | null): void {\n scope.setUser(user);\n}\n\nexport function setContext(name: string, context: Record<string, unknown> | null): void {\n scope.setContext(name, context);\n}\n\nexport function setExtra(key: string, value: unknown): void {\n scope.setExtra(key, value);\n}\n\n/** Executa o callback com uma cópia isolada do scope (alterações não vazam para fora). */\nexport function withScope<T>(callback: (scope: Scope) => T): T {\n const previous = scope;\n scope = previous.clone();\n try {\n return callback(scope);\n } finally {\n scope = previous;\n }\n}\n\n/** Inicia uma transaction de performance. Chame .finish() para enviá-la. */\nexport function startTransaction(name: string, op?: string): Transaction {\n const rate = client?.options.tracesSampleRate ?? 1;\n const sampled = rate >= 1 || Math.random() < rate;\n return new Transaction(client, name, op, sampled);\n}\n\n/** Check-in manual de um monitor cron. Retorna o check_in_id para fechar a execução depois. */\nexport function checkIn(options: CheckInOptions): string | undefined {\n return client ? sendCheckIn(client, options) : undefined;\n}\n\n/** Envolve um job monitorado: envia in_progress → ok/error com duração e captura a exceção em caso de falha. */\nexport async function withMonitor<T>(\n monitorSlug: string,\n fn: () => T | Promise<T>,\n options?: WithMonitorOptions\n): Promise<T> {\n if (!client) return fn();\n return withMonitorImpl(\n client,\n error => captureException(error, { tags: { monitor: monitorSlug } }),\n monitorSlug,\n fn,\n options\n );\n}\n\n/** Aguarda o envio de tudo que está na fila (até timeoutMs). */\nexport function flush(timeoutMs?: number): Promise<boolean> {\n return client ? client.flush(timeoutMs) : Promise.resolve(true);\n}\n\n/** Registra o handler de uma task do Manager (o task_slug configurado no formulário do app). */\nexport function register<P = Record<string, unknown>>(task: string, handler: ManagerTaskHandler<P>): void {\n if (registry.has(task)) {\n (agent?.logger ?? client?.logger)?.warn(`register('${task}') sobrescreveu um handler existente`);\n }\n if (client && !agent && !warnedManagerDisabled) {\n warnedManagerDisabled = true;\n client.logger.warn(\n `register('${task}') com o Manager desabilitado — passe manager: true (ou opções) no init()`\n );\n }\n registry.set(task, handler as ManagerTaskHandler);\n}\n\n/**\n * Inicia o polling do Manager. O timer NÃO é unref'd: o processo fica vivo\n * aguardando trabalho até stop()/close() — o inverso deliberado do Monitor.\n */\nexport function start(): void {\n if (!agent) {\n throw new Error('[hobots] Manager não configurado — passe manager: true (ou opções) no init() antes de start()');\n }\n agent.start();\n}\n\n/** Para só o Manager: encerra o polling e aguarda as runs ativas (até timeoutMs). A telemetria continua. */\nexport function stop(timeoutMs?: number): Promise<boolean> {\n return agent ? agent.stop(timeoutMs) : Promise.resolve(true);\n}\n\n/**\n * Encerra tudo: para o Manager (aguardando runs em voo), o heartbeat e faz o\n * flush final do transport. Chame antes do processo terminar.\n */\nexport async function close(timeoutMs?: number): Promise<boolean> {\n const agentStopped = agent ? await agent.stop(timeoutMs) : true;\n heartbeat?.stop();\n heartbeat = undefined;\n const clientClosed = client ? await client.close(timeoutMs) : true;\n return agentStopped && clientClosed;\n}\n"],"mappings":";AACO,IAAM,mBAAmB;AAoBhC,SAAS,aAAiC;AAExC,MAAI,OAAO,YAAY,eAAe,CAAC,QAAQ,IAAK,QAAO;AAC3D,SAAO,QAAQ,IAAI,gBAAgB,KAAK,KAAK;AAC/C;AAGO,SAAS,cAAc,SAAsB,SAAS,YAA4B;AACvF,QAAM,MAAM,QAAQ,cAAc,KAAK;AACvC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,GAAG,MAAM,sGAAsF;AAAA,EACjH;AAEA,QAAM,WAAW,WAAW,KAAK,kBAAkB,QAAQ,QAAQ,EAAE;AACrE,MAAI;AACF,QAAI,IAAI,OAAO;AAAA,EACjB,QAAQ;AACN,UAAM,IAAI,MAAM,GAAG,MAAM,iCAA8B,OAAO,8CAAyC;AAAA,EACzG;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,gBAAgB,GAAG,OAAO;AAAA,IAC1B,gBAAgB,GAAG,OAAO;AAAA,EAC5B;AACF;;;AC7CA,IAAM,aAAa;AAGnB,IAAM,WAAW;AACjB,IAAM,cAAc;AAEpB,SAAS,QAAQ,UAAuC;AACtD,MAAI,CAAC,SAAU,QAAO;AACtB,MAAI,SAAS,WAAW,OAAO,EAAG,QAAO;AACzC,MAAI,SAAS,WAAW,WAAW,EAAG,QAAO;AAC7C,MAAI,SAAS,SAAS,cAAc,EAAG,QAAO;AAC9C,MAAI,aAAa,cAAe,QAAO;AACvC,SAAO;AACT;AAGO,SAAS,gBAAgB,OAAgD;AAC9E,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,QAAM,SAAuB,CAAC;AAC9B,aAAW,QAAQ,MAAM,MAAM,IAAI,GAAG;AACpC,QAAI,OAAO,UAAU,WAAY;AACjC,UAAM,QAAQ,SAAS,KAAK,IAAI;AAChC,QAAI,CAAC,SAAS,CAAC,KAAK,UAAU,EAAE,WAAW,KAAK,EAAG;AAEnD,UAAM,CAAC,EAAE,IAAI,QAAQ,IAAI;AACzB,UAAM,MAAM,YAAY,KAAK,YAAY,EAAE;AAC3C,UAAM,WAAW,MAAM,IAAI,CAAC,IAAI;AAChC,WAAO,KAAK;AAAA,MACV,UAAU,MAAM;AAAA,MAChB,UAAU,YAAY;AAAA,MACtB,QAAQ,MAAM,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,IAAI;AAAA,MACpC,OAAO,MAAM,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,IAAI;AAAA,MACnC,QAAQ,QAAQ,QAAQ;AAAA,IAC1B,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;ACvCO,IAAM,WAAW;AACjB,IAAM,cAAc;AAEpB,SAAS,SAAkB;AAChC,SAAO,OAAO,YAAY,eAAe,OAAO,QAAQ,UAAU,SAAS;AAC7E;AAGO,SAAS,QAAgB;AAC9B,QAAM,YAAa,WAAmC;AACtD,MAAI,aAAa,OAAO,UAAU,eAAe,YAAY;AAC3D,WAAO,UAAU,WAAW,EAAE,QAAQ,MAAM,EAAE;AAAA,EAChD;AACA,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,WAAO,KAAK,MAAM,KAAK,OAAO,IAAI,EAAE,EAAE,SAAS,EAAE;AAAA,EACnD;AACA,SAAO;AACT;AAEO,SAAS,SAAiB;AAC/B,UAAO,oBAAI,KAAK,GAAE,YAAY;AAChC;AAGO,SAAS,WAAW,OAAsB;AAC/C,EAAC,OAA8C,QAAQ;AACzD;AAEO,SAAS,MAAM,IAA2B;AAC/C,SAAO,IAAI,QAAQ,aAAW;AAC5B,UAAM,QAAQ,WAAW,SAAS,EAAE;AACpC,eAAW,KAAK;AAAA,EAClB,CAAC;AACH;AAQA,IAAM,SAAS;AAER,SAAS,WAAW,SAAkB,SAAiB,QAAgB;AAC5E,SAAO;AAAA,IACL,OAAO,IAAI,SAAS,WAAW,QAAQ,MAAM,QAAQ,GAAG,IAAI;AAAA,IAC5D,MAAM,IAAI,SAAS,WAAW,QAAQ,KAAK,QAAQ,GAAG,IAAI;AAAA,IAC1D,OAAO,IAAI,SAAS,QAAQ,MAAM,QAAQ,GAAG,IAAI;AAAA,EACnD;AACF;;;AC9CA,SAAS,WAAW,OAAwB;AAC1C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI;AACF,UAAM,OAAO,KAAK,UAAU,KAAK;AACjC,QAAI,QAAQ,SAAS,KAAM,QAAO;AAAA,EACpC,QAAQ;AAAA,EAER;AACA,SAAO,OAAO,KAAK;AACrB;AAEO,SAAS,mBAAmB,OAAgB,QAAkB,SAAuB;AAC1F,MAAI;AACJ,MAAI;AACJ,MAAI,SAAS,CAAC;AAEd,MAAI,iBAAiB,OAAO;AAC1B,WAAO,MAAM,QAAQ;AACrB,YAAQ,MAAM;AACd,aAAS,gBAAgB,MAAM,KAAK;AAAA,EACtC,OAAO;AACL,WAAO;AACP,YAAQ,WAAW,KAAK;AAAA,EAC1B;AAEA,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,WAAW,OAAO;AAAA,IAClB;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,MACA,GAAI,OAAO,SAAS,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACxD;AAAA,EACF;AACF;AAEO,SAAS,iBAAiB,SAAiB,QAAkB,QAAsB;AACxF,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,WAAW,OAAO;AAAA,IAClB;AAAA,IACA;AAAA,EACF;AACF;;;AC7CA,IAAM,kBAAkB,CAAC,KAAO,KAAO,IAAM;AAC7C,IAAM,4BAA4B;AAClC,IAAM,yBAAyB;AAC/B,IAAM,yBAAyB;AAaxB,IAAM,YAAN,MAAgB;AAAA,EACJ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,SAAyB,CAAC;AAAA,EAC1B;AAAA,EACA,UAAU,oBAAI,IAAmB;AAAA,EACjC,SAAS;AAAA,EAEjB,YAAY,SAA2B;AACrC,SAAK,WAAW,QAAQ;AACxB,SAAK,MAAM,QAAQ;AACnB,SAAK,SAAS,QAAQ;AACtB,SAAK,kBAAkB,QAAQ,mBAAmB;AAClD,SAAK,eAAe,QAAQ,gBAAgB;AAC5C,SAAK,eAAe,QAAQ,gBAAgB;AAAA,EAC9C;AAAA,EAEA,QAAQ,MAA0B;AAChC,QAAI,KAAK,QAAQ;AACf,WAAK,OAAO,KAAK,uCAAuC,KAAK,IAAI;AACjE;AAAA,IACF;AACA,QAAI,KAAK,OAAO,UAAU,KAAK,cAAc;AAC3C,WAAK,OAAO,MAAM;AAClB,WAAK,OAAO,KAAK,yCAAyC;AAAA,IAC5D;AACA,SAAK,OAAO,KAAK,IAAI;AAErB,QAAI,KAAK,OAAO,UAAU,KAAK,cAAc;AAC3C,WAAK,KAAK,YAAY;AAAA,IACxB,OAAO;AACL,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEQ,WAAiB;AACvB,QAAI,KAAK,MAAO;AAChB,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,QAAQ;AACb,WAAK,KAAK,YAAY;AAAA,IACxB,GAAG,KAAK,eAAe;AACvB,eAAW,KAAK,KAAK;AAAA,EACvB;AAAA,EAEQ,cAA6B;AACnC,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AACA,QAAI,KAAK,OAAO,WAAW,EAAG,QAAO,QAAQ,QAAQ;AAErD,UAAM,QAAQ,KAAK,OAAO,OAAO,GAAG,KAAK,OAAO,MAAM;AACtD,UAAM,WAAqB;AAAA,MACzB,KAAK,EAAE,MAAM,UAAU,SAAS,YAAY;AAAA,MAC5C,SAAS,OAAO;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,UAAyB,KAAK,cAAc,QAAQ,EAAE,QAAQ,MAAM;AACxE,WAAK,QAAQ,OAAO,OAAO;AAAA,IAC7B,CAAC;AACD,SAAK,QAAQ,IAAI,OAAO;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,cAAc,UAAmC;AAC7D,aAAS,UAAU,KAAK,WAAW;AACjC,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,KAAK,UAAU;AAAA,UAC1C,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,oBAAoB,eAAe,UAAU,KAAK,GAAG,GAAG;AAAA,UACnF,MAAM,KAAK,UAAU,QAAQ;AAAA,QAC/B,CAAC;AACD,YAAI,SAAS,IAAI;AACf,eAAK,OAAO,MAAM,qBAAqB,SAAS,MAAM,MAAM,SAAS;AACrE;AAAA,QACF;AAEA,YAAI,SAAS,UAAU,OAAO,SAAS,SAAS,OAAO,SAAS,WAAW,KAAK;AAC9E,eAAK,OAAO,MAAM,4BAA4B,SAAS,MAAM,eAAe;AAC5E;AAAA,QACF;AACA,cAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE;AAAA,MAC3C,SAAS,OAAO;AACd,cAAM,QAAQ,gBAAgB,OAAO;AACrC,YAAI,UAAU,QAAW;AACvB,eAAK,OAAO,MAAM,wCAAqC,KAAK;AAC5D;AAAA,QACF;AACA,aAAK,OAAO,KAAK,mBAAmB,OAAO,KAAK,CAAC,eAAe,KAAK,IAAI;AACzE,cAAM,MAAM,KAAK;AAAA,MACnB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,MAAM,YAAY,KAAyB;AAC/C,SAAK,KAAK,YAAY;AACtB,UAAM,MAAM,QAAQ,WAAW,CAAC,GAAG,KAAK,OAAO,CAAC,EAAE,KAAK,MAAM,IAAI;AACjE,WAAO,QAAQ,KAAK,CAAC,KAAK,MAAM,SAAS,EAAE,KAAK,MAAM,KAAK,CAAC,CAAC;AAAA,EAC/D;AAAA,EAEA,MAAM,MAAM,YAAY,KAAyB;AAC/C,UAAM,SAAS,MAAM,KAAK,MAAM,SAAS;AACzC,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AACF;;;AC3HA,SAAS,kBAA2D;AAClE,MAAI,OAAO,GAAG;AACZ,WAAO;AAAA,MACL,SAAS,EAAE,MAAM,QAAQ,SAAS,QAAQ,QAAQ;AAAA,MAClD,IAAI,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,KAAK;AAAA,IACnD;AAAA,EACF;AACA,SAAO,EAAE,SAAS,EAAE,MAAM,UAAU,EAAE;AACxC;AAEO,IAAM,SAAN,MAAa;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACQ;AAAA,EAEjB,YAAY,SAAsB;AAChC,SAAK,UAAU;AACf,SAAK,SAAS,WAAW,CAAC,CAAC,QAAQ,KAAK;AACxC,SAAK,SAAS,cAAc,OAAO;AACnC,SAAK,YAAY,IAAI,UAAU;AAAA,MAC7B,UAAU,KAAK,OAAO;AAAA,MACtB,KAAK,KAAK,OAAO;AAAA,MACjB,QAAQ,KAAK;AAAA,MACb,iBAAiB,QAAQ;AAAA,MACzB,cAAc,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH;AAAA,EAEA,iBAAiB,OAAgB,MAA+BA,QAAsB;AACpF,WAAO,KAAK,aAAa,mBAAmB,OAAO,MAAM,SAAS,OAAO,GAAG,MAAMA,MAAK;AAAA,EACzF;AAAA,EAEA,eAAe,SAAiB,OAAiB,MAA+BA,QAAsB;AACpG,WAAO,KAAK,aAAa,iBAAiB,SAAS,KAAK,GAAG,MAAMA,MAAK;AAAA,EACxE;AAAA,EAEA,aAAa,OAAqB,MAA+BA,QAAsB;AACrF,UAAM,aAAa,KAAK,QAAQ,cAAc;AAC9C,QAAI,aAAa,KAAK,KAAK,OAAO,KAAK,YAAY;AACjD,WAAK,OAAO,MAAM,kCAAkC;AACpD,aAAO,MAAM;AAAA,IACf;AAEA,UAAM,WAAW,KAAK,aAAa,OAAO,MAAMA,MAAK;AACrD,UAAM,QAAQ,KAAK,QAAQ,aAAa,KAAK,QAAQ,WAAW,QAAQ,IAAI;AAC5E,QAAI,CAAC,OAAO;AACV,WAAK,OAAO,MAAM,kCAAkC;AACpD,aAAO,MAAM;AAAA,IACf;AAEA,SAAK,UAAU,QAAQ,EAAE,MAAM,SAAS,SAAS,MAAM,CAAC;AACxD,WAAO,MAAM;AAAA,EACf;AAAA,EAEQ,aAAa,OAAqB,MAA+BA,QAA4B;AACnG,UAAM,OAAO,EAAE,GAAG,KAAK,QAAQ,MAAM,GAAGA,OAAM,MAAM,GAAG,MAAM,MAAM,GAAG,MAAM,KAAK;AACjF,UAAM,QAAQ,EAAE,GAAGA,OAAM,OAAO,GAAG,MAAM,OAAO,GAAG,MAAM,MAAM;AAE/D,WAAO;AAAA,MACL,GAAG;AAAA,MACH,OAAO,MAAM,SAAS,MAAM,SAASA,OAAM,SAAS;AAAA,MACpD,SAAS,MAAM,WAAW,KAAK,QAAQ;AAAA,MACvC,aAAa,MAAM,eAAe,KAAK,QAAQ,eAAe;AAAA,MAC9D,MAAM,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO;AAAA,MAC5C,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,QAAQ;AAAA,MAC/C,MAAM,MAAM,QAAQA,OAAM;AAAA,MAC1B,UAAU,EAAE,GAAG,gBAAgB,GAAG,GAAGA,OAAM,UAAU,GAAG,MAAM,SAAS;AAAA,MACvE,aAAaA,OAAM,YAAY,SAAS,IAAI,CAAC,GAAGA,OAAM,WAAW,IAAI,MAAM;AAAA,MAC3E,aAAa,MAAM,eAAe,MAAM,eAAeA,OAAM;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,gBAAgB,SAAmC;AACjD,SAAK,UAAU,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,GAAG;AAAA,QACH,SAAS,QAAQ,WAAW,KAAK,QAAQ;AAAA,QACzC,aAAa,QAAQ,eAAe,KAAK,QAAQ,eAAe;AAAA,QAChE,MAAM,EAAE,GAAG,KAAK,QAAQ,MAAM,GAAG,QAAQ,KAAK;AAAA,MAChD;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,SAA+B;AACzC,SAAK,UAAU,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,SAAS;AAAA,QACP,GAAG;AAAA,QACH,SAAS,QAAQ,WAAW,KAAK,QAAQ;AAAA,QACzC,aAAa,QAAQ,eAAe,KAAK,QAAQ,eAAe;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,cAAc,SAAiC;AAC7C,SAAK,UAAU,QAAQ;AAAA,MACrB,MAAM;AAAA,MACN,SAAS,EAAE,GAAG,SAAS,SAAS,QAAQ,WAAW,KAAK,QAAQ,QAAQ;AAAA,IAC1E,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WAAsC;AAC1C,WAAO,KAAK,UAAU,MAAM,SAAS;AAAA,EACvC;AAAA,EAEA,MAAM,WAAsC;AAC1C,WAAO,KAAK,UAAU,MAAM,SAAS;AAAA,EACvC;AACF;;;AClHA,IAAM,sBAAsB;AAGrB,IAAM,YAAN,MAAgB;AAAA,EAOrB,YACmBC,SACjB,UAA4B,CAAC,GAC7B,YACA;AAHiB,kBAAAA;AAIjB,SAAK,aAAa,QAAQ,cAAc;AACxC,SAAK,aAAa;AAClB,SAAK,OAAO,QAAQ,QAAQ;AAC5B,SAAK,WAAW,QAAQ;AAAA,EAC1B;AAAA,EAfiB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT;AAAA,EAaR,QAAc;AACZ,QAAI,KAAK,MAAO;AAChB,SAAK,KAAK;AACV,SAAK,QAAQ,YAAY,MAAM,KAAK,KAAK,GAAG,KAAK,UAAU;AAC3D,eAAW,KAAK,KAAK;AAAA,EACvB;AAAA,EAEA,OAAa;AACX,QAAI,KAAK,OAAO;AACd,oBAAc,KAAK,KAAK;AACxB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,OAAa;AACnB,SAAK,OAAO,cAAc;AAAA,MACxB,aAAa,KAAK;AAAA,MAClB,MAAM,KAAK;AAAA,MACX,aAAa,KAAK;AAAA,MAClB,WAAW,OAAO;AAAA,MAClB,UAAU,KAAK;AAAA,IACjB,CAAC;AAAA,EACH;AACF;;;AC5CA,IAAI,YAAY;AAOT,SAAS,sBAAsBC,SAAgB,UAA6B;AACjF,MAAI,UAAW;AACf,cAAY;AAEZ,MAAI,OAAO,GAAG;AACZ,YAAQ,GAAG,qBAAqB,CAAC,UAAiB;AAChD,MAAAA,QAAO,iBAAiB,OAAO,EAAE,OAAO,SAAS,MAAM,EAAE,WAAW,oBAAoB,EAAE,GAAG,SAAS,CAAC;AACvG,WAAKA,QAAO,MAAM,GAAK,EAAE,KAAK,MAAM;AAClC,YAAI,QAAQ,cAAc,mBAAmB,KAAK,GAAG;AACnD,kBAAQ,MAAM,KAAK;AACnB,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAED,YAAQ,GAAG,sBAAsB,CAAC,WAAoB;AACpD,MAAAA,QAAO,iBAAiB,QAAQ,EAAE,OAAO,SAAS,MAAM,EAAE,WAAW,qBAAqB,EAAE,GAAG,SAAS,CAAC;AAEzG,WAAKA,QAAO,MAAM,GAAK;AAAA,IACzB,CAAC;AAGD,YAAQ,GAAG,cAAc,MAAM;AAC7B,WAAKA,QAAO,MAAM,GAAK;AAAA,IACzB,CAAC;AACD;AAAA,EACF;AAEA,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,iBAAiB,SAAS,WAAS;AACxC,MAAAA,QAAO,iBAAiB,MAAM,SAAS,MAAM,SAAS,EAAE,MAAM,EAAE,WAAW,UAAU,EAAE,GAAG,SAAS,CAAC;AAAA,IACtG,CAAC;AACD,WAAO,iBAAiB,sBAAsB,WAAS;AACrD,MAAAA,QAAO,iBAAiB,MAAM,QAAQ,EAAE,MAAM,EAAE,WAAW,uBAAuB,EAAE,GAAG,SAAS,CAAC;AAAA,IACnG,CAAC;AACD,WAAO,iBAAiB,YAAY,MAAM;AACxC,WAAKA,QAAO,MAAM,GAAK;AAAA,IACzB,CAAC;AAAA,EACH;AACF;;;AC5CO,IAAM,QAAN,MAAM,OAAM;AAAA,EACjB,OAA+B,CAAC;AAAA,EAChC;AAAA,EACA,WAAoD,CAAC;AAAA,EACrD,QAAiC,CAAC;AAAA,EAClC;AAAA,EACA;AAAA,EACA,cAA4B,CAAC;AAAA,EAE7B,OAAO,KAAa,OAAqB;AACvC,SAAK,KAAK,GAAG,IAAI;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAAoC;AAC1C,WAAO,OAAO,KAAK,MAAM,IAAI;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAA8B;AACpC,SAAK,OAAO,QAAQ;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,MAAc,SAA+C;AACtE,QAAI,YAAY,MAAM;AACpB,aAAO,KAAK,SAAS,IAAI;AAAA,IAC3B,OAAO;AACL,WAAK,SAAS,IAAI,IAAI;AAAA,IACxB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,KAAa,OAAsB;AAC1C,SAAK,MAAM,GAAG,IAAI;AAClB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,QAAuC;AAC/C,WAAO,OAAO,KAAK,OAAO,MAAM;AAChC,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAAuB;AAC9B,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA,EAEA,eAAe,aAA6B;AAC1C,SAAK,cAAc;AACnB,WAAO;AAAA,EACT;AAAA,EAEA,cAAc,OAAwB,gBAA8B;AAClE,SAAK,YAAY,KAAK,EAAE,WAAW,OAAO,GAAG,GAAG,MAAM,CAAC;AACvD,QAAI,KAAK,YAAY,SAAS,gBAAgB;AAC5C,WAAK,YAAY,OAAO,GAAG,KAAK,YAAY,SAAS,cAAc;AAAA,IACrE;AACA,WAAO;AAAA,EACT;AAAA,EAEA,mBAAyB;AACvB,SAAK,cAAc,CAAC;AACpB,WAAO;AAAA,EACT;AAAA,EAEA,QAAe;AACb,UAAM,OAAO,IAAI,OAAM;AACvB,SAAK,OAAO,EAAE,GAAG,KAAK,KAAK;AAC3B,SAAK,OAAO,KAAK,OAAO,EAAE,GAAG,KAAK,KAAK,IAAI;AAC3C,SAAK,WAAW,OAAO,YAAY,OAAO,QAAQ,KAAK,QAAQ,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;AAC/F,SAAK,QAAQ,EAAE,GAAG,KAAK,MAAM;AAC7B,SAAK,QAAQ,KAAK;AAClB,SAAK,cAAc,KAAK,cAAc,CAAC,GAAG,KAAK,WAAW,IAAI;AAC9D,SAAK,cAAc,CAAC,GAAG,KAAK,WAAW;AACvC,WAAO;AAAA,EACT;AACF;;;AC/EA,SAAS,SAAiB;AACxB,SAAO,MAAM,EAAE,MAAM,GAAG,EAAE;AAC5B;AAEO,IAAM,OAAN,MAAW;AAAA,EAOhB,YACmB,aACR,cACA,IACA,aACT;AAJiB;AACR;AACA;AACA;AAAA,EACR;AAAA,EAXM,SAAS,OAAO;AAAA,EAChB,iBAAiB,OAAO;AAAA,EACjC,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EASA,UAAU,QAAsB;AAC9B,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,KAAa,OAAsB;AACzC,SAAK,OAAO,EAAE,GAAG,KAAK,MAAM,CAAC,GAAG,GAAG,MAAM;AACzC,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,IAAa,aAA4B;AAClD,WAAO,KAAK,YAAY,WAAW,KAAK,QAAQ,IAAI,WAAW;AAAA,EACjE;AAAA,EAEA,SAAe;AACb,QAAI,CAAC,KAAK,aAAc,MAAK,eAAe,OAAO;AAAA,EACrD;AAAA,EAEA,SAAmB;AACjB,WAAO;AAAA,MACL,SAAS,KAAK;AAAA,MACd,gBAAgB,KAAK;AAAA,MACrB,IAAI,KAAK;AAAA,MACT,aAAa,KAAK;AAAA,MAClB,QAAQ,KAAK;AAAA,MACb,iBAAiB,KAAK;AAAA,MACtB,WAAW,KAAK,gBAAgB,OAAO;AAAA,MACvC,MAAM,KAAK;AAAA,IACb;AAAA,EACF;AACF;AAMO,IAAM,cAAN,MAAkB;AAAA,EASvB,YACmBC,SACV,MACE,IACQ,UAAU,MAC3B;AAJiB,kBAAAA;AACV;AACE;AACQ;AAAA,EAChB;AAAA,EAbM,UAAU,MAAM;AAAA,EAChB,SAAS,OAAO;AAAA,EAChB,iBAAiB,OAAO;AAAA,EACjC,SAAS;AAAA,EACQ,QAAgB,CAAC;AAAA,EACjB,OAA+B,CAAC;AAAA,EACzC,WAAW;AAAA,EASnB,WAAW,cAAsB,IAAa,aAA4B;AACxE,UAAM,OAAO,IAAI,KAAK,MAAM,cAAc,IAAI,WAAW;AACzD,SAAK,MAAM,KAAK,IAAI;AACpB,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,WAAW,IAAa,aAA4B;AAClD,WAAO,KAAK,WAAW,KAAK,QAAQ,IAAI,WAAW;AAAA,EACrD;AAAA,EAEA,OAAO,KAAa,OAAqB;AACvC,SAAK,KAAK,GAAG,IAAI;AACjB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,QAAsB;AAC9B,SAAK,SAAS;AACd,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,MAAoB;AAC1B,SAAK,OAAO;AACZ,WAAO;AAAA,EACT;AAAA,EAEA,SAAe;AACb,QAAI,KAAK,SAAU;AACnB,SAAK,WAAW;AAEhB,eAAW,QAAQ,KAAK,MAAO,MAAK,OAAO;AAE3C,QAAI,CAAC,KAAK,WAAW,CAAC,KAAK,OAAQ;AACnC,UAAM,UAA8B;AAAA,MAClC,UAAU,KAAK;AAAA,MACf,MAAM,KAAK;AAAA,MACX,IAAI,KAAK;AAAA,MACT,QAAQ,KAAK;AAAA,MACb,iBAAiB,KAAK;AAAA,MACtB,WAAW,OAAO;AAAA,MAClB,OAAO,KAAK,MAAM,IAAI,UAAQ,KAAK,OAAO,CAAC;AAAA,MAC3C,MAAM,OAAO,KAAK,KAAK,IAAI,EAAE,SAAS,IAAI,KAAK,OAAO;AAAA,IACxD;AACA,SAAK,OAAO,gBAAgB,OAAO;AAAA,EACrC;AACF;;;ACzGO,SAAS,YAAYC,SAAgB,SAAiC;AAC3E,QAAM,YAAY,QAAQ,aAAa,MAAM;AAC7C,EAAAA,QAAO,YAAY;AAAA,IACjB,aAAa;AAAA,IACb,cAAc,QAAQ;AAAA,IACtB,QAAQ,QAAQ;AAAA,IAChB,aAAa,QAAQ;AAAA,IACrB,UAAU,QAAQ;AAAA,IAClB,UAAU,QAAQ;AAAA,EACpB,CAAC;AACD,SAAO;AACT;AAQA,eAAsB,gBACpBA,SACA,cACA,aACA,IACA,SACY;AACZ,QAAM,YAAY,YAAYA,SAAQ;AAAA,IACpC;AAAA,IACA,QAAQ;AAAA,IACR,UAAU,SAAS;AAAA,IACnB,UAAU,SAAS;AAAA,EACrB,CAAC;AACD,QAAM,YAAY,KAAK,IAAI;AAE3B,MAAI;AACF,UAAM,SAAS,MAAM,GAAG;AACxB,gBAAYA,SAAQ;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,IACrB,CAAC;AACD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,gBAAYA,SAAQ;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,YAAY,KAAK,IAAI,IAAI;AAAA,MACzB,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,IACrB,CAAC;AACD,iBAAa,KAAK;AAClB,UAAM;AAAA,EACR;AACF;;;ACrEA,IAAMC,mBAAkB,CAAC,KAAO,KAAO,IAAM;AAEtC,IAAM,kBAAN,cAA8B,MAAM;AAAA,EACzC,YACE,SACS,QACT;AACA,UAAM,OAAO;AAFJ;AAGT,SAAK,OAAO;AAAA,EACd;AACF;AASO,IAAM,aAAN,MAAiB;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAA4B;AACtC,SAAK,UAAU,QAAQ;AACvB,SAAK,MAAM,QAAQ;AACnB,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAEQ,UAAkC;AACxC,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,eAAe,UAAU,KAAK,GAAG;AAAA,IACnC;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,KAAK,SAA6B,QAAoD;AAC1F,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,SAAS;AAAA,MACnD,QAAQ;AAAA,MACR,SAAS,KAAK,QAAQ;AAAA,MACtB,MAAM,KAAK,UAAU,OAAO;AAAA,MAC5B;AAAA,IACF,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,gBAAgB,qBAAqB,SAAS,MAAM,KAAK,SAAS,MAAM;AAAA,IACpF;AACA,WAAQ,MAAM,SAAS,KAAK;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU,OAAe,QAAgD;AAC7E,aAAS,UAAU,KAAK,WAAW;AACjC,UAAI;AACJ,UAAI;AACF,cAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,SAAS,mBAAmB,KAAK,CAAC,IAAI;AAAA,UAChF,QAAQ;AAAA,UACR,SAAS,KAAK,QAAQ;AAAA,UACtB,MAAM,KAAK,UAAU,MAAM;AAAA,QAC7B,CAAC;AACD,YAAI,SAAS,GAAI;AACjB,YAAI,SAAS,UAAU,OAAO,SAAS,SAAS,OAAO,SAAS,WAAW,KAAK;AAC9E,gBAAM,IAAI,gBAAgB,0BAA0B,SAAS,MAAM,KAAK,SAAS,MAAM;AAAA,QACzF;AACA,oBAAY,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE;AAAA,MACjD,SAAS,OAAO;AACd,YAAI,iBAAiB,gBAAiB,OAAM;AAC5C,oBAAY;AAAA,MACd;AAEA,YAAM,QAAQA,iBAAgB,OAAO;AACrC,UAAI,UAAU,QAAW;AACvB,cAAM,IAAI,MAAM,iBAAiB,KAAK,gCAA6B,OAAO,SAAS,CAAC,EAAE;AAAA,MACxF;AACA,WAAK,OAAO,KAAK,0BAA0B,KAAK,KAAK,OAAO,SAAS,CAAC,eAAe,KAAK,IAAI;AAC9F,YAAM,MAAM,KAAK;AAAA,IACnB;AAAA,EACF;AACF;;;AChFA,IAAM,gCAAgC;AACtC,IAAM,wBAAwB;AAC9B,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAQnB,IAAM,cAAN,MAAkB;AAAA,EAYvB,YACmB,KACA,OACjB,MACiB,QACjB,iBACA;AALiB;AACA;AAEA;AAGjB,SAAK,kBAAkB,mBAAmB;AAC1C,SAAK,UAAU;AAAA,MACb;AAAA,MACA;AAAA,MACA,KAAK,CAAC,OAAO,YAAY,KAAK,IAAI,OAAO,OAAO;AAAA,MAChD,QAAQ,KAAK,gBAAgB;AAAA,IAC/B;AAAA,EACF;AAAA,EAzBS;AAAA,EAED,SAAwB,CAAC;AAAA,EACzB,cAAc;AAAA,EACd,eAAe;AAAA,EACf,OAAO;AAAA,EACP,QAAuB,QAAQ,QAAQ;AAAA,EACvC;AAAA,EACS,kBAAkB,IAAI,gBAAgB;AAAA,EACtC;AAAA,EAkBjB,IAAI,SAAkB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA,EAGA,QAAc;AACZ,QAAI,CAAC,KAAK,gBAAgB,OAAO,QAAS,MAAK,gBAAgB,MAAM;AAAA,EACvE;AAAA,EAEQ,IAAI,OAAoB,SAAuB;AACrD,QAAI,KAAK,KAAM;AACf,QAAI,KAAK,eAAe,kBAAkB;AACxC,WAAK;AACL;AAAA,IACF;AACA,SAAK;AACL,UAAM,YACJ,QAAQ,SAAS,wBAAwB,GAAG,QAAQ,MAAM,GAAG,qBAAqB,CAAC,sBAAiB;AACtG,SAAK,OAAO,KAAK,EAAE,IAAI,OAAO,GAAG,OAAO,SAAS,UAAU,CAAC;AAE5D,QAAI,KAAK,OAAO,UAAU,mBAAmB;AAC3C,WAAK,UAAU;AAAA,IACjB,OAAO;AACL,WAAK,cAAc;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,gBAAsB;AAC5B,QAAI,KAAK,MAAO;AAChB,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,QAAQ;AACb,WAAK,UAAU;AAAA,IACjB,GAAG,KAAK,eAAe;AACvB,eAAW,KAAK,KAAK;AAAA,EACvB;AAAA,EAEQ,kBAAwB;AAC9B,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEQ,WAA0B;AAChC,UAAM,OAAO,KAAK,OAAO,OAAO,GAAG,KAAK,OAAO,MAAM;AACrD,QAAI,KAAK,eAAe,GAAG;AACzB,WAAK,KAAK;AAAA,QACR,IAAI,OAAO;AAAA,QACX,OAAO;AAAA,QACP,SAAS,GAAG,KAAK,YAAY,gCAAgC,gBAAgB;AAAA,MAC/E,CAAC;AACD,WAAK,eAAe;AAAA,IACtB;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,YAAkB;AACxB,SAAK,gBAAgB;AACrB,QAAI,KAAK,QAAQ,KAAK,OAAO,WAAW,EAAG;AAC3C,UAAM,OAAO,KAAK,OAAO,OAAO,GAAG,KAAK,OAAO,MAAM;AACrD,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,oBAAoB;AACxD,WAAK,QAAQ,EAAE,QAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAAA,IACjF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,gBAAkC;AACtC,SAAK,QAAQ,EAAE,QAAQ,UAAU,CAAC;AAClC,UAAM,KAAK;AACX,WAAO,CAAC,KAAK;AAAA,EACf;AAAA,EAEA,gBAAsB;AACpB,SAAK,gBAAgB;AACrB,SAAK,QAAQ,EAAE,QAAQ,aAAa,MAAM,KAAK,SAAS,EAAE,CAAC;AAAA,EAC7D;AAAA,EAEA,cAAc,OAA8B;AAC1C,SAAK,gBAAgB;AACrB,SAAK,QAAQ,EAAE,QAAQ,UAAU,OAAO,MAAM,KAAK,SAAS,EAAE,CAAC;AAAA,EACjE;AAAA;AAAA,EAGA,WAA0B;AACxB,WAAO,KAAK;AAAA,EACd;AAAA,EAEQ,QAAQ,QAAuC;AACrD,QAAI,KAAK,KAAM;AACf,SAAK,QAAQ,KAAK,MAAM,KAAK,YAAY;AACvC,UAAI,KAAK,KAAM;AACf,YAAM,UAAU,OAAO,QAAQ,OAAO,KAAK,WAAW,IAAI,EAAE,GAAG,QAAQ,MAAM,OAAU,IAAI;AAC3F,UAAI;AACF,cAAM,KAAK,IAAI,UAAU,KAAK,OAAO,OAAO;AAAA,MAC9C,SAAS,OAAO;AACd,YAAI,iBAAiB,oBAAoB,MAAM,WAAW,OAAO,MAAM,WAAW,MAAM;AACtF,eAAK,OAAO;AACZ,eAAK,MAAM;AACX,eAAK,SAAS,CAAC;AACf,eAAK,OAAO,KAAK,OAAO,KAAK,KAAK,0DAAqD;AACvF;AAAA,QACF;AACA,aAAK,OAAO,MAAM,iBAAiB,KAAK,KAAK,aAAa,KAAK;AAAA,MACjE;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACjJA,IAAM,2BAA2B;AACjC,IAAM,uBAAuB;AAC7B,IAAM,kBAAkB;AACxB,IAAM,uBAAuB,CAAC,KAAO,KAAO,IAAM;AAClD,IAAM,2BAA2B;AAKjC,SAAS,WAA+B;AACtC,MAAI,CAAC,OAAO,EAAG,QAAO;AACtB,SAAO,QAAQ,IAAI,YAAY,QAAQ,IAAI,gBAAgB;AAC7D;AAOO,IAAM,eAAN,MAAmB;AAAA,EAkBxB,YACmB,SACAC,WACjB;AAFiB;AACA,oBAAAA;AAEjB,SAAK,SAAS,WAAW,QAAQ,SAAS,OAAO,kBAAkB;AACnE,UAAM,SAAS,cAAc,SAAS,kBAAkB;AACxD,SAAK,MAAM,IAAI,WAAW,EAAE,SAAS,OAAO,gBAAgB,KAAK,OAAO,KAAK,QAAQ,KAAK,OAAO,CAAC;AAClG,SAAK,iBAAiB,KAAK,IAAI,sBAAsB,QAAQ,kBAAkB,wBAAwB;AACvG,SAAK,cAAc,KAAK,IAAI,iBAAiB,KAAK,IAAI,GAAG,QAAQ,eAAe,CAAC,CAAC;AAClF,SAAK,aAAa,QAAQ;AAC1B,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,qBAAqB,QAAQ;AAClC,SAAK,OAAO,MAAM,sBAAsB,EAAE,SAAS,OAAO,eAAe,CAAC;AAAA,EAC5E;AAAA,EA9BS;AAAA,EAEQ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,QAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EACjB,aAAa,oBAAI,IAAmB;AAAA,EACpC,YAAY,oBAAI,IAAiB;AAAA,EAiBlD,IAAI,cAAsB;AACxB,WAAO,KAAK,WAAW;AAAA,EACzB;AAAA,EAEA,QAAc;AACZ,QAAI,KAAK,UAAU,UAAW;AAC9B,QAAI,KAAK,UAAU,YAAY;AAC7B,YAAM,IAAI,MAAM,gFAA2E;AAAA,IAC7F;AACA,QAAI,KAAK,SAAS,SAAS,GAAG;AAC5B,YAAM,IAAI,MAAM,mFAA8E;AAAA,IAChG;AACA,SAAK,QAAQ;AACb,SAAK,OAAO,MAAM,4BAA4B,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG;AACrF,SAAK,SAAS,CAAC;AAAA,EACjB;AAAA;AAAA,EAGA,MAAM,KAAK,YAAY,KAA0B;AAC/C,QAAI,KAAK,UAAU,OAAQ,QAAO;AAClC,SAAK,QAAQ;AACb,QAAI,KAAK,OAAO;AACd,mBAAa,KAAK,KAAK;AACvB,WAAK,QAAQ;AAAA,IACf;AACA,SAAK,WAAW,MAAM;AAEtB,UAAM,MAAM,QAAQ,WAAW,CAAC,GAAG,KAAK,UAAU,CAAC,EAAE,KAAK,MAAM,IAAI;AACpE,UAAM,WAAW,YAAY,IAAI,MAAM,QAAQ,KAAK,CAAC,KAAK,MAAM,SAAS,EAAE,KAAK,MAAM,KAAK,CAAC,CAAC,IAAI;AACjG,QAAI,CAAC,YAAY,KAAK,WAAW,OAAO,GAAG;AACzC,WAAK,OAAO,KAAK,GAAG,KAAK,WAAW,IAAI,2CAAkC,SAAS,gCAA2B;AAC9G,iBAAW,YAAY,KAAK,UAAW,UAAS,MAAM;AAAA,IACxD;AACA,SAAK,QAAQ;AACb,WAAO;AAAA,EACT;AAAA;AAAA,EAGQ,SAAS,SAAuB;AACtC,QAAI,KAAK,UAAU,aAAa,KAAK,MAAO;AAC5C,SAAK,QAAQ,WAAW,MAAM;AAC5B,WAAK,QAAQ;AACb,WAAK,KAAK,KAAK;AAAA,IACjB,GAAG,OAAO;AAAA,EACZ;AAAA,EAEA,MAAc,OAAsB;AAClC,QAAI,KAAK,UAAU,UAAW;AAC9B,QAAI,KAAK,WAAW,QAAQ,KAAK,aAAa;AAC5C,WAAK,SAAS,KAAK,cAAc;AACjC;AAAA,IACF;AAEA,SAAK,YAAY,IAAI,gBAAgB;AACrC,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,IAAI;AAAA,QAC9B;AAAA,UACE,OAAO;AAAA;AAAA;AAAA,YAGL,aAAa,KAAK;AAAA,YAClB,SAAS;AAAA,YACT,MAAM,SAAS;AAAA,YACf,OAAO,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,UACjC;AAAA,UACA,KAAK,KAAK,IAAI,iBAAiB,KAAK,cAAc,KAAK,WAAW,IAAI;AAAA,UACtE,OAAO,CAAC,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,QACjC;AAAA,QACA,KAAK,UAAU;AAAA,MACjB;AACA,WAAK,sBAAsB;AAC3B,WAAK,0BAA0B;AAE/B,iBAAW,OAAO,SAAS,MAAM;AAC/B,aAAK,SAAS,GAAG;AAAA,MACnB;AAEA,WAAK,SAAS,SAAS,KAAK,SAAS,IAAI,IAAI,KAAK,cAAc;AAAA,IAClE,SAAS,OAAO;AACd,UAAI,KAAK,UAAU,UAAW;AAC9B,WAAK,SAAS,KAAK,oBAAoB,KAAK,CAAC;AAAA,IAC/C,UAAE;AACA,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEQ,oBAAoB,OAAwB;AAClD,QAAI,iBAAiB,mBAAmB,MAAM,WAAW,KAAK;AAE5D,WAAK;AACL,UAAI,KAAK,4BAA4B,KAAK,KAAK,0BAA0B,OAAO,GAAG;AACjF,aAAK,OAAO,MAAM,0GAA0F;AAAA,MAC9G;AACA,aAAO,KAAK,IAAI,KAAK,gBAAgB,wBAAwB;AAAA,IAC/D;AACA,SAAK;AACL,UAAM,SAAS,qBAAqB,KAAK,IAAI,KAAK,sBAAsB,GAAG,qBAAqB,SAAS,CAAC,CAAC;AAC3G,UAAM,QAAQ,KAAK,IAAI,KAAK,IAAI,QAAQ,CAAC,GAAG,KAAK,IAAI,KAAK,gBAAgB,IAAM,CAAC;AACjF,SAAK,OAAO,KAAK,gBAAgB,OAAO,KAAK,CAAC,8BAA2B,KAAK,IAAI;AAClF,WAAO;AAAA,EACT;AAAA,EAEQ,SAAS,KAAiC;AAChD,UAAM,UAAU,KAAK,WAAW,GAAG,EAChC,MAAM,WAAS,KAAK,OAAO,MAAM,0BAA0B,IAAI,EAAE,KAAK,KAAK,CAAC,EAC5E,QAAQ,MAAM;AACb,WAAK,WAAW,OAAO,OAAO;AAC9B,UAAI,KAAK,UAAU,UAAW,MAAK,SAAS,CAAC;AAAA,IAC/C,CAAC;AACH,SAAK,WAAW,IAAI,OAAO;AAAA,EAC7B;AAAA,EAEA,MAAc,WAAW,KAA0C;AACjE,UAAM,WAAW,IAAI,YAAY,KAAK,KAAK,IAAI,IAAI,IAAI,MAAM,KAAK,QAAQ,KAAK,kBAAkB;AACjG,SAAK,UAAU,IAAI,QAAQ;AAC3B,QAAI;AACF,YAAM,UAAU,KAAK,SAAS,IAAI,IAAI,IAAI;AAC1C,UAAI,CAAC,SAAS;AAEZ,iBAAS,cAAc;AAAA,UACrB,MAAM;AAAA,UACN,SAAS,uCAAoC,IAAI,IAAI;AAAA,QACvD,CAAC;AACD,cAAM,SAAS,SAAS;AACxB;AAAA,MACF;AAEA,YAAM,KAAK,MAAM,SAAS,cAAc;AACxC,UAAI,CAAC,IAAI;AACP,aAAK,OAAO,MAAM,OAAO,IAAI,EAAE,6DAAqD;AACpF;AAAA,MACF;AAEA,WAAK,OAAO,MAAM,kBAAkB,IAAI,EAAE,KAAK,IAAI,IAAI,GAAG;AAC1D,UAAI;AACF,cAAM,KAAK,kBAAkB,SAAS,KAAK,QAAQ;AACnD,iBAAS,cAAc;AACvB,aAAK,OAAO,MAAM,OAAO,IAAI,EAAE,eAAY;AAAA,MAC7C,SAAS,OAAO;AACd,iBAAS,cAAc,WAAW,KAAK,CAAC;AACxC,aAAK,OAAO,MAAM,OAAO,IAAI,EAAE,YAAY,OAAO,KAAK,CAAC,EAAE;AAAA,MAC5D;AACA,YAAM,SAAS,SAAS;AAAA,IAC1B,UAAE;AACA,WAAK,UAAU,OAAO,QAAQ;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,MAAc,kBACZ,SACA,KACA,UACe;AACf,UAAM,aAAa,QAAQ,QAAQ,EAAE,KAAK,MAAM,QAAQ,IAAI,QAAQ,SAAS,OAAO,CAAC;AACrF,QAAI,CAAC,KAAK,iBAAiB,KAAK,iBAAiB,GAAG;AAClD,YAAM;AACN;AAAA,IACF;AAEA,UAAM,YAAY,KAAK;AACvB,UAAM,UAAU,MAAM,SAAS,EAAE,KAAK,MAAM,gBAAgB;AAC5D,UAAM,UAAU,MAAM,QAAQ,KAAK,CAAC,YAAY,OAAO,CAAC;AACxD,QAAI,YAAY,iBAAkB;AAGlC,aAAS,MAAM;AACf,eACG,KAAK,MAAM,KAAK,OAAO,KAAK,OAAO,IAAI,EAAE,kCAAkC,SAAS,IAAI,CAAC,EACzF,MAAM,MAAM,KAAK,OAAO,KAAK,OAAO,IAAI,EAAE,gCAAgC,SAAS,sBAAsB,CAAC;AAC7G,UAAM,OAAO,OAAO,IAAI,MAAM,mBAAgB,SAAS,6CAA6C,GAAG;AAAA,MACrG,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACF;AAEA,IAAM,mBAAmB,uBAAO,cAAc;AAE9C,IAAM,0BAA0B;AAChC,IAAM,wBAAwB;AAE9B,SAAS,SAAS,OAAe,KAAqB;AACpD,SAAO,MAAM,SAAS,MAAM,GAAG,MAAM,MAAM,GAAG,GAAG,CAAC,sBAAiB;AACrE;AAEA,SAAS,WAAW,OAAiC;AACnD,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,MAAM,MAAM;AAAA,MACZ,SAAS,SAAS,MAAM,SAAS,uBAAuB;AAAA,MACxD,OAAO,MAAM,QAAQ,SAAS,MAAM,OAAO,qBAAqB,IAAI;AAAA,IACtE;AAAA,EACF;AACA,SAAO,EAAE,SAAS,SAAS,OAAO,KAAK,GAAG,uBAAuB,EAAE;AACrE;;;ACjPA,IAAM,0BAA0B;AAEhC,IAAI;AACJ,IAAI,QAAQ,IAAI,MAAM;AACtB,IAAI;AACJ,IAAI;AACJ,IAAM,WAAW,oBAAI,IAAgC;AACrD,IAAI,wBAAwB;AAGrB,SAAS,KAAK,SAA4B;AAC/C,MAAI,QAAQ;AACV,WAAO,OAAO,KAAK,sEAAiE;AACpF,eAAW,KAAK;AAChB,gBAAY;AAAA,EACd;AACA,MAAI,OAAO;AACT,SAAK,MAAM,KAAK,CAAC;AACjB,YAAQ;AAAA,EACV;AACA,0BAAwB;AAExB,WAAS,IAAI,OAAO,OAAO;AAE3B,MAAI,QAAQ,qBAAqB,OAAO;AACtC,0BAAsB,QAAQ,MAAM,KAAK;AAAA,EAC3C;AAEA,MAAI,QAAQ,WAAW;AACrB,UAAM,mBAAmB,QAAQ,cAAc,OAAO,CAAC,IAAI,QAAQ;AACnE,gBAAY,IAAI,UAAU,QAAQ,kBAAkB,QAAQ,UAAU;AACtE,cAAU,MAAM;AAAA,EAClB;AAEA,MAAI,QAAQ,SAAS;AACnB,UAAM,iBAAiB,QAAQ,YAAY,OAAO,CAAC,IAAI,QAAQ;AAC/D,YAAQ,IAAI;AAAA,MACV,EAAE,GAAG,gBAAgB,cAAc,QAAQ,cAAc,YAAY,QAAQ,YAAY,OAAO,QAAQ,MAAM;AAAA,MAC9G;AAAA,IACF;AAAA,EACF;AAEA,SAAO,OAAO,MAAM,gBAAgB,EAAE,UAAU,OAAO,OAAO,eAAe,CAAC;AAChF;AAEO,SAAS,YAAgC;AAC9C,SAAO;AACT;AAGO,SAAS,iBAAiB,OAAgB,MAAwC;AACvF,SAAO,QAAQ,iBAAiB,OAAO,MAAM,KAAK;AACpD;AAEO,SAAS,eAAe,SAAiB,QAAkB,QAAQ,MAAwC;AAChH,SAAO,QAAQ,eAAe,SAAS,OAAO,MAAM,KAAK;AAC3D;AAGO,SAAS,cAAc,OAA8B;AAC1D,QAAM,cAAc,OAAO,QAAQ,QAAQ,kBAAkB,uBAAuB;AACtF;AAEO,SAAS,OAAO,KAAa,OAAqB;AACvD,QAAM,OAAO,KAAK,KAAK;AACzB;AAEO,SAAS,QAAQ,MAAoC;AAC1D,QAAM,QAAQ,IAAI;AACpB;AAEO,SAAS,QAAQ,MAA8B;AACpD,QAAM,QAAQ,IAAI;AACpB;AAEO,SAAS,WAAW,MAAc,SAA+C;AACtF,QAAM,WAAW,MAAM,OAAO;AAChC;AAEO,SAAS,SAAS,KAAa,OAAsB;AAC1D,QAAM,SAAS,KAAK,KAAK;AAC3B;AAGO,SAAS,UAAa,UAAkC;AAC7D,QAAM,WAAW;AACjB,UAAQ,SAAS,MAAM;AACvB,MAAI;AACF,WAAO,SAAS,KAAK;AAAA,EACvB,UAAE;AACA,YAAQ;AAAA,EACV;AACF;AAGO,SAAS,iBAAiB,MAAc,IAA0B;AACvE,QAAM,OAAO,QAAQ,QAAQ,oBAAoB;AACjD,QAAM,UAAU,QAAQ,KAAK,KAAK,OAAO,IAAI;AAC7C,SAAO,IAAI,YAAY,QAAQ,MAAM,IAAI,OAAO;AAClD;AAGO,SAAS,QAAQ,SAA6C;AACnE,SAAO,SAAS,YAAY,QAAQ,OAAO,IAAI;AACjD;AAGA,eAAsB,YACpB,aACA,IACA,SACY;AACZ,MAAI,CAAC,OAAQ,QAAO,GAAG;AACvB,SAAO;AAAA,IACL;AAAA,IACA,WAAS,iBAAiB,OAAO,EAAE,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;AAAA,IACnE;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAGO,SAAS,MAAM,WAAsC;AAC1D,SAAO,SAAS,OAAO,MAAM,SAAS,IAAI,QAAQ,QAAQ,IAAI;AAChE;AAGO,SAAS,SAAsC,MAAc,SAAsC;AACxG,MAAI,SAAS,IAAI,IAAI,GAAG;AACtB,KAAC,OAAO,UAAU,QAAQ,SAAS,KAAK,aAAa,IAAI,sCAAsC;AAAA,EACjG;AACA,MAAI,UAAU,CAAC,SAAS,CAAC,uBAAuB;AAC9C,4BAAwB;AACxB,WAAO,OAAO;AAAA,MACZ,aAAa,IAAI;AAAA,IACnB;AAAA,EACF;AACA,WAAS,IAAI,MAAM,OAA6B;AAClD;AAMO,SAAS,QAAc;AAC5B,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,6GAA+F;AAAA,EACjH;AACA,QAAM,MAAM;AACd;AAGO,SAAS,KAAK,WAAsC;AACzD,SAAO,QAAQ,MAAM,KAAK,SAAS,IAAI,QAAQ,QAAQ,IAAI;AAC7D;AAMA,eAAsB,MAAM,WAAsC;AAChE,QAAM,eAAe,QAAQ,MAAM,MAAM,KAAK,SAAS,IAAI;AAC3D,aAAW,KAAK;AAChB,cAAY;AACZ,QAAM,eAAe,SAAS,MAAM,OAAO,MAAM,SAAS,IAAI;AAC9D,SAAO,gBAAgB;AACzB;","names":["scope","client","client","client","client","RETRY_DELAYS_MS","registry"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/manager/protocol.ts"],"sourcesContent":["/**\n * Tipos do protocolo do Hobots Manager (agente SDK ↔ servidor).\n *\n * Este arquivo é a fonte de verdade do wire format e não pode importar nada:\n * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`\n * contra estes tipos (reexportados por `hobots/protocol`; `hobots/manager/protocol` é alias transitório).\n */\n\n/** Ciclo de vida completo de uma run no servidor. */\nexport type ManagerRunStatus = 'pending' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'canceled';\n\n/** Subconjunto que o agente pode enviar no PATCH. */\nexport type ManagerRunUpdateStatus = 'running' | 'succeeded' | 'failed';\n\nexport type RunLogLevel = 'debug' | 'info' | 'warning' | 'error';\n\nexport interface RunLogEntry {\n /** ISO 8601 — relógio do agente, apenas para exibição */\n ts: string;\n level: RunLogLevel;\n message: string;\n}\n\nexport interface ManagerAgentInfo {\n /** Identidade canônica do agente — correlaciona com o heartbeat do Monitor */\n instance_id: string;\n name?: string;\n /** Versão do SDK */\n version?: string;\n /** Hostname da máquina */\n host?: string;\n /** Tasks registradas no agente */\n tasks?: string[];\n}\n\n/** POST /
|
|
1
|
+
{"version":3,"sources":["../../src/manager/protocol.ts"],"sourcesContent":["/**\n * Tipos do protocolo do Hobots Manager (agente SDK ↔ servidor).\n *\n * Este arquivo é a fonte de verdade do wire format e não pode importar nada:\n * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`\n * contra estes tipos (reexportados por `hobots/protocol`; `hobots/manager/protocol` é alias transitório).\n */\n\n/** Ciclo de vida completo de uma run no servidor. */\nexport type ManagerRunStatus = 'pending' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'canceled';\n\n/** Subconjunto que o agente pode enviar no PATCH. */\nexport type ManagerRunUpdateStatus = 'running' | 'succeeded' | 'failed';\n\nexport type RunLogLevel = 'debug' | 'info' | 'warning' | 'error';\n\nexport interface RunLogEntry {\n /** ISO 8601 — relógio do agente, apenas para exibição */\n ts: string;\n level: RunLogLevel;\n message: string;\n}\n\nexport interface ManagerAgentInfo {\n /** Identidade canônica do agente — correlaciona com o heartbeat do Monitor */\n instance_id: string;\n name?: string;\n /** Versão do SDK */\n version?: string;\n /** Hostname da máquina */\n host?: string;\n /** Tasks registradas no agente */\n tasks?: string[];\n}\n\n/** POST /v1/manager/poll */\nexport interface ManagerPollRequest {\n agent?: ManagerAgentInfo;\n /** Quantas runs reivindicar de uma vez (1..5). Default: 1 */\n max?: number;\n /** Só entrega runs destas tasks (nomes registrados no agente) */\n tasks?: string[];\n}\n\nexport interface ManagerRunDescriptor {\n id: string;\n task: string;\n params: Record<string, unknown>;\n form: { id: string; name: string } | null;\n /** Origem da run: 'manual' | 'link' | 'schedule' (informativo) */\n source: string;\n /** ISO 8601 (relógio do servidor) */\n created_at: string;\n}\n\nexport interface ManagerPollResponse {\n runs: ManagerRunDescriptor[];\n}\n\nexport interface ManagerRunError {\n /** ex.: nome da classe do erro */\n type?: string;\n message: string;\n stack?: string;\n}\n\n/** PATCH /v1/manager/runs/{id} — 'running' pode repetir com logs incrementais */\nexport interface ManagerRunUpdateRequest {\n status: ManagerRunUpdateStatus;\n /** Apenas com status 'failed' */\n error?: ManagerRunError;\n /** Delta desde o último envio — o servidor concatena */\n logs?: RunLogEntry[];\n}\n\nexport interface ManagerRunUpdateResponse {\n ok: true;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -27,7 +27,7 @@ interface ManagerAgentInfo {
|
|
|
27
27
|
/** Tasks registradas no agente */
|
|
28
28
|
tasks?: string[];
|
|
29
29
|
}
|
|
30
|
-
/** POST /
|
|
30
|
+
/** POST /v1/manager/poll */
|
|
31
31
|
interface ManagerPollRequest {
|
|
32
32
|
agent?: ManagerAgentInfo;
|
|
33
33
|
/** Quantas runs reivindicar de uma vez (1..5). Default: 1 */
|
|
@@ -57,7 +57,7 @@ interface ManagerRunError {
|
|
|
57
57
|
message: string;
|
|
58
58
|
stack?: string;
|
|
59
59
|
}
|
|
60
|
-
/** PATCH /
|
|
60
|
+
/** PATCH /v1/manager/runs/{id} — 'running' pode repetir com logs incrementais */
|
|
61
61
|
interface ManagerRunUpdateRequest {
|
|
62
62
|
status: ManagerRunUpdateStatus;
|
|
63
63
|
/** Apenas com status 'failed' */
|
|
@@ -27,7 +27,7 @@ interface ManagerAgentInfo {
|
|
|
27
27
|
/** Tasks registradas no agente */
|
|
28
28
|
tasks?: string[];
|
|
29
29
|
}
|
|
30
|
-
/** POST /
|
|
30
|
+
/** POST /v1/manager/poll */
|
|
31
31
|
interface ManagerPollRequest {
|
|
32
32
|
agent?: ManagerAgentInfo;
|
|
33
33
|
/** Quantas runs reivindicar de uma vez (1..5). Default: 1 */
|
|
@@ -57,7 +57,7 @@ interface ManagerRunError {
|
|
|
57
57
|
message: string;
|
|
58
58
|
stack?: string;
|
|
59
59
|
}
|
|
60
|
-
/** PATCH /
|
|
60
|
+
/** PATCH /v1/manager/runs/{id} — 'running' pode repetir com logs incrementais */
|
|
61
61
|
interface ManagerRunUpdateRequest {
|
|
62
62
|
status: ManagerRunUpdateStatus;
|
|
63
63
|
/** Apenas com status 'failed' */
|
package/docs/README.md
CHANGED
|
@@ -29,7 +29,6 @@ const clientSecret = 'hb_<64 hex>';
|
|
|
29
29
|
// O instanceId é a identidade única — o robô aparece como um agente só no painel.
|
|
30
30
|
Hobots.init({
|
|
31
31
|
clientSecret,
|
|
32
|
-
// baseUrl: 'http://localhost:3002', // só em desenvolvimento
|
|
33
32
|
instanceId: 'vm-cliente-01',
|
|
34
33
|
heartbeat: true,
|
|
35
34
|
manager: true,
|
package/docs/api-reference.md
CHANGED
|
@@ -31,14 +31,14 @@
|
|
|
31
31
|
| `flush` | `flush(timeoutMs?: number): Promise<boolean>` | enviou tudo? |
|
|
32
32
|
| `close` | `close(timeoutMs?: number): Promise<boolean>` | para o Manager (aguarda runs) + heartbeat + flush final do transport |
|
|
33
33
|
|
|
34
|
-
Classes exportadas: `Client`, `Scope`, `Transaction`, `Span`. Função `resolveConfig({ clientSecret
|
|
34
|
+
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):
|
|
35
35
|
|
|
36
36
|
```ts
|
|
37
37
|
interface ResolvedConfig {
|
|
38
38
|
key: string; // Client Secret do projeto (vai no Authorization: Bearer, nunca na URL)
|
|
39
|
-
baseUrl: string; //
|
|
40
|
-
ingestEndpoint: string; // <baseUrl>/
|
|
41
|
-
managerBaseUrl: string; // <baseUrl>/
|
|
39
|
+
baseUrl: string; // DEFAULT_BASE_URL, ou HOBOTS_API_URL em desenvolvimento
|
|
40
|
+
ingestEndpoint: string; // <baseUrl>/v1/ingest
|
|
41
|
+
managerBaseUrl: string; // <baseUrl>/v1/manager
|
|
42
42
|
}
|
|
43
43
|
```
|
|
44
44
|
|
|
@@ -73,7 +73,6 @@ No poll, o agente se identifica com `ManagerAgentInfo` (`hobots/protocol`): o ca
|
|
|
73
73
|
| Opção | Tipo | Default | Descrição |
|
|
74
74
|
| --- | --- | --- | --- |
|
|
75
75
|
| `clientSecret` | `string` | — | **obrigatório**; o Client Secret do projeto (`hb_<64 hex>`), copiado em **Configurações → Projetos** |
|
|
76
|
-
| `baseUrl` | `string` | `'https://app.hobots.app'` | host do app da Hobots — só sobrescreva em desenvolvimento (ex.: `http://localhost:3002`) |
|
|
77
76
|
| `environment` | `string` | `'production'` | ambiente lógico |
|
|
78
77
|
| `release` | `string` | — | versão do programa, ex. `robo-nfe@1.4.2` |
|
|
79
78
|
| `instanceId` | `string` | **obrigatório** | identidade única da instância; heartbeat do Monitor e agente do Manager convergem nela |
|
package/docs/getting-started.md
CHANGED
|
@@ -18,13 +18,13 @@ hb_<64 hex>
|
|
|
18
18
|
|
|
19
19
|
(Chaves antigas, 64 hex puros, continuam válidas no servidor.) A credencial é **secreta** e viaja sempre no header `Authorization: Bearer` — nunca na URL. Copie o Client Secret no app, em **Configurações → Projetos** — os snippets de integração já vêm prontos.
|
|
20
20
|
|
|
21
|
-
O SDK fala com `https://
|
|
21
|
+
O SDK fala com a API oficial `https://api2.hobots.app` automaticamente — não há configuração de host no `init()`. Em desenvolvimento, aponte para outro host com a env `HOBOTS_API_URL`:
|
|
22
22
|
|
|
23
|
-
```
|
|
24
|
-
|
|
23
|
+
```bash
|
|
24
|
+
HOBOTS_API_URL=http://localhost:3001 node meu-robo.js
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Veja [Protocolo & transporte](./protocol.md) para os endpoints derivados da
|
|
27
|
+
Veja [Protocolo & transporte](./protocol.md) para os endpoints derivados da URL base.
|
|
28
28
|
|
|
29
29
|
## Monitor e Manager — qual usar
|
|
30
30
|
|
|
@@ -42,7 +42,6 @@ import * as Hobots from 'hobots';
|
|
|
42
42
|
|
|
43
43
|
Hobots.init({
|
|
44
44
|
clientSecret: 'hb_<64 hex>',
|
|
45
|
-
// baseUrl: 'http://localhost:3002', // só em desenvolvimento
|
|
46
45
|
environment: 'production',
|
|
47
46
|
release: 'robo-nfe@1.4.2',
|
|
48
47
|
instanceId: 'vm-cliente-01', // identidade única: heartbeat + agente Manager
|
|
@@ -70,7 +69,6 @@ import * as Hobots from 'hobots';
|
|
|
70
69
|
|
|
71
70
|
Hobots.init({
|
|
72
71
|
clientSecret: 'hb_<64 hex>',
|
|
73
|
-
// baseUrl: 'http://localhost:3002', // só em desenvolvimento
|
|
74
72
|
instanceId: 'vm-cliente-01',
|
|
75
73
|
manager: true, // ou { pollIntervalMs, concurrency, ... }
|
|
76
74
|
});
|
package/docs/manager.md
CHANGED
|
@@ -9,7 +9,6 @@ import * as Hobots from 'hobots';
|
|
|
9
9
|
|
|
10
10
|
Hobots.init({
|
|
11
11
|
clientSecret: 'hb_<64 hex>',
|
|
12
|
-
// baseUrl: 'http://localhost:3002', // só em desenvolvimento
|
|
13
12
|
instanceId: 'vm-cliente-01',
|
|
14
13
|
manager: true, // ou { pollIntervalMs, concurrency, taskTimeoutMs, logFlushIntervalMs }
|
|
15
14
|
});
|
|
@@ -93,4 +92,4 @@ Todas as opções em [Referência de API → ManagerOptions](./api-reference.md#
|
|
|
93
92
|
|
|
94
93
|
## Como o claim funciona (resumo)
|
|
95
94
|
|
|
96
|
-
O SDK é um cliente HTTP: ele faz `POST /
|
|
95
|
+
O SDK é um cliente HTTP: ele faz `POST /v1/manager/poll` e o **servidor** reivindica as runs pendentes de forma atômica com `FOR UPDATE SKIP LOCKED` — dois agentes nunca pegam a mesma run. Detalhes em [Protocolo & transporte](./protocol.md).
|
package/docs/monitor.md
CHANGED
|
@@ -13,7 +13,6 @@ Todas as funções abaixo são no-op seguros se `Hobots.init()` não foi chamado
|
|
|
13
13
|
```js
|
|
14
14
|
Hobots.init({
|
|
15
15
|
clientSecret: 'hb_<64 hex>',
|
|
16
|
-
// baseUrl: 'http://localhost:3002', // só em desenvolvimento
|
|
17
16
|
environment: 'production',
|
|
18
17
|
release: 'robo-nfe@1.4.2',
|
|
19
18
|
instanceId: 'vm-cliente-01',
|
package/docs/protocol.md
CHANGED
|
@@ -14,16 +14,16 @@ hb_<64 hex>
|
|
|
14
14
|
|
|
15
15
|
| Canal | Endpoint | Autenticação |
|
|
16
16
|
| --- | --- | --- |
|
|
17
|
-
| Monitor (ingestão) | `POST <baseUrl>/
|
|
18
|
-
| Manager (execução) | `<baseUrl>/
|
|
17
|
+
| Monitor (ingestão) | `POST <baseUrl>/v1/ingest` | `Authorization: Bearer <clientSecret>` |
|
|
18
|
+
| Manager (execução) | `<baseUrl>/v1/manager/*` | `Authorization: Bearer <clientSecret>` |
|
|
19
19
|
|
|
20
|
-
`resolveConfig({ clientSecret
|
|
20
|
+
`resolveConfig({ clientSecret }) → { key, baseUrl, ingestEndpoint, managerBaseUrl }` (em `src/config.ts`, com a constante `DEFAULT_BASE_URL = 'https://api2.hobots.app'`; em desenvolvimento a env `HOBOTS_API_URL` sobrescreve a URL base). A credencial é **secreta** (formato `hb_<64 hex>`; chaves antigas de 64 hex puros continuam válidas no servidor) e viaja **só no header** `Authorization: Bearer` — nunca na URL da requisição.
|
|
21
21
|
|
|
22
|
-
> As DSNs foram **descontinuadas** em favor do Client Secret — tanto a antiga do Monitor (public key na URL, `POST /
|
|
22
|
+
> As DSNs foram **descontinuadas** em favor do Client Secret — tanto a antiga do Monitor (public key na URL, `POST /v1/ingest/<key>`, que responde **410** e o transport descarta sem retry) quanto a de key-na-URL (`https://<secretKey>@host/<slug>`). Copie o Client Secret em **Configurações → Projetos** no app.
|
|
23
23
|
|
|
24
24
|
## Monitor — ingestão
|
|
25
25
|
|
|
26
|
-
Endpoint fixo `POST /
|
|
26
|
+
Endpoint fixo `POST /v1/ingest` recebe **envelopes** JSON autenticados por Bearer. O transport mantém uma fila em memória, agrupa itens em envelopes e faz POST via `fetch`.
|
|
27
27
|
|
|
28
28
|
```jsonc
|
|
29
29
|
{
|
|
@@ -44,9 +44,9 @@ Tipos de item: `event`, `transaction`, `check_in`, `heartbeat` (definidos em `ho
|
|
|
44
44
|
|
|
45
45
|
## Manager — polling e reporte
|
|
46
46
|
|
|
47
|
-
Dois endpoints sob `<baseUrl>/
|
|
47
|
+
Dois endpoints sob `<baseUrl>/v1/manager`, ambos com `Authorization: Bearer <clientSecret>` (a credencial única do projeto):
|
|
48
48
|
|
|
49
|
-
### `POST /
|
|
49
|
+
### `POST /v1/manager/poll`
|
|
50
50
|
|
|
51
51
|
Corpo `ManagerPollRequest`:
|
|
52
52
|
|
|
@@ -70,7 +70,7 @@ O `agent.instance_id` é a **mesma identidade** do heartbeat do Monitor (`instan
|
|
|
70
70
|
|
|
71
71
|
**Backoff:** um request por poll; o loop decide o ritmo. HTTP 401 (key rejeitada) → retry lento a 30s com log throttled; outros erros → ladder `[1s, 4s, 16s]`.
|
|
72
72
|
|
|
73
|
-
### `PATCH /
|
|
73
|
+
### `PATCH /v1/manager/runs/{id}`
|
|
74
74
|
|
|
75
75
|
Corpo `ManagerRunUpdateRequest`:
|
|
76
76
|
|
|
@@ -91,7 +91,7 @@ Ciclo de vida completo da run no servidor: `pending → claimed → running →
|
|
|
91
91
|
|
|
92
92
|
## Onde vive o claim atômico
|
|
93
93
|
|
|
94
|
-
O `POST /
|
|
94
|
+
O `POST /v1/manager/poll` no app chama `claimPendingRuns()` em
|
|
95
95
|
[`apps/webapp/lib/manager/claim.ts`](../../../apps/webapp/lib/manager/claim.ts): um CTE que seleciona runs `pending` vencidas com `FOR UPDATE SKIP LOCKED` e as promove a `claimed` num único `UPDATE ... RETURNING`. Isso garante que dois agentes concorrentes nunca peguem a mesma run. **Nada disso está no SDK** — ele só faz o HTTP.
|
|
96
96
|
|
|
97
97
|
## Identidade do SDK
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hobots",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "SDK JavaScript da Hobots — captura de erros, transactions, check-ins de cron e heartbeats (Monitor) e execução remota de tarefas sob demanda (Manager) para RPAs e integrações. Um único import e um único init().",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|