hobots 1.9.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.ts","../src/stacktrace.ts","../src/scrub.ts","../src/utils.ts","../src/eventbuilder.ts","../src/transport.ts","../src/client.ts","../src/heartbeat.ts","../src/internal-handlers.ts","../src/instrument.ts","../src/scope.ts","../src/transaction.ts","../src/tasks/api.ts","../src/tasks/attachments.ts","../src/tasks/context.ts","../src/tasks/run-context-store.ts","../src/tasks/shutdown.ts","../src/tasks/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 agente (enviado como Authorization: Bearer, nunca na URL) */\n key: string;\n baseUrl: string;\n /** Ingestão de telemetria: <baseUrl>/v1/ingest */\n ingestEndpoint: string;\n /** API de tasks (execução sob demanda): <baseUrl>/v1/tasks */\n tasksBaseUrl: string;\n}\n\ninterface ConfigInput {\n clientSecret: string;\n}\n\n/** hb_<64 hex>. */\nconst SECRET_PATTERN = /^hb_[a-f0-9]{64}$/i;\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\nfunction isLoopbackHost(hostname: string): boolean {\n return (\n hostname === 'localhost' ||\n hostname.endsWith('.localhost') ||\n hostname.startsWith('127.') ||\n hostname === '[::1]' ||\n hostname === '::1' ||\n hostname === '0.0.0.0'\n );\n}\n\n// warning de http remoto sai uma vez por processo\nlet warnedInsecureBaseUrl = false;\n\n/**\n * Valida a baseUrl sem nunca ecoar o valor completo em erro/log — a env pode\n * conter credenciais embutidas por engano.\n */\nfunction validateBaseUrl(raw: string, prefix: string): string {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new Error(`${prefix} HOBOTS_API_URL inválida — esperado URL http(s), ex.: http://localhost:3001`);\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error(`${prefix} HOBOTS_API_URL com esquema \"${url.protocol}\" não suportado — use http(s)`);\n }\n if (url.username || url.password) {\n throw new Error(`${prefix} HOBOTS_API_URL não pode conter credenciais na URL — a autenticação é só pelo Client Secret`);\n }\n if (url.protocol === 'http:' && !isLoopbackHost(url.hostname) && !warnedInsecureBaseUrl) {\n warnedInsecureBaseUrl = true;\n console.warn(\n `${prefix} HOBOTS_API_URL usa http para o host remoto \"${url.hostname}\" — o Client Secret trafega sem TLS`\n );\n }\n return raw.replace(/\\/+$/, '');\n}\n\n/** Resolve o clientSecret nos endpoints de telemetria e de tasks. */\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 agente em Configurações → Agentes`);\n }\n if (!SECRET_PATTERN.test(key)) {\n // nunca incluir o valor na mensagem — só o tamanho, como pista de diagnóstico\n throw new Error(\n `${prefix} clientSecret com formato inválido (${key.length} caracteres) — esperado \"hb_\" + 64 hex; copie o Client Secret do agente em Configurações → Agentes`\n );\n }\n\n const baseUrl = validateBaseUrl(envBaseUrl() ?? DEFAULT_BASE_URL, prefix);\n\n return {\n key,\n baseUrl,\n ingestEndpoint: `${baseUrl}/v1/ingest`,\n tasksBaseUrl: `${baseUrl}/v1/tasks`,\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","/**\n * Redação de segredos em texto que sai do processo (mensagens de erro, stacks,\n * logs de run). Padrões conservadores — falso positivo é preferível a vazar\n * uma credencial para o painel.\n */\nconst SECRET_PATTERNS: ReadonlyArray<readonly [RegExp, string]> = [\n // client secret da Hobots\n [/hb_[a-f0-9]{16,}/gi, '[REDACTED]'],\n // tokens bearer em headers/mensagens\n [/\\b(authorization:?\\s*)?bearer\\s+[a-z0-9._~+/=-]{8,}/gi, 'Bearer [REDACTED]'],\n // chaves no formato sk-… (OpenAI e afins)\n [/\\bsk-[a-z0-9_-]{16,}\\b/gi, '[REDACTED]'],\n // credenciais embutidas em URL (https://user:pass@host)\n [/\\/\\/[^/\\s:@]+:[^/\\s@]+@/g, '//[REDACTED]@'],\n];\n\nexport function scrubSecrets(text: string): string {\n let out = text;\n for (const [pattern, replacement] of SECRET_PATTERNS) {\n out = out.replace(pattern, replacement);\n }\n return out;\n}\n","/** Injetada pelo `define` do tsup a partir da versão do package.json. */\ndeclare const __SDK_VERSION__: string | undefined;\n\nexport const SDK_NAME = 'hobots';\nexport const SDK_VERSION = typeof __SDK_VERSION__ === 'string' ? __SDK_VERSION__ : '0.0.0-dev';\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 if (cryptoRef && typeof cryptoRef.getRandomValues === 'function') {\n const bytes = cryptoRef.getRandomValues(new Uint8Array(16));\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n }\n // último recurso (runtimes sem crypto algum) — ids aqui são só de correlação\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\n/** Equal jitter: metade fixa + metade aleatória, evita thundering herd nos retries. */\nexport function jitter(baseMs: number): number {\n return Math.floor(baseMs / 2 + Math.random() * (baseMs / 2));\n}\n\nexport function truncate(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max)}… [truncado]` : value;\n}\n\nexport const DEFAULT_RETRY_DELAYS_MS: readonly number[] = [1_000, 4_000, 16_000];\n\n/**\n * Executa `send` com retry em falha de rede/5xx/429 (respeitando Retry-After + jitter).\n * Devolve a Response tanto em ok quanto em 4xx≠429 — a rejeição definitiva é decisão\n * do chamador (o transport descarta logando; a API de tasks lança erro tipado).\n * Lança o último erro quando o ladder de retries esgota.\n */\nexport async function fetchWithRetry(\n send: () => Promise<Response>,\n options: { delays?: readonly number[]; logger: Logger; label: string }\n): Promise<Response> {\n const delays = options.delays ?? DEFAULT_RETRY_DELAYS_MS;\n for (let attempt = 0; ; attempt++) {\n let retriable: unknown;\n let serverDelay: number | undefined;\n try {\n const response = await send();\n if (response.ok) return response;\n if (response.status >= 400 && response.status < 500 && response.status !== 429) return response;\n if (response.status === 429) serverDelay = retryAfterMs(response);\n retriable = new Error(`HTTP ${response.status}`);\n } catch (error) {\n retriable = error;\n }\n const base = delays[attempt];\n if (base === undefined) {\n throw retriable instanceof Error ? retriable : new Error(String(retriable));\n }\n const delay = serverDelay ?? jitter(base);\n options.logger.warn(`${options.label}: falha (${String(retriable)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n}\n\nconst MAX_RETRY_AFTER_MS = 60_000;\n\n/** Parse do header Retry-After (segundos ou HTTP-date), clampado a [0, 60s]. */\nexport function retryAfterMs(response: Response): number | undefined {\n const header = response.headers.get('retry-after');\n if (!header) return undefined;\n const seconds = Number(header);\n if (Number.isFinite(seconds)) {\n return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, seconds * 1_000));\n }\n const date = Date.parse(header);\n if (Number.isNaN(date)) return undefined;\n return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, date - Date.now()));\n}\n\n/**\n * Signal com timeout composável com um signal externo (stop/cancelamento).\n * Node 18 não tem AbortSignal.any — composição manual; chame cleanup() em finally\n * para não acumular listeners num signal externo reutilizado.\n */\nexport function withTimeoutSignal(timeoutMs: number, external?: AbortSignal): { signal: AbortSignal; cleanup: () => void } {\n const controller = new AbortController();\n const onAbort = (): void => controller.abort(external?.reason);\n if (external?.aborted) {\n onAbort();\n } else {\n external?.addEventListener('abort', onAbort, { once: true });\n }\n const timer = setTimeout(() => {\n controller.abort(Object.assign(new Error(`timeout após ${timeoutMs}ms`), { name: 'TimeoutError' }));\n }, timeoutMs);\n unrefTimer(timer);\n return {\n signal: controller.signal,\n cleanup: () => {\n clearTimeout(timer);\n external?.removeEventListener('abort', onAbort);\n },\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]';\n\nexport function makeLogger(enabled: boolean, prefix: string = PREFIX): Logger {\n return {\n debug: (...args) => enabled && console.debug(colorize(prefix, 'gray'), ...args),\n warn: (...args) => enabled && console.warn(colorize(prefix, 'yellow'), ...args),\n error: (...args) => console.error(colorize(prefix, 'red'), ...args),\n };\n}\n\nconst ANSI = {\n reset: '\\x1b[0m',\n gray: '\\x1b[90m',\n cyan: '\\x1b[36m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n} as const;\n\nfunction colorEnabled(): boolean {\n if (!isNode()) return false;\n return Boolean(process.stdout?.isTTY) && !process.env.NO_COLOR;\n}\n\n/** Envolve `text` em código ANSI — vira no-op fora de um TTY Node (ou com NO_COLOR definido). */\nexport function colorize(text: string, color: keyof typeof ANSI): string {\n if (!colorEnabled()) return text;\n return `${ANSI[color]}${text}${ANSI.reset}`;\n}\n","import type { EventPayload, Severity } from './protocol';\nimport { parseStacktrace } from './stacktrace';\nimport { scrubSecrets } from './scrub';\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 = scrubSecrets(error.message);\n frames = parseStacktrace(error.stack);\n } else {\n type = 'NonError';\n value = scrubSecrets(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: scrubSecrets(message),\n };\n}\n","import type { Envelope, EnvelopeItem } from './protocol';\nimport { SDK_NAME, SDK_VERSION, fetchWithRetry, nowISO, sleep, unrefTimer, type Logger } from './utils';\n\nconst REQUEST_TIMEOUT_MS = 10_000;\nconst DEFAULT_FLUSH_INTERVAL_MS = 2_000;\nconst DEFAULT_MAX_BATCH_SIZE = 10;\nconst DEFAULT_MAX_QUEUE_SIZE = 200;\n/**\n * Teto de itens por envelope — espelha o `.max(50)` de `envelopeSchema.items`\n * (apps/api/lib/ingest/schemas.ts). Acima disso a API responde 422 e o envelope é\n * descartado sem retry, então a fila é fatiada em envelopes deste tamanho antes de enviar.\n * Ao mudar um dos dois lados, mude o outro.\n */\nconst MAX_ITEMS_PER_ENVELOPE = 50;\n\nexport interface TransportOptions {\n endpoint: string;\n /** Chave secreta do agente — 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 // maxBatchSize decide *quando* flushar, não quanto cabe num envelope: um burst de\n // captures (ou uma janela de rede ruim em que a fila cresceu até maxQueueSize) junta\n // mais itens do que a API aceita, então quebra em lotes de MAX_ITEMS_PER_ENVELOPE.\n const taken = this.buffer.splice(0, this.buffer.length);\n const sends: Promise<void>[] = [];\n for (let offset = 0; offset < taken.length; offset += MAX_ITEMS_PER_ENVELOPE) {\n sends.push(this.send(taken.slice(offset, offset + MAX_ITEMS_PER_ENVELOPE)));\n }\n return Promise.all(sends).then(() => undefined);\n }\n\n /** Registra o envio em `this.pending` para que `flush()` aguarde todos os envelopes. */\n private send(items: EnvelopeItem[]): Promise<void> {\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 let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(this.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${this.key}` },\n body: JSON.stringify(envelope),\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n }),\n { logger: this.logger, label: 'envio de envelope' }\n );\n } catch (error) {\n this.logger.error('envelope descartado após retries:', error);\n return;\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 this.logger.error(`envelope rejeitado (HTTP ${response.status}), descartado (${envelope.items.length} itens)`);\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 { 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 { SDK_NAME, SDK_VERSION, 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 logger: Logger;\n // campos privados + getters de protótipo: o clientSecret não aparece em\n // JSON.stringify/serialização enumerável do Client (ex.: um objeto capturado\n // que referencie o client), mas client.options/config seguem funcionando\n readonly #options: InitOptions;\n readonly #config: ResolvedConfig;\n private readonly transport: Transport;\n\n constructor(options: InitOptions, config: ResolvedConfig = resolveConfig(options)) {\n this.#options = options;\n this.logger = makeLogger(!!options.debug);\n this.#config = config;\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 get options(): InitOptions {\n return this.#options;\n }\n\n get config(): ResolvedConfig {\n return this.#config;\n }\n\n /** Serialização explícita nunca inclui o secret. */\n toJSON(): Record<string, unknown> {\n return { sdk: SDK_NAME, version: SDK_VERSION, baseUrl: this.#config.baseUrl };\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `Client { baseUrl: '${this.#config.baseUrl}' }`;\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 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 { sleep } from './utils';\n\n/**\n * Coordenação entre os handlers de processo do SDK (instrument + tasks/shutdown):\n * marca os listeners internos para que a checagem de \"o programa tem handler próprio?\"\n * não conte os nossos, e agrega os reportes de emergência que o exit precisa aguardar.\n */\nconst INTERNAL = Symbol.for('hobots.sdk.internalListener');\n\ntype Marked = { [INTERNAL]?: true };\n\nexport function markInternal<T extends (...args: never[]) => unknown>(listener: T): T {\n (listener as Marked)[INTERNAL] = true;\n return listener;\n}\n\n/** Listeners do programa (não-SDK) para o evento — decide se o SDK preserva o exit default. */\nexport function externalListenerCount(event: string): number {\n const listeners = process.listeners(event as 'uncaughtException');\n return listeners.filter(listener => !(listener as Marked)[INTERNAL]).length;\n}\n\nconst emergencyTasks: Promise<unknown>[] = [];\n\n/** Reporte best-effort em voo (ex: run → AgentTerminated) que um exit iminente deve aguardar. */\nexport function addEmergencyTask(task: Promise<unknown>): void {\n emergencyTasks.push(task);\n}\n\nexport async function awaitEmergencyTasks(capMs: number): Promise<void> {\n if (emergencyTasks.length === 0) return;\n await Promise.race([Promise.allSettled(emergencyTasks), sleep(capMs)]);\n}\n","import type { Client } from './client';\nimport type { Scope } from './scope';\nimport { awaitEmergencyTasks, externalListenerCount, markInternal } from './internal-handlers';\nimport { isNode } from './utils';\n\nconst EMERGENCY_REPORT_CAP_MS = 3_000;\n\nlet installed = false;\n\n/** O tasks/shutdown consulta para saber se o exit de uncaughtException já tem dono. */\nexport function hasInstalledGlobalHandlers(): boolean {\n return installed;\n}\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(\n 'uncaughtException',\n markInternal((error: Error) => {\n client.captureException(error, { level: 'fatal', tags: { mechanism: 'uncaughtException' } }, getScope());\n void client.flush(2_000).then(async () => {\n // conta só handlers do programa — os do próprio SDK (este e o de tasks) não\n // impedem o exit default\n if (externalListenerCount('uncaughtException') === 0) {\n // aguarda o reporte de emergência do agente de tasks (runs → AgentTerminated), se houver\n await awaitEmergencyTasks(EMERGENCY_REPORT_CAP_MS);\n console.error(error);\n process.exit(1);\n }\n });\n })\n );\n\n process.on(\n 'unhandledRejection',\n markInternal((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\n // rede de segurança: envia o que restou na fila quando o event loop esvazia\n process.on(\n 'beforeExit',\n markInternal(() => {\n void client.flush(2_000);\n })\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 { StepData, StepStatus, TransactionPayload } from './protocol';\nimport type { RunLogLevel } from './tasks/protocol';\nimport type { Client } from './client';\nimport { colorize, nowISO, uuid4 } from './utils';\n\nfunction stepId(): string {\n return uuid4().slice(0, 16);\n}\n\n/** Recebe os eventos de lifecycle da transaction para espelhá-los nos logs da run. */\nexport type LifecycleSink = (level: RunLogLevel, message: string) => void;\n\n/** Rótulo legível de uma step a partir de op/description. */\nfunction stepLabel(op?: string, description?: string): string {\n return [op, description].filter(Boolean).join(' — ') || '(sem nome)';\n}\n\n/** Mapeia o status de finalização (step/transaction) para o nível de log da run. */\nfunction levelForStatus(status: StepStatus | string): RunLogLevel {\n switch (status) {\n case 'warning':\n return 'warning';\n case 'error':\n return 'error';\n case 'cancelled':\n return 'warning';\n default:\n return 'success';\n }\n}\n\n/** Mapeia o status de finalização para a cor ANSI usada no eco do terminal. */\nfunction colorForStatus(status: StepStatus | string): Parameters<typeof colorize>[1] {\n switch (status) {\n case 'warning':\n return 'yellow';\n case 'error':\n return 'red';\n case 'cancelled':\n return 'gray';\n default:\n return 'green';\n }\n}\n\nexport class Step {\n readonly stepId = stepId();\n readonly startTimestamp = nowISO();\n status: StepStatus = 'ok';\n endTimestamp?: string;\n data?: Record<string, unknown>;\n\n constructor(\n private readonly transaction: Transaction,\n readonly parentStepId: string,\n readonly op?: string,\n readonly description?: string\n ) {}\n\n setStatus(status: StepStatus): 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 /** Step aninhada (filha desta step). */\n startChild(op?: string, description?: string): Step {\n return this.transaction.createStep(this.stepId, op, description);\n }\n\n finish(): void {\n if (this.endTimestamp) return;\n this.endTimestamp = nowISO();\n this.transaction.emit(\n 'step',\n 'finish',\n stepLabel(this.op, this.description),\n this.startTimestamp,\n this.endTimestamp,\n this.status\n );\n }\n\n toJSON(): StepData {\n return {\n step_id: this.stepId,\n parent_step_id: this.parentStepId,\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 * Steps filhas medem as etapas internas (chamadas HTTP, queries, etc.).\n */\nexport class Transaction {\n readonly eventId = uuid4();\n readonly stepId = stepId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n private readonly steps: Step[] = [];\n private readonly tags: Record<string, string> = {};\n private finished = false;\n private lifecycleSink?: LifecycleSink;\n // eventos emitidos antes do sink existir (o START da transaction sai no construtor,\n // antes do RunReporter conectar) — replay no setLifecycleSink\n private lifecycleBacklog: Array<[RunLogLevel, string]> = [];\n\n constructor(\n private readonly client: Client | undefined,\n public name: string,\n readonly op?: string,\n private readonly sampled = true,\n /** Correlaciona a uma execução de task — preenchido automaticamente em ctx.tx */\n private readonly runId?: string\n ) {\n this.emit('transaction', 'start', op ? `${name} (${op})` : name);\n }\n\n /**\n * Ecoa no terminal o início/fim de uma step ou transaction (sempre, independente de\n * sampling ou do debug) e espelha a linha no sink de lifecycle, se conectado — é\n * assim que os eventos de performance também aparecem nos logs da run no app.\n */\n emit(\n kind: 'transaction' | 'step',\n phase: 'start' | 'finish',\n label: string,\n startTs?: string,\n endTs?: string,\n status?: StepStatus | string\n ): void {\n const durationMs = startTs && endTs ? new Date(endTs).getTime() - new Date(startTs).getTime() : undefined;\n const tag = colorize(`[hobots:${kind}] ${phase.toUpperCase()}`, phase === 'finish' ? colorForStatus(status ?? 'ok') : 'cyan');\n const suffix = durationMs != null ? ` (${durationMs}ms)` : '';\n console.log(`${tag} ${label}${suffix}`);\n\n const level: RunLogLevel = phase === 'finish' ? levelForStatus(status ?? 'ok') : 'info';\n const message = `[${kind}] ${phase.toUpperCase()} ${label}${suffix}`;\n if (this.lifecycleSink) this.lifecycleSink(level, message);\n // sem sink (transaction fora de run): backlog capado — nunca vai ser drenado\n else if (this.lifecycleBacklog.length < 100) this.lifecycleBacklog.push([level, message]);\n }\n\n /** Conecta o espelho de lifecycle (RunReporter) e faz replay do backlog em ordem. */\n setLifecycleSink(sink: LifecycleSink): void {\n this.lifecycleSink = sink;\n const backlog = this.lifecycleBacklog;\n this.lifecycleBacklog = [];\n for (const [level, message] of backlog) sink(level, message);\n }\n\n createStep(parentStepId: string, op?: string, description?: string): Step {\n const step = new Step(this, parentStepId, op, description);\n this.steps.push(step);\n this.emit('step', 'start', stepLabel(op, description));\n return step;\n }\n\n /** Step direta da transaction. */\n startChild(op?: string, description?: string): Step {\n return this.createStep(this.stepId, 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 step of this.steps) step.finish();\n\n const endTimestamp = nowISO();\n this.emit(\n 'transaction',\n 'finish',\n this.op ? `${this.name} (${this.op})` : this.name,\n this.startTimestamp,\n endTimestamp,\n this.status\n );\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: endTimestamp,\n steps: this.steps.map(step => step.toJSON()),\n tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,\n run_id: this.runId,\n };\n this.client.sendTransaction(payload);\n }\n}\n","import type {\n PollRequest,\n PollResponse,\n RunAttachmentConfirmRequest,\n RunAttachmentCreateRequest,\n RunAttachmentCreateResponse,\n RunDescriptor,\n RunUpdateRequest,\n} from './protocol';\nimport { fetchWithRetry, withTimeoutSignal, type Logger } from '../utils';\n\nconst POLL_TIMEOUT_MS = 30_000;\nconst UPDATE_TIMEOUT_MS = 10_000;\n/** O PUT carrega o binário inteiro — ladder mais curta e timeout mais folgado que os PATCHes. */\nconst UPLOAD_TIMEOUT_MS = 30_000;\nconst UPLOAD_RETRY_DELAYS_MS: readonly number[] = [1_000, 4_000];\n\nexport class TasksApiError extends Error {\n constructor(\n message: string,\n readonly status: number\n ) {\n super(message);\n this.name = 'TasksApiError';\n }\n}\n\nexport interface TasksApiOptions {\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 TasksApi {\n private readonly baseUrl: string;\n private readonly key: string;\n private readonly logger: Logger;\n\n constructor(options: TasksApiOptions) {\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: PollRequest, signal?: AbortSignal): Promise<PollResponse> {\n const { signal: timeoutSignal, cleanup } = withTimeoutSignal(POLL_TIMEOUT_MS, signal);\n let response: Response;\n try {\n response = await fetch(`${this.baseUrl}/poll`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal: timeoutSignal,\n });\n } finally {\n cleanup();\n }\n if (!response.ok) {\n throw new TasksApiError(`poll falhou (HTTP ${response.status})`, response.status);\n }\n return this.parsePollResponse(await response.json(), request.max ?? 1);\n }\n\n /** Nunca confia no shape da resposta: runs malformadas são descartadas e o `max` é respeitado. */\n private parsePollResponse(body: unknown, max: number): PollResponse {\n const runs = (body as { runs?: unknown } | null)?.runs;\n if (!Array.isArray(runs)) {\n throw new TasksApiError('resposta inválida do poll (campo runs ausente)', 0);\n }\n const valid: RunDescriptor[] = [];\n for (const run of runs.slice(0, Math.max(0, max)) as Array<Record<string, unknown> | null>) {\n if (typeof run?.id !== 'string' || typeof run.task !== 'string') continue;\n const params = run.params && typeof run.params === 'object' && !Array.isArray(run.params) ? run.params : {};\n valid.push({ ...run, id: run.id, task: run.task, params } as RunDescriptor);\n }\n if (valid.length < runs.length) {\n this.logger.warn(`poll retornou ${runs.length - valid.length} run(s) inválida(s)/excedente(s) — descartadas`);\n }\n return { runs: valid };\n }\n\n /**\n * PATCH de status/logs com retry em falha de rede/5xx/429.\n * 4xx é definitivo e vira TasksApiError imediato (409 = run cancelada/transição inválida).\n */\n async updateRun(runId: string, update: RunUpdateRequest): Promise<void> {\n let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}`, {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(update),\n signal: AbortSignal.timeout(UPDATE_TIMEOUT_MS),\n }),\n { logger: this.logger, label: `update da run ${runId}` }\n );\n } catch (error) {\n throw new Error(`update da run ${runId} descartado após retries: ${String(error)}`);\n }\n if (!response.ok) {\n // 4xx definitivo (409 = run cancelada/transição inválida) — o RunReporter trata por status\n throw new TasksApiError(`update rejeitado (HTTP ${response.status})`, response.status);\n }\n }\n\n /**\n * Um único PATCH com timeout curto — exit path (o processo está morrendo, o retry\n * ladder do updateRun é proibido aqui). Status HTTP é ignorado: 409/404 significa\n * que a run já foi cancelada/finalizada, o que é aceitável nesse caminho.\n */\n async updateRunOnce(runId: string, update: RunUpdateRequest, timeoutMs = 2_000): Promise<void> {\n await fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}`, {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(update),\n signal: AbortSignal.timeout(timeoutMs),\n });\n }\n\n /**\n * Registra o anexo e obtém a URL presignada de upload. 404/501/503 significam\n * \"esta instalação não tem anexos\" — o RunReporter degrada em silêncio a partir daí.\n */\n async createAttachment(\n runId: string,\n request: RunAttachmentCreateRequest,\n signal?: AbortSignal\n ): Promise<RunAttachmentCreateResponse> {\n const { signal: timeoutSignal, cleanup } = withTimeoutSignal(UPDATE_TIMEOUT_MS, signal);\n let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}/attachments`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal: timeoutSignal,\n }),\n { logger: this.logger, label: `anexo da run ${runId}` }\n );\n } finally {\n cleanup();\n }\n if (!response.ok) {\n throw new TasksApiError(`criação de anexo rejeitada (HTTP ${response.status})`, response.status);\n }\n const body = (await response.json()) as Partial<RunAttachmentCreateResponse> | null;\n if (typeof body?.upload_url !== 'string') {\n throw new TasksApiError('resposta inválida do anexo (upload_url ausente)', 0);\n }\n return {\n id: body.id ?? request.id,\n upload_url: body.upload_url,\n headers: body.headers ?? { 'content-type': request.content_type },\n expires_in: body.expires_in ?? 900,\n };\n }\n\n /**\n * PUT do binário direto no S3. Deliberadamente sem `authorization`: a autorização\n * está na assinatura da URL, e mandar o client secret para fora da API seria vazamento.\n */\n async uploadAttachment(\n url: string,\n headers: Record<string, string>,\n body: Uint8Array,\n signal?: AbortSignal\n ): Promise<void> {\n const { signal: timeoutSignal, cleanup } = withTimeoutSignal(UPLOAD_TIMEOUT_MS, signal);\n let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(url, {\n method: 'PUT',\n headers,\n // BodyInit não aceita Uint8Array<ArrayBufferLike> em todos os lib.dom; o buffer é o mesmo\n body: body as BodyInit,\n signal: timeoutSignal,\n }),\n { delays: UPLOAD_RETRY_DELAYS_MS, logger: this.logger, label: 'upload de anexo' }\n );\n } finally {\n cleanup();\n }\n if (!response.ok) {\n throw new TasksApiError(`upload de anexo rejeitado (HTTP ${response.status})`, response.status);\n }\n }\n\n /** Marca o anexo como enviado (ou falho). Best-effort — a leitura não depende disso. */\n async confirmAttachment(\n runId: string,\n attachmentId: string,\n request: RunAttachmentConfirmRequest\n ): Promise<void> {\n const response = await fetch(\n `${this.baseUrl}/runs/${encodeURIComponent(runId)}/attachments/${encodeURIComponent(attachmentId)}`,\n {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal: AbortSignal.timeout(UPDATE_TIMEOUT_MS),\n }\n );\n if (!response.ok) {\n throw new TasksApiError(`confirmação de anexo rejeitada (HTTP ${response.status})`, response.status);\n }\n }\n}\n","import type { RunAttachmentContentType, RunLogLevel } from './protocol';\nimport { isNode } from '../utils';\n\n/** Tamanho máximo de um anexo. O servidor aplica o mesmo teto. */\nexport const MAX_ATTACHMENT_BYTES = 5_242_880; // 5 MB\n/** Teto de anexos por execução. O servidor aplica o mesmo teto (429). */\nexport const MAX_ATTACHMENTS_PER_RUN = 20;\n/** Uploads simultâneos por run — o resto fica na fila. */\nexport const MAX_CONCURRENT_UPLOADS = 3;\nexport const MAX_CAPTION_CHARS = 200;\n/** Tempo máximo que a run espera pelos uploads pendentes antes do PATCH terminal. */\nexport const ATTACHMENT_DRAIN_MS = 15_000;\n\nexport interface AttachOptions {\n /** Legenda curta, exibida sob a miniatura no app. Passa pelo scrub de segredos. */\n caption?: string;\n /** Nível da linha de log que carrega o anexo. Default: 'info' */\n level?: RunLogLevel;\n /** Texto da linha de log. Default: a legenda, ou 'captura de tela' */\n message?: string;\n /** Informe quando os magic bytes não bastarem (o SDK sempre prefere o que detectar). */\n contentType?: RunAttachmentContentType;\n}\n\nexport type AttachFailureReason =\n /** A instalação do Hobots não tem anexos habilitados (ou a API é anterior ao recurso) */\n | 'unsupported'\n | 'too-large'\n | 'quota'\n | 'read-failed'\n /** Formato não reconhecido ou fora de PNG/JPEG/WEBP */\n | 'unsupported-format'\n | 'upload-failed'\n | 'canceled';\n\nexport interface AttachResult {\n /** Id do anexo, o mesmo referenciado na linha de log */\n id: string;\n ok: boolean;\n /** Motivo do insucesso — para diagnóstico; `attach` nunca lança */\n reason?: AttachFailureReason;\n}\n\n/** Aceita tudo que o handler pode ter em mãos: bytes ou um caminho de arquivo (só Node). */\nexport type AttachInput = Uint8Array | ArrayBuffer | string;\n\n/**\n * Lê um arquivo de imagem do disco. Import dinâmico de `node:fs/promises` — nada de\n * import estático de builtin do Node, que quebraria o bundle neutro/browser.\n */\nexport async function readImageFile(path: string): Promise<Uint8Array> {\n if (!isNode()) {\n throw new Error('caminho de arquivo só é suportado em Node');\n }\n const { readFile } = await import('node:fs/promises');\n return new Uint8Array(await readFile(path));\n}\n\nfunction startsWith(bytes: Uint8Array, signature: readonly number[], offset = 0): boolean {\n if (bytes.length < offset + signature.length) return false;\n return signature.every((byte, index) => bytes[offset + index] === byte);\n}\n\nconst PNG_MAGIC = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] as const;\nconst JPEG_MAGIC = [0xff, 0xd8, 0xff] as const;\nconst RIFF_MAGIC = [0x52, 0x49, 0x46, 0x46] as const; // \"RIFF\"\nconst WEBP_MAGIC = [0x57, 0x45, 0x42, 0x50] as const; // \"WEBP\" no offset 8\n\n/** Detecta o formato pelos magic bytes. `undefined` quando não é PNG/JPEG/WEBP. */\nexport function sniffContentType(bytes: Uint8Array): RunAttachmentContentType | undefined {\n if (startsWith(bytes, PNG_MAGIC)) return 'image/png';\n if (startsWith(bytes, JPEG_MAGIC)) return 'image/jpeg';\n if (startsWith(bytes, RIFF_MAGIC) && startsWith(bytes, WEBP_MAGIC, 8)) return 'image/webp';\n return undefined;\n}\n\n/**\n * Dimensões pelo chunk IHDR de um PNG (bytes 16..23). Só PNG: é o formato de print\n * mais comum e o único que dá pra ler sem parser. Sem dimensões o app apenas não\n * reserva o espaço da miniatura antes do carregamento.\n */\nexport function readPngDimensions(bytes: Uint8Array): { width: number; height: number } | undefined {\n if (!startsWith(bytes, PNG_MAGIC) || bytes.length < 24) return undefined;\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const width = view.getUint32(16);\n const height = view.getUint32(20);\n if (width === 0 || height === 0) return undefined;\n return { width, height };\n}\n\n/** Normaliza a entrada do handler para bytes, lendo do disco quando for um caminho. */\nexport async function toBytes(input: AttachInput): Promise<Uint8Array> {\n if (typeof input === 'string') return readImageFile(input);\n if (input instanceof Uint8Array) return input;\n return new Uint8Array(input);\n}\n","import type { RunAttachmentContentType, RunError, RunUpdateRequest, RunLogEntry, RunLogLevel } from './protocol';\nimport type { RunContext, RunLogger } from './types';\nimport { TasksApi, TasksApiError } from './api';\nimport {\n ATTACHMENT_DRAIN_MS,\n MAX_ATTACHMENTS_PER_RUN,\n MAX_ATTACHMENT_BYTES,\n MAX_CAPTION_CHARS,\n MAX_CONCURRENT_UPLOADS,\n readPngDimensions,\n sniffContentType,\n toBytes,\n type AttachFailureReason,\n type AttachInput,\n type AttachOptions,\n type AttachResult,\n} from './attachments';\nimport { colorize, nowISO, truncate, unrefTimer, uuid4, type Logger } from '../utils';\nimport { scrubSecrets } from '../scrub';\nimport type { Transaction } from '../transaction';\n\nconst LOG_LEVEL_COLOR = {\n debug: 'gray',\n info: 'cyan',\n warning: 'yellow',\n error: 'red',\n success: 'green',\n} as const;\n\n/** Ecoa o log da run no terminal local, colorido por nível — o buffer/envio ao servidor é independente disso. */\nfunction printRunLog(task: string, level: RunLogLevel, message: string): void {\n const line = colorize(`[hobots:${task}] ${level.toUpperCase()}`, LOG_LEVEL_COLOR[level]);\n const method = level === 'warning' ? 'warn' : level === 'success' ? 'info' : level;\n console[method](line, message);\n}\n\nfunction runCanceledError(): Error {\n return Object.assign(new Error('execução cancelada'), { name: 'RunCanceled' });\n}\n\n/**\n * Sleep que respeita o ctx.signal — rejeita com RunCanceled no abort.\n * O timer NÃO é unref'd de propósito: uma run em execução é trabalho legítimo e\n * deve segurar o processo vivo mesmo com o polling já parado (shutdown gracioso).\n */\nfunction cancelableSleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal.aborted) {\n reject(runCanceledError());\n return;\n }\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(runCanceledError());\n };\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nconst DEFAULT_LOG_FLUSH_INTERVAL_MS = 2_000;\nconst DEFAULT_CANCEL_CHECK_INTERVAL_MS = 5_000;\nconst MIN_CANCEL_CHECK_INTERVAL_MS = 1_000;\n// teto: o PATCH periódico é o sinal de vida da run — o servidor marca como\n// encerrada inesperadamente após ~120s sem reporte, então o intervalo não pode chegar perto disso\nconst MAX_CANCEL_CHECK_INTERVAL_MS = 15_000;\nconst MAX_LOG_MESSAGE_CHARS = 10_000;\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/finalizada no servidor): o handler não\n * pode ser morto, mas status posterior é suprimido e ctx.signal dispara para abort\n * cooperativo. Logs nunca são descartados em silêncio: falha de rede devolve ao\n * buffer, e depois da morte eles seguem best-effort como \"log tardio\" (o servidor\n * anexa logs a runs terminais mesmo respondendo 409).\n */\nexport class RunReporter {\n readonly context: RunContext;\n\n private buffer: RunLogEntry[] = [];\n private dead = false;\n private chain: Promise<void> = Promise.resolve();\n private pendingUpdates = 0;\n private timer: ReturnType<typeof setTimeout> | undefined;\n private watchTimer: ReturnType<typeof setInterval> | undefined;\n private readonly abortController = new AbortController();\n private readonly flushIntervalMs: number;\n private readonly cancelCheckIntervalMs: number;\n\n // Uploads de anexo vivem FORA de `this.chain`: a cadeia é um FIFO puro de\n // status/logs e não pode ficar bloqueada esperando um binário subir.\n private readonly pendingAttachments = new Set<Promise<void>>();\n private attachmentCount = 0;\n private uploadSlots = MAX_CONCURRENT_UPLOADS;\n private uploadQueue: Array<() => void> = [];\n /** Uma vez que a instalação recusa anexos, para de tentar (e de avisar) nesta run. */\n private attachmentsUnsupported = false;\n\n constructor(\n private readonly api: TasksApi,\n private readonly runId: string,\n task: string,\n private readonly logger: Logger,\n tx: Transaction,\n flushIntervalMs?: number,\n cancelCheckIntervalMs?: number\n ) {\n this.flushIntervalMs = flushIntervalMs ?? DEFAULT_LOG_FLUSH_INTERVAL_MS;\n this.cancelCheckIntervalMs = Math.min(\n MAX_CANCEL_CHECK_INTERVAL_MS,\n Math.max(MIN_CANCEL_CHECK_INTERVAL_MS, cancelCheckIntervalMs ?? DEFAULT_CANCEL_CHECK_INTERVAL_MS)\n );\n const log: RunLogger = {\n debug: message => this.log('debug', message),\n info: message => this.log('info', message),\n warn: message => this.log('warning', message),\n error: message => this.log('error', message),\n success: message => this.log('success', message),\n };\n // eventos de transaction/step da run espelham nos logs (o terminal já foi\n // ecoado pelo próprio emit da Transaction — aqui é só buffer/envio)\n tx.setLifecycleSink((level, message) => this.push(level, message));\n const signal = this.abortController.signal;\n this.context = {\n runId,\n task,\n log,\n tx,\n signal,\n throwIfCanceled: () => {\n if (signal.aborted) throw runCanceledError();\n },\n sleep: ms => cancelableSleep(ms, 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 this.stopCancelWatch(); // o heartbeat só existe para disparar o signal\n if (!this.abortController.signal.aborted) this.abortController.abort();\n }\n\n /**\n * Mata o reporter de vez: aborta o signal e suprime todo reporte futuro.\n * Usado no exit path — depois que o agente reportou AgentTerminated por fora\n * da fila, um handler zumbi não pode reenviar status por cima.\n */\n kill(): void {\n this.abort();\n this.dead = true;\n this.clearFlushTimer();\n this.buffer = [];\n // uploads na fila nunca vão rodar: solta quem espera slot para não vazar promises\n const waiting = this.uploadQueue.splice(0, this.uploadQueue.length);\n for (const resume of waiting) resume();\n }\n\n /**\n * Drena o buffer pendente para o PATCH único do exit path (chame ANTES de kill,\n * que descarta o buffer). Capado em um chunk — o exit path não tem retry nem fila,\n * então preserva os logs mais recentes, os mais valiosos na morte do processo.\n */\n drainLogs(): RunLogEntry[] {\n this.clearFlushTimer();\n return this.takeLogs().slice(-MAX_LOGS_PER_PATCH);\n }\n\n private log(level: RunLogLevel, message: string): void {\n if (this.dead) return;\n const scrubbed = scrubSecrets(message);\n printRunLog(this.context.task, level, scrubbed);\n this.push(level, scrubbed, true);\n }\n\n /** Bufferiza uma entrada de log sem eco no terminal (cap, truncate, flush). */\n private push(level: RunLogLevel, message: string, alreadyScrubbed = false, attachments?: string[]): string {\n const ts = nowISO();\n if (this.dead) return ts;\n const scrubbed = alreadyScrubbed ? message : scrubSecrets(message);\n this.buffer.push({\n ts,\n level,\n message: truncate(scrubbed, MAX_LOG_MESSAGE_CHARS),\n ...(attachments && attachments.length > 0 ? { attachments } : {}),\n });\n\n if (this.buffer.length >= FLUSH_AT_BUFFERED) {\n this.flushLogs();\n } else {\n this.scheduleFlush();\n }\n return ts;\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 return this.buffer.splice(0, this.buffer.length);\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 if (!this.dead) this.startCancelWatch();\n return !this.dead;\n }\n\n reportSuccess(): void {\n this.stopCancelWatch();\n this.clearFlushTimer();\n this.enqueue({ status: 'succeeded', logs: this.takeLogs() });\n }\n\n reportFailure(error: RunError): void {\n this.stopCancelWatch();\n this.clearFlushTimer();\n this.enqueue({ status: 'failed', error, logs: this.takeLogs() });\n }\n\n /**\n * Heartbeat de cancelamento: enquanto o handler roda, um PATCH 'running' vazio\n * periódico faz o servidor responder 409 se a run foi cancelada no app — o que\n * mata o reporter e dispara ctx.signal, mesmo em handlers que nunca logam.\n */\n private startCancelWatch(): void {\n if (this.watchTimer) return;\n this.watchTimer = setInterval(() => {\n // já há tráfego a caminho (logs/updates) — ele mesmo detecta o cancelamento\n if (this.dead || this.pendingUpdates > 0 || this.buffer.length > 0) return;\n this.enqueue({ status: 'running' });\n }, this.cancelCheckIntervalMs);\n unrefTimer(this.watchTimer);\n }\n\n private stopCancelWatch(): void {\n if (this.watchTimer) {\n clearInterval(this.watchTimer);\n this.watchTimer = undefined;\n }\n }\n\n /** Aguarda a fila de PATCHes esvaziar (chame depois do terminal). */\n finalize(): Promise<void> {\n return this.chain;\n }\n\n // ── Anexos ───────────────────────────────────────────────────────────────────\n\n /**\n * Registra a linha de log com o id do anexo (síncrono, na ordem certa) e dispara\n * o upload em segundo plano. Nunca lança: todo caminho de erro vira `{ ok: false }`\n * com um aviso no log da run. Chega ao handler pelos capture* do SDK — o hint\n * `attachment` de Hobots.captureException/captureMessage cai aqui via run-context-store.\n */\n async attach(image: AttachInput, options: AttachOptions = {}): Promise<AttachResult> {\n const id = uuid4();\n const level = options.level ?? 'info';\n const caption = options.caption ? truncate(scrubSecrets(options.caption), MAX_CAPTION_CHARS) : undefined;\n const message = options.message ?? options.caption ?? 'captura de tela';\n\n if (this.dead) return { id, ok: false, reason: 'canceled' };\n if (this.attachmentsUnsupported) {\n // já avisamos uma vez nesta run — registra só a linha de log, sem anexo\n this.log(level, message);\n return { id, ok: false, reason: 'unsupported' };\n }\n if (this.attachmentCount >= MAX_ATTACHMENTS_PER_RUN) {\n this.log(level, message);\n this.log('warning', `anexo descartado: limite de ${MAX_ATTACHMENTS_PER_RUN} por execução atingido`);\n return { id, ok: false, reason: 'quota' };\n }\n this.attachmentCount++;\n\n // A linha de log entra ANTES de qualquer I/O — é isso que mantém a ordem dos\n // logs intacta e o handler livre da latência do upload.\n const scrubbed = scrubSecrets(message);\n printRunLog(this.context.task, level, `${scrubbed} [imagem]`);\n const logTs = this.push(level, scrubbed, true, [id]);\n\n let settle!: (result: AttachResult) => void;\n const result = new Promise<AttachResult>(resolve => {\n settle = resolve;\n });\n const work = this.uploadAttachment(id, image, { caption, logTs, contentType: options.contentType })\n .then(reason => settle(reason ? { id, ok: false, reason } : { id, ok: true }))\n .catch(() => settle({ id, ok: false, reason: 'upload-failed' }));\n this.pendingAttachments.add(work);\n void work.finally(() => this.pendingAttachments.delete(work));\n\n return result;\n }\n\n /** Retorna o motivo da falha, ou undefined em sucesso. */\n private async uploadAttachment(\n id: string,\n image: AttachInput,\n meta: { caption?: string; logTs: string; contentType?: RunAttachmentContentType }\n ): Promise<AttachFailureReason | undefined> {\n let bytes: Uint8Array;\n try {\n bytes = await toBytes(image);\n } catch (error) {\n this.log('warning', `anexo não pôde ser lido: ${String(error)}`);\n return 'read-failed';\n }\n\n // magic bytes ganham do que o chamador declarou — o S3 rejeita a assinatura se divergir\n const contentType = sniffContentType(bytes) ?? meta.contentType;\n if (!contentType) {\n this.log('warning', 'anexo descartado: formato não reconhecido (aceitos: PNG, JPEG, WEBP)');\n return 'unsupported-format';\n }\n if (bytes.byteLength > MAX_ATTACHMENT_BYTES) {\n this.log(\n 'warning',\n `anexo descartado: ${Math.round(bytes.byteLength / 1024)} KB excede o limite de ${MAX_ATTACHMENT_BYTES / 1024 / 1024} MB`\n );\n return 'too-large';\n }\n\n const dimensions = readPngDimensions(bytes);\n const release = await this.acquireUploadSlot();\n try {\n if (this.abortController.signal.aborted || this.dead) return 'canceled';\n const created = await this.api.createAttachment(\n this.runId,\n {\n id,\n content_type: contentType,\n size_bytes: bytes.byteLength,\n log_ts: meta.logTs,\n ...(meta.caption ? { caption: meta.caption } : {}),\n ...(dimensions ?? {}),\n },\n this.abortController.signal\n );\n await this.api.uploadAttachment(created.upload_url, created.headers, bytes, this.abortController.signal);\n // confirmação é conforto de UX (some o placeholder \"enviando…\"): falha não invalida o upload\n await this.api\n .confirmAttachment(this.runId, id, { status: 'uploaded', size_bytes: bytes.byteLength, ...(dimensions ?? {}) })\n .catch(() => {});\n return undefined;\n } catch (error) {\n if (this.isUnsupported(error)) {\n this.attachmentsUnsupported = true;\n this.log('warning', 'anexos não estão habilitados nesta instalação do Hobots — imagem não enviada');\n return 'unsupported';\n }\n if (error instanceof TasksApiError && error.status === 429) {\n this.log('warning', 'anexo descartado: limite de anexos por execução atingido no servidor');\n return 'quota';\n }\n if (this.abortController.signal.aborted) return 'canceled';\n this.log('warning', `falha ao enviar o anexo: ${String(error)}`);\n void this.api.confirmAttachment(this.runId, id, { status: 'failed' }).catch(() => {});\n return 'upload-failed';\n } finally {\n release();\n }\n }\n\n /** 404 = API anterior ao recurso; 501/503 = instalação sem S3 configurado. */\n private isUnsupported(error: unknown): boolean {\n return error instanceof TasksApiError && (error.status === 404 || error.status === 501 || error.status === 503);\n }\n\n /** Semáforo simples: no máximo MAX_CONCURRENT_UPLOADS binários em voo por run. */\n private acquireUploadSlot(): Promise<() => void> {\n const release = (): void => {\n const next = this.uploadQueue.shift();\n if (next) next();\n else this.uploadSlots++;\n };\n if (this.uploadSlots > 0) {\n this.uploadSlots--;\n return Promise.resolve(release);\n }\n return new Promise<() => void>(resolve => {\n this.uploadQueue.push(() => resolve(release));\n });\n }\n\n /**\n * Espera os uploads pendentes antes do PATCH terminal, para a run não terminar\n * exibindo miniaturas em \"enviando…\". Capado: um upload lento não segura a run.\n */\n async finalizeAttachments(timeoutMs = ATTACHMENT_DRAIN_MS): Promise<void> {\n if (this.pendingAttachments.size === 0) return;\n await Promise.race([\n Promise.allSettled([...this.pendingAttachments]),\n new Promise<void>(resolve => unrefTimer(setTimeout(resolve, timeoutMs))),\n ]);\n }\n\n private enqueue(update: RunUpdateRequest): void {\n if (this.dead) {\n this.salvageLogs(update.logs);\n return;\n }\n this.pendingUpdates++;\n this.chain = this.chain.then(async () => {\n if (this.dead) {\n // update enfileirado atrás do PATCH que morreu (ex.: chunks de flush): logs seguem tardios\n this.salvageLogs(update.logs);\n return;\n }\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 TasksApiError && (error.status === 409 || error.status === 404)) {\n this.dead = true;\n this.stopCancelWatch();\n this.abort();\n // os logs deste payload já foram anexados pelo servidor (append tardio no 409);\n // o que resta no buffer segue best-effort pelo mesmo caminho\n const pending = this.buffer.splice(0, this.buffer.length);\n this.salvageLogs(pending);\n this.logger.warn(\n `run ${this.runId} cancelada/finalizada no servidor — status suprimido` +\n (pending.length > 0 ? `, ${pending.length} log(s) enviados como log tardio` : '')\n );\n return;\n }\n // rede/5xx com retries esgotados: devolve os logs ao buffer para o próximo PATCH\n if (update.logs && update.logs.length > 0) {\n this.buffer.unshift(...update.logs);\n this.scheduleFlush();\n }\n this.logger.error(`update da run ${this.runId} perdido:`, error);\n }\n }).finally(() => {\n this.pendingUpdates--;\n });\n }\n\n /**\n * Best-effort de log tardio: envia logs para uma run já terminal, fora da fila.\n * O servidor anexa os logs mesmo respondendo 409; erros são engolidos — este é\n * o último recurso, não um canal confiável.\n */\n private salvageLogs(logs: RunLogEntry[] | undefined): void {\n if (!logs || logs.length === 0) return;\n for (let i = 0; i < logs.length; i += MAX_LOGS_PER_PATCH) {\n void this.api\n .updateRunOnce(this.runId, { status: 'running', logs: logs.slice(i, i + MAX_LOGS_PER_PATCH) })\n .catch(() => {});\n }\n }\n}\n","import type { AsyncLocalStorage } from 'node:async_hooks';\n\nimport { isNode } from '../utils';\nimport type { Transaction } from '../transaction';\nimport type { AttachInput, AttachOptions, AttachResult } from './attachments';\n\nexport type RunAttach = (image: AttachInput, options?: AttachOptions) => Promise<AttachResult>;\n\ninterface RunStore {\n runId: string;\n /** Transaction da run (ctx.tx) — a única transaction da execução. */\n tx: Transaction;\n /** Anexa uma imagem a uma linha de log da run — a ponte dos capture* até o reporter. */\n attach: RunAttach;\n}\n\n// Inicializado sob demanda só em Node (import dinâmico → não entra no bundle do browser).\n// import type acima é apagado em compilação, então não há import estático de node:async_hooks.\nlet storage: AsyncLocalStorage<RunStore> | undefined;\nlet initPromise: Promise<void> | undefined;\n\nasync function ensureStorage(): Promise<void> {\n if (storage || !isNode()) return;\n initPromise ??= import('node:async_hooks').then(({ AsyncLocalStorage: ALS }) => {\n storage = new ALS<RunStore>();\n });\n await initPromise;\n}\n\n/**\n * Executa `fn` com a run ativa no contexto async atual. Qualquer chamada a\n * Hobots.startTransaction() por dentro reutiliza a transaction da run (ctx.tx) —\n * a execução tem sempre UMA transaction, com as steps do handler no waterfall.\n */\nexport async function runWithRunContext<T>(store: RunStore, fn: () => Promise<T>): Promise<T> {\n await ensureStorage();\n return storage ? storage.run(store, fn) : fn();\n}\n\n/** Transaction da run em execução no contexto async atual, se houver. */\nexport function currentRunTransaction(): Transaction | undefined {\n return storage?.getStore()?.tx;\n}\n\n/** Pipeline de anexos da run em execução no contexto async atual, se houver. */\nexport function currentRunAttach(): RunAttach | undefined {\n return storage?.getStore()?.attach;\n}\n","import type { TaskAgent } from './agent';\nimport { hasInstalledGlobalHandlers } from '../instrument';\nimport { addEmergencyTask, externalListenerCount, markInternal } from '../internal-handlers';\nimport { isNode } from '../utils';\n\nconst WATCHED_SIGNALS = ['SIGINT', 'SIGTERM'] as const;\ntype WatchedSignal = (typeof WATCHED_SIGNALS)[number];\n\n/**\n * Rede de segurança do agente: quando o processo morre (sinal ou erro não tratado)\n * com runs em execução, tenta reportar 'failed'/AgentTerminated antes de sair —\n * assim o app mostra a falha na hora, sem esperar o sweep server-side (~60s).\n *\n * Nunca interfere no shutdown gracioso: se o programa tem handler próprio para o\n * sinal (ex: SIGINT → close()), o SDK fica quieto e deixa o caminho normal reportar.\n */\nexport function installShutdownHandlers(agent: TaskAgent): () => void {\n if (!isNode()) return () => {};\n\n let signaled = false;\n const signalHandlers = new Map<WatchedSignal, () => void>();\n\n for (const signal of WATCHED_SIGNALS) {\n const handler = markInternal(() => {\n // o programa tem handler próprio (shutdown gracioso) — o caminho normal reporta\n if (externalListenerCount(signal) > 0) return;\n if (signaled) return;\n signaled = true;\n\n const reraise = (): void => {\n process.removeListener(signal, handler);\n process.kill(process.pid, signal); // exit default do sinal (código 130/143)\n };\n if (agent.activeCount === 0) {\n reraise();\n return;\n }\n const report = agent.reportAgentTerminated(`o processo do agente recebeu ${signal} durante a execução`);\n addEmergencyTask(report);\n void report.finally(reraise);\n });\n process.on(signal, handler);\n signalHandlers.set(signal, handler);\n }\n\n const onFatal = markInternal((error: Error) => {\n const report =\n agent.activeCount > 0\n ? agent.reportAgentTerminated('o processo do agente morreu com um erro não tratado durante a execução')\n : Promise.resolve();\n addEmergencyTask(report);\n // o exit é decidido pelo instrument (captureUnhandled) ou pelo handler do programa;\n // sem nenhum dos dois, preservamos o comportamento default do Node aqui\n if (!hasInstalledGlobalHandlers() && externalListenerCount('uncaughtException') === 0) {\n void report.finally(() => {\n console.error(error);\n process.exit(1);\n });\n }\n });\n process.on('uncaughtException', onFatal);\n\n return () => {\n for (const [signal, handler] of signalHandlers) process.removeListener(signal, handler);\n process.removeListener('uncaughtException', onFatal);\n };\n}\n","import type { RunDescriptor, RunError } from './protocol';\nimport type { TaskAgentOptions, TaskHandler } from './types';\nimport { TasksApi, TasksApiError } from './api';\nimport { RunReporter } from './context';\nimport { runWithRunContext } from './run-context-store';\nimport { installShutdownHandlers } from './shutdown';\nimport { Transaction } from '../transaction';\nimport { isNode, jitter, makeLogger, sleep, truncate, SDK_VERSION, type Logger } from '../utils';\nimport { scrubSecrets } from '../scrub';\nimport type { Client } from '../client';\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;\nconst DEFAULT_CANCEL_GRACE_MS = 10_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 de tasks: busca runs pendentes, executa os handlers registrados\n * e reporta status/logs/result. Ao contrário da Telemetria, o timer de polling NÃO é\n * unref'd — um agente iniciado mantém o processo vivo até stop().\n */\nexport class TaskAgent {\n readonly logger: Logger;\n\n private readonly api: TasksApi;\n private readonly client: Client | undefined;\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 private readonly cancelCheckIntervalMs?: number;\n private readonly cancelGraceMs: 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 private uninstallShutdown: (() => void) | undefined;\n\n constructor(\n private readonly options: TaskAgentOptions,\n private readonly registry: Map<string, TaskHandler>\n ) {\n this.logger = makeLogger(options.debug ?? false);\n const config = options.config;\n this.api = new TasksApi({ baseUrl: config.tasksBaseUrl, key: config.key, logger: this.logger });\n this.client = options.client;\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.cancelCheckIntervalMs = options.cancelCheckIntervalMs;\n this.cancelGraceMs = options.cancelGraceMs ?? DEFAULT_CANCEL_GRACE_MS;\n this.logger.debug('agente configurado', { baseUrl: config.tasksBaseUrl });\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] start() chamado durante stop() — aguarde o stop terminar');\n }\n if (this.registry.size === 0) {\n throw new Error('[hobots] nenhuma task registrada — chame register() antes de start()');\n }\n this.state = 'started';\n if (this.options.installExitHandlers !== false && !this.uninstallShutdown) {\n this.uninstallShutdown = installShutdownHandlers(this);\n }\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 // o processo vai morrer com as runs no meio: falha imediata no app em vez\n // de esperar o sweep server-side marcar o encerramento inesperado\n await this.reportAgentTerminated('agente encerrado durante a execução (shutdown excedeu o tempo de espera)');\n }\n this.uninstallShutdown?.();\n this.uninstallShutdown = undefined;\n this.state = 'idle';\n return finished;\n }\n\n /**\n * Best-effort do exit path: reporta 'failed'/AgentTerminated para as runs ativas\n * antes do processo morrer, fora da fila do reporter e com timeout curto. Runs já\n * canceladas no app (reporter morto) são puladas; erros de rede são engolidos —\n * o sweep server-side é o backstop.\n */\n async reportAgentTerminated(message: string, timeoutMs = 2_500): Promise<void> {\n const pending: Promise<void>[] = [];\n for (const reporter of this.reporters) {\n if (reporter.isDead) continue;\n // drena os logs pendentes antes do kill (que descarta o buffer) e mata o\n // reporter: o handler zumbi não pode reenviar status por cima do failed\n const logs = reporter.drainLogs();\n reporter.kill();\n pending.push(\n this.api\n .updateRunOnce(\n reporter.context.runId,\n { status: 'failed', error: { type: 'AgentTerminated', message }, logs: logs.length > 0 ? logs : undefined },\n timeoutMs\n )\n .catch(() => {})\n );\n }\n if (pending.length === 0) return;\n await Promise.race([Promise.allSettled(pending), sleep(timeoutMs)]);\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 da Telemetria, 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 // defesa em profundidade: nunca exceder a concorrência, mesmo com resposta acima do max\n if (this.activeRuns.size >= this.concurrency) break;\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 TasksApiError && 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 agente em Configurações → Agentes');\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(jitter(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: RunDescriptor): 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: RunDescriptor): Promise<void> {\n // correlacionada à run via run_id — as steps que o handler criar em ctx.tx.startChild()\n // viram o waterfall de performance da execução no dashboard\n const tx = new Transaction(this.client, `run:${run.task}`, 'hobots.task', true, run.id);\n const reporter = new RunReporter(this.api, run.id, run.task, this.logger, tx, this.logFlushIntervalMs, this.cancelCheckIntervalMs);\n this.reporters.add(reporter);\n\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 tx.setStatus('error');\n tx.finish();\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 tx.setStatus('cancelled');\n tx.finish();\n return;\n }\n\n this.logger.debug(`executando run ${run.id} (${run.task})`);\n try {\n // corre dentro do contexto de run: startTransaction() no handler reutiliza a tx da run\n // e o hint `attachment` dos capture* chega ao pipeline de anexos desta run\n await runWithRunContext(\n { runId: run.id, tx, attach: (image, options) => reporter.attach(image, options) },\n () => this.invokeWithTimeout(handler, run, reporter)\n );\n // anexos disparados sem await (fire-and-forget) ainda podem estar subindo:\n // espera (com teto) para a run não terminar com miniaturas em \"enviando…\"\n await reporter.finalizeAttachments();\n // finish antes do terminal: as linhas FINISH de tx/steps entram no mesmo PATCH\n tx.setStatus('ok');\n tx.finish();\n reporter.reportSuccess();\n this.logger.debug(`run ${run.id} concluída`);\n } catch (error) {\n // uma falha é justamente quando o print importa — vale esperar o upload aqui também\n await reporter.finalizeAttachments();\n tx.setStatus('error');\n tx.finish();\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(handler: TaskHandler, run: RunDescriptor, reporter: RunReporter): Promise<void> {\n const invocation = Promise.resolve().then(() => handler(run.params, reporter.context));\n const races: Promise<typeof TIMEOUT_SENTINEL | typeof CANCEL_SENTINEL>[] = [];\n if (this.taskTimeoutMs && this.taskTimeoutMs > 0) {\n races.push(sleep(this.taskTimeoutMs).then(() => TIMEOUT_SENTINEL));\n }\n if (this.cancelGraceMs > 0) {\n races.push(waitForCancelGrace(reporter.context.signal, this.cancelGraceMs).then(() => CANCEL_SENTINEL));\n }\n if (races.length === 0) {\n await invocation;\n return;\n }\n\n const outcome = await Promise.race([invocation, ...races]);\n if (outcome !== TIMEOUT_SENTINEL && outcome !== CANCEL_SENTINEL) return; // invocation venceu a corrida\n\n if (outcome === CANCEL_SENTINEL) {\n // run já cancelada no app (409) há cancelGraceMs — o handler não respondeu a\n // ctx.signal a tempo; não dá para matar o código do usuário, então o agente\n // para de esperar e libera o slot. Reportes subsequentes são no-op (reporter morto).\n this.logger.warn(\n `run ${run.id} cancelada — handler não respondeu a ctx.signal em ${this.cancelGraceMs}ms, ` +\n 'liberando o slot (o handler pode continuar rodando em segundo plano)'\n );\n return;\n }\n\n // TIMEOUT_SENTINEL: não dá para matar o código do usuário — reporta, aborta o signal e libera o slot\n const timeoutMs = this.taskTimeoutMs!;\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');\nconst CANCEL_SENTINEL = Symbol('task-canceled');\n\n/** Resolve só depois que `signal` abortar + `graceMs` — nunca resolve se o signal nunca disparar. */\nfunction waitForCancelGrace(signal: AbortSignal, graceMs: number): Promise<void> {\n return new Promise<void>(resolve => {\n if (signal.aborted) {\n setTimeout(resolve, graceMs);\n return;\n }\n signal.addEventListener('abort', () => setTimeout(resolve, graceMs), { once: true });\n });\n}\n\nconst MAX_ERROR_MESSAGE_CHARS = 10_000;\nconst MAX_ERROR_STACK_CHARS = 20_000;\n\nfunction toRunError(error: unknown): RunError {\n if (error instanceof Error) {\n return {\n type: error.name,\n message: scrubSecrets(truncate(error.message, MAX_ERROR_MESSAGE_CHARS)),\n stack: error.stack ? scrubSecrets(truncate(error.stack, MAX_ERROR_STACK_CHARS)) : undefined,\n };\n }\n return { message: scrubSecrets(truncate(String(error), MAX_ERROR_MESSAGE_CHARS)) };\n}\n","import type { EventUser, Severity } from './protocol';\nimport type { CaptureAttachment, 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 { TaskAgent } from './tasks/agent';\nimport type { AttachInput } from './tasks/attachments';\nimport type { RunLogLevel } from './tasks/protocol';\nimport { currentRunAttach, currentRunTransaction } from './tasks/run-context-store';\nimport type { TaskHandler } from './tasks/types';\nimport { resolveConfig } from './config';\n\nconst DEFAULT_MAX_BREADCRUMBS = 100;\n\nlet client: Client | undefined;\nlet scope = new Scope();\nlet heartbeat: Heartbeat | undefined;\nlet agent: TaskAgent | undefined;\nconst registry = new Map<string, TaskHandler>();\nlet warnedTasksDisabled = 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 warnedTasksDisabled = false;\n\n // resolvida uma única vez por init() — Client e TaskAgent recebem a mesma config\n const config = resolveConfig(options);\n client = new Client(options, config);\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.tasks) {\n const tasksOptions = options.tasks === true ? {} : options.tasks;\n agent = new TaskAgent(\n { ...tasksOptions, config, instanceId: options.instanceId, debug: options.debug, client },\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/** O log da run não tem 'fatal' — rebaixa para 'error'. */\nfunction toRunLogLevel(level: Severity): RunLogLevel {\n return level === 'fatal' ? 'error' : level;\n}\n\n/**\n * Encaminha o `attachment` de um capture* para o pipeline de anexos da run ativa\n * (fire-and-forget): a imagem vira anexo da linha de log que espelha o evento.\n * Fora de uma execução de task não há onde pendurar a imagem — descarta com aviso.\n */\nfunction forwardAttachment(attachment: AttachInput | CaptureAttachment, message: string, level: Severity): void {\n const attach = currentRunAttach();\n if (!attach) {\n client?.logger.warn('attachment descartado — só é suportado dentro de uma execução de task (register/start)');\n return;\n }\n const withMeta = typeof attachment === 'object' && 'image' in attachment ? attachment : { image: attachment };\n void attach(withMeta.image, {\n message,\n level: toRunLogLevel(level),\n caption: withMeta.caption,\n contentType: withMeta.contentType,\n });\n}\n\n/**\n * Captura uma exceção e retorna o event_id (undefined se o SDK não foi inicializado).\n * `hint.attachment` envia um print junto — dentro de uma execução de task, ele aparece\n * como miniatura na linha de log da run correspondente ao erro.\n */\nexport function captureException(error: unknown, hint?: CaptureHint): string | undefined {\n if (hint?.attachment) {\n const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);\n forwardAttachment(hint.attachment, message, hint.level ?? 'error');\n }\n return client?.captureException(error, hint, scope);\n}\n\nexport function captureMessage(message: string, level: Severity = 'info', hint?: CaptureHint): string | undefined {\n if (hint?.attachment) {\n forwardAttachment(hint.attachment, message, hint.level ?? level);\n }\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 // dentro de um handler, a execução já tem a sua transaction (ctx.tx) —\n // reutiliza em vez de criar uma segunda com o mesmo run_id\n const active = currentRunTransaction();\n if (active) {\n client?.logger.debug(`startTransaction('${name}') dentro de uma execução — reutilizando a transaction da run`);\n return active;\n }\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/** 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 (o task_slug configurado no formulário do app, em Configurações → Formulários). */\nexport function register<P = Record<string, unknown>>(task: string, handler: TaskHandler<P>): void {\n if (registry.has(task)) {\n (agent?.logger ?? client?.logger)?.warn(`register('${task}') sobrescreveu um handler existente`);\n }\n if (client && !agent && !warnedTasksDisabled) {\n warnedTasksDisabled = true;\n client.logger.warn(\n `register('${task}') com tasks desabilitadas — passe tasks: true (ou opções) no init()`\n );\n }\n registry.set(task, handler as TaskHandler);\n}\n\n/**\n * Inicia o polling de tasks. O timer NÃO é unref'd: o processo fica vivo\n * aguardando trabalho até stop()/close() — o inverso deliberado da telemetria.\n */\nexport function start(): void {\n if (!agent) {\n throw new Error('[hobots] tasks não configuradas — passe tasks: true (ou opções) no init() antes de start()');\n }\n agent.start();\n}\n\n/** Para só o polling de tasks 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 polling de tasks (aguardando runs em voo), o heartbeat\n * e faz o 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":["hostname","scope","client","client","client","agent","registry"]}
1
+ {"version":3,"sources":["../src/config.ts","../src/stacktrace.ts","../src/scrub.ts","../src/utils.ts","../src/eventbuilder.ts","../src/transport.ts","../src/client.ts","../src/heartbeat.ts","../src/internal-handlers.ts","../src/instrument.ts","../src/scope.ts","../src/transaction.ts","../src/tasks/api.ts","../src/tasks/attachments.ts","../src/tasks/context.ts","../src/tasks/run-context-store.ts","../src/tasks/shutdown.ts","../src/tasks/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 agente (enviado como Authorization: Bearer, nunca na URL) */\n key: string;\n baseUrl: string;\n /** Ingestão de telemetria: <baseUrl>/v1/ingest */\n ingestEndpoint: string;\n /** API de tasks (execução sob demanda): <baseUrl>/v1/tasks */\n tasksBaseUrl: string;\n}\n\ninterface ConfigInput {\n clientSecret: string;\n}\n\n/** hb_<64 hex>. */\nconst SECRET_PATTERN = /^hb_[a-f0-9]{64}$/i;\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\nfunction isLoopbackHost(hostname: string): boolean {\n return (\n hostname === 'localhost' ||\n hostname.endsWith('.localhost') ||\n hostname.startsWith('127.') ||\n hostname === '[::1]' ||\n hostname === '::1' ||\n hostname === '0.0.0.0'\n );\n}\n\n// warning de http remoto sai uma vez por processo\nlet warnedInsecureBaseUrl = false;\n\n/**\n * Valida a baseUrl sem nunca ecoar o valor completo em erro/log — a env pode\n * conter credenciais embutidas por engano.\n */\nfunction validateBaseUrl(raw: string, prefix: string): string {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n throw new Error(`${prefix} HOBOTS_API_URL inválida — esperado URL http(s), ex.: http://localhost:3001`);\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') {\n throw new Error(`${prefix} HOBOTS_API_URL com esquema \"${url.protocol}\" não suportado — use http(s)`);\n }\n if (url.username || url.password) {\n throw new Error(`${prefix} HOBOTS_API_URL não pode conter credenciais na URL — a autenticação é só pelo Client Secret`);\n }\n if (url.protocol === 'http:' && !isLoopbackHost(url.hostname) && !warnedInsecureBaseUrl) {\n warnedInsecureBaseUrl = true;\n console.warn(\n `${prefix} HOBOTS_API_URL usa http para o host remoto \"${url.hostname}\" — o Client Secret trafega sem TLS`\n );\n }\n return raw.replace(/\\/+$/, '');\n}\n\n/** Resolve o clientSecret nos endpoints de telemetria e de tasks. */\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 agente em Configurações → Agentes`);\n }\n if (!SECRET_PATTERN.test(key)) {\n // nunca incluir o valor na mensagem — só o tamanho, como pista de diagnóstico\n throw new Error(\n `${prefix} clientSecret com formato inválido (${key.length} caracteres) — esperado \"hb_\" + 64 hex; copie o Client Secret do agente em Configurações → Agentes`\n );\n }\n\n const baseUrl = validateBaseUrl(envBaseUrl() ?? DEFAULT_BASE_URL, prefix);\n\n return {\n key,\n baseUrl,\n ingestEndpoint: `${baseUrl}/v1/ingest`,\n tasksBaseUrl: `${baseUrl}/v1/tasks`,\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","/**\n * Redação de segredos em texto que sai do processo (mensagens de erro, stacks,\n * logs de run). Padrões conservadores — falso positivo é preferível a vazar\n * uma credencial para o painel.\n */\nconst SECRET_PATTERNS: ReadonlyArray<readonly [RegExp, string]> = [\n // client secret da Hobots\n [/hb_[a-f0-9]{16,}/gi, '[REDACTED]'],\n // tokens bearer em headers/mensagens\n [/\\b(authorization:?\\s*)?bearer\\s+[a-z0-9._~+/=-]{8,}/gi, 'Bearer [REDACTED]'],\n // chaves no formato sk-… (OpenAI e afins)\n [/\\bsk-[a-z0-9_-]{16,}\\b/gi, '[REDACTED]'],\n // credenciais embutidas em URL (https://user:pass@host)\n [/\\/\\/[^/\\s:@]+:[^/\\s@]+@/g, '//[REDACTED]@'],\n];\n\nexport function scrubSecrets(text: string): string {\n let out = text;\n for (const [pattern, replacement] of SECRET_PATTERNS) {\n out = out.replace(pattern, replacement);\n }\n return out;\n}\n","/** Injetada pelo `define` do tsup a partir da versão do package.json. */\ndeclare const __SDK_VERSION__: string | undefined;\n\nexport const SDK_NAME = 'hobots';\nexport const SDK_VERSION = typeof __SDK_VERSION__ === 'string' ? __SDK_VERSION__ : '0.0.0-dev';\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 if (cryptoRef && typeof cryptoRef.getRandomValues === 'function') {\n const bytes = cryptoRef.getRandomValues(new Uint8Array(16));\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n return Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n }\n // último recurso (runtimes sem crypto algum) — ids aqui são só de correlação\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\n/** Equal jitter: metade fixa + metade aleatória, evita thundering herd nos retries. */\nexport function jitter(baseMs: number): number {\n return Math.floor(baseMs / 2 + Math.random() * (baseMs / 2));\n}\n\nexport function truncate(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max)}… [truncado]` : value;\n}\n\nexport const DEFAULT_RETRY_DELAYS_MS: readonly number[] = [1_000, 4_000, 16_000];\n\n/**\n * Executa `send` com retry em falha de rede/5xx/429 (respeitando Retry-After + jitter).\n * Devolve a Response tanto em ok quanto em 4xx≠429 — a rejeição definitiva é decisão\n * do chamador (o transport descarta logando; a API de tasks lança erro tipado).\n * Lança o último erro quando o ladder de retries esgota.\n */\nexport async function fetchWithRetry(\n send: () => Promise<Response>,\n options: { delays?: readonly number[]; logger: Logger; label: string }\n): Promise<Response> {\n const delays = options.delays ?? DEFAULT_RETRY_DELAYS_MS;\n for (let attempt = 0; ; attempt++) {\n let retriable: unknown;\n let serverDelay: number | undefined;\n try {\n const response = await send();\n if (response.ok) return response;\n if (response.status >= 400 && response.status < 500 && response.status !== 429) return response;\n if (response.status === 429) serverDelay = retryAfterMs(response);\n retriable = new Error(`HTTP ${response.status}`);\n } catch (error) {\n retriable = error;\n }\n const base = delays[attempt];\n if (base === undefined) {\n throw retriable instanceof Error ? retriable : new Error(String(retriable));\n }\n const delay = serverDelay ?? jitter(base);\n options.logger.warn(`${options.label}: falha (${String(retriable)}), retry em ${delay}ms`);\n await sleep(delay);\n }\n}\n\nconst MAX_RETRY_AFTER_MS = 60_000;\n\n/** Parse do header Retry-After (segundos ou HTTP-date), clampado a [0, 60s]. */\nexport function retryAfterMs(response: Response): number | undefined {\n const header = response.headers.get('retry-after');\n if (!header) return undefined;\n const seconds = Number(header);\n if (Number.isFinite(seconds)) {\n return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, seconds * 1_000));\n }\n const date = Date.parse(header);\n if (Number.isNaN(date)) return undefined;\n return Math.min(MAX_RETRY_AFTER_MS, Math.max(0, date - Date.now()));\n}\n\n/**\n * Signal com timeout composável com um signal externo (stop/cancelamento).\n * Node 18 não tem AbortSignal.any — composição manual; chame cleanup() em finally\n * para não acumular listeners num signal externo reutilizado.\n */\nexport function withTimeoutSignal(timeoutMs: number, external?: AbortSignal): { signal: AbortSignal; cleanup: () => void } {\n const controller = new AbortController();\n const onAbort = (): void => controller.abort(external?.reason);\n if (external?.aborted) {\n onAbort();\n } else {\n external?.addEventListener('abort', onAbort, { once: true });\n }\n const timer = setTimeout(() => {\n controller.abort(Object.assign(new Error(`timeout após ${timeoutMs}ms`), { name: 'TimeoutError' }));\n }, timeoutMs);\n unrefTimer(timer);\n return {\n signal: controller.signal,\n cleanup: () => {\n clearTimeout(timer);\n external?.removeEventListener('abort', onAbort);\n },\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]';\n\nexport function makeLogger(enabled: boolean, prefix: string = PREFIX): Logger {\n return {\n debug: (...args) => enabled && console.debug(colorize(prefix, 'gray'), ...args),\n warn: (...args) => enabled && console.warn(colorize(prefix, 'yellow'), ...args),\n error: (...args) => console.error(colorize(prefix, 'red'), ...args),\n };\n}\n\nconst ANSI = {\n reset: '\\x1b[0m',\n gray: '\\x1b[90m',\n cyan: '\\x1b[36m',\n yellow: '\\x1b[33m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n} as const;\n\nfunction colorEnabled(): boolean {\n if (!isNode()) return false;\n return Boolean(process.stdout?.isTTY) && !process.env.NO_COLOR;\n}\n\n/** Envolve `text` em código ANSI — vira no-op fora de um TTY Node (ou com NO_COLOR definido). */\nexport function colorize(text: string, color: keyof typeof ANSI): string {\n if (!colorEnabled()) return text;\n return `${ANSI[color]}${text}${ANSI.reset}`;\n}\n","import type { EventPayload, Severity } from './protocol';\nimport { parseStacktrace } from './stacktrace';\nimport { scrubSecrets } from './scrub';\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 = scrubSecrets(error.message);\n frames = parseStacktrace(error.stack);\n } else {\n type = 'NonError';\n value = scrubSecrets(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: scrubSecrets(message),\n };\n}\n","import type { Envelope, EnvelopeItem } from './protocol';\nimport { SDK_NAME, SDK_VERSION, fetchWithRetry, nowISO, sleep, unrefTimer, type Logger } from './utils';\n\nconst REQUEST_TIMEOUT_MS = 10_000;\nconst DEFAULT_FLUSH_INTERVAL_MS = 2_000;\nconst DEFAULT_MAX_BATCH_SIZE = 10;\nconst DEFAULT_MAX_QUEUE_SIZE = 200;\n/**\n * Teto de itens por envelope — espelha o `.max(50)` de `envelopeSchema.items`\n * (apps/api/lib/ingest/schemas.ts). Acima disso a API responde 422 e o envelope é\n * descartado sem retry, então a fila é fatiada em envelopes deste tamanho antes de enviar.\n * Ao mudar um dos dois lados, mude o outro.\n */\nconst MAX_ITEMS_PER_ENVELOPE = 50;\n\nexport interface TransportOptions {\n endpoint: string;\n /** Chave secreta do agente — 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 // nunca descarta heartbeat: um burst de erros não pode derrubar a presença —\n // o servidor marcaria offline um agente vivo (e gritando)\n const dropIndex = this.buffer.findIndex(queued => queued.type !== 'heartbeat');\n this.buffer.splice(dropIndex === -1 ? 0 : dropIndex, 1);\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 // maxBatchSize decide *quando* flushar, não quanto cabe num envelope: um burst de\n // captures (ou uma janela de rede ruim em que a fila cresceu até maxQueueSize) junta\n // mais itens do que a API aceita, então quebra em lotes de MAX_ITEMS_PER_ENVELOPE.\n const taken = this.buffer.splice(0, this.buffer.length);\n const sends: Promise<void>[] = [];\n for (let offset = 0; offset < taken.length; offset += MAX_ITEMS_PER_ENVELOPE) {\n sends.push(this.send(taken.slice(offset, offset + MAX_ITEMS_PER_ENVELOPE)));\n }\n return Promise.all(sends).then(() => undefined);\n }\n\n /** Registra o envio em `this.pending` para que `flush()` aguarde todos os envelopes. */\n private send(items: EnvelopeItem[]): Promise<void> {\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 let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(this.endpoint, {\n method: 'POST',\n headers: { 'content-type': 'application/json', authorization: `Bearer ${this.key}` },\n body: JSON.stringify(envelope),\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n }),\n { logger: this.logger, label: 'envio de envelope' }\n );\n } catch (error) {\n this.logger.error('envelope descartado após retries:', error);\n return;\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 this.logger.error(`envelope rejeitado (HTTP ${response.status}), descartado (${envelope.items.length} itens)`);\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 { 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 { SDK_NAME, SDK_VERSION, 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 logger: Logger;\n /** Eco de lifecycle (Transaction.emit) e afins só imprimem no terminal com debug ligado. */\n readonly debug: boolean;\n // campos privados + getters de protótipo: o clientSecret não aparece em\n // JSON.stringify/serialização enumerável do Client (ex.: um objeto capturado\n // que referencie o client), mas client.options/config seguem funcionando\n readonly #options: InitOptions;\n readonly #config: ResolvedConfig;\n private readonly transport: Transport;\n\n constructor(options: InitOptions, config: ResolvedConfig = resolveConfig(options)) {\n this.#options = options;\n this.debug = !!options.debug;\n this.logger = makeLogger(this.debug);\n this.#config = config;\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 get options(): InitOptions {\n return this.#options;\n }\n\n get config(): ResolvedConfig {\n return this.#config;\n }\n\n /** Serialização explícita nunca inclui o secret. */\n toJSON(): Record<string, unknown> {\n return { sdk: SDK_NAME, version: SDK_VERSION, baseUrl: this.#config.baseUrl };\n }\n\n [Symbol.for('nodejs.util.inspect.custom')](): string {\n return `Client { baseUrl: '${this.#config.baseUrl}' }`;\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 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// faixa aceita pelo servidor para interval_ms (apps/api/lib/ingest/schemas.ts) — o valor\n// REPORTADO é clampado para o envelope não ser rejeitado; a cadência real fica como configurada.\n// Janelas maiores que 15 min são caso para o timeout de presença do agente, no app.\nconst MIN_REPORTED_INTERVAL_MS = 1_000;\nconst MAX_REPORTED_INTERVAL_MS = 900_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 setTimeout> | 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.schedule();\n }\n\n /** Jitter de ±10%: uma frota iniciada junto não sincroniza todos os beats no mesmo segundo. */\n private schedule(): void {\n this.timer = setTimeout(\n () => {\n this.beat();\n this.schedule();\n },\n this.intervalMs * (0.9 + Math.random() * 0.2)\n );\n unrefTimer(this.timer);\n }\n\n stop(): void {\n if (this.timer) {\n clearTimeout(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: Math.min(Math.max(this.intervalMs, MIN_REPORTED_INTERVAL_MS), MAX_REPORTED_INTERVAL_MS),\n timestamp: nowISO(),\n metadata: this.metadata,\n });\n }\n}\n","import { sleep } from './utils';\n\n/**\n * Coordenação entre os handlers de processo do SDK (instrument + tasks/shutdown):\n * marca os listeners internos para que a checagem de \"o programa tem handler próprio?\"\n * não conte os nossos, e agrega os reportes de emergência que o exit precisa aguardar.\n */\nconst INTERNAL = Symbol.for('hobots.sdk.internalListener');\n\ntype Marked = { [INTERNAL]?: true };\n\nexport function markInternal<T extends (...args: never[]) => unknown>(listener: T): T {\n (listener as Marked)[INTERNAL] = true;\n return listener;\n}\n\n/** Listeners do programa (não-SDK) para o evento — decide se o SDK preserva o exit default. */\nexport function externalListenerCount(event: string): number {\n const listeners = process.listeners(event as 'uncaughtException');\n return listeners.filter(listener => !(listener as Marked)[INTERNAL]).length;\n}\n\nconst emergencyTasks: Promise<unknown>[] = [];\n\n/** Reporte best-effort em voo (ex: run → AgentTerminated) que um exit iminente deve aguardar. */\nexport function addEmergencyTask(task: Promise<unknown>): void {\n emergencyTasks.push(task);\n}\n\nexport async function awaitEmergencyTasks(capMs: number): Promise<void> {\n if (emergencyTasks.length === 0) return;\n await Promise.race([Promise.allSettled(emergencyTasks), sleep(capMs)]);\n}\n","import type { Client } from './client';\nimport type { Scope } from './scope';\nimport { awaitEmergencyTasks, externalListenerCount, markInternal } from './internal-handlers';\nimport { isNode } from './utils';\n\nconst EMERGENCY_REPORT_CAP_MS = 3_000;\n\nlet installed = false;\n\n/** O tasks/shutdown consulta para saber se o exit de uncaughtException já tem dono. */\nexport function hasInstalledGlobalHandlers(): boolean {\n return installed;\n}\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(\n 'uncaughtException',\n markInternal((error: Error) => {\n client.captureException(error, { level: 'fatal', tags: { mechanism: 'uncaughtException' } }, getScope());\n void client.flush(2_000).then(async () => {\n // conta só handlers do programa — os do próprio SDK (este e o de tasks) não\n // impedem o exit default\n if (externalListenerCount('uncaughtException') === 0) {\n // aguarda o reporte de emergência do agente de tasks (runs → AgentTerminated), se houver\n await awaitEmergencyTasks(EMERGENCY_REPORT_CAP_MS);\n console.error(error);\n process.exit(1);\n }\n });\n })\n );\n\n process.on(\n 'unhandledRejection',\n markInternal((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\n // rede de segurança: envia o que restou na fila quando o event loop esvazia\n process.on(\n 'beforeExit',\n markInternal(() => {\n void client.flush(2_000);\n })\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 { StepData, StepStatus, TransactionPayload } from './protocol';\nimport type { RunLogLevel } from './tasks/protocol';\nimport type { Client } from './client';\nimport { colorize, nowISO, uuid4 } from './utils';\n\nfunction stepId(): string {\n return uuid4().slice(0, 16);\n}\n\n/** Recebe os eventos de lifecycle da transaction para espelhá-los nos logs da run. */\nexport type LifecycleSink = (level: RunLogLevel, message: string) => void;\n\n/** Rótulo legível de uma step a partir de op/description. */\nfunction stepLabel(op?: string, description?: string): string {\n return [op, description].filter(Boolean).join(' — ') || '(sem nome)';\n}\n\n/** Mapeia o status de finalização (step/transaction) para o nível de log da run. */\nfunction levelForStatus(status: StepStatus | string): RunLogLevel {\n switch (status) {\n case 'warning':\n return 'warning';\n case 'error':\n return 'error';\n case 'cancelled':\n return 'warning';\n default:\n return 'success';\n }\n}\n\n/** Mapeia o status de finalização para a cor ANSI usada no eco do terminal. */\nfunction colorForStatus(status: StepStatus | string): Parameters<typeof colorize>[1] {\n switch (status) {\n case 'warning':\n return 'yellow';\n case 'error':\n return 'red';\n case 'cancelled':\n return 'gray';\n default:\n return 'green';\n }\n}\n\nexport class Step {\n readonly stepId = stepId();\n readonly startTimestamp = nowISO();\n status: StepStatus = 'ok';\n endTimestamp?: string;\n data?: Record<string, unknown>;\n\n constructor(\n private readonly transaction: Transaction,\n readonly parentStepId: string,\n readonly op?: string,\n readonly description?: string\n ) {}\n\n setStatus(status: StepStatus): 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 /** Step aninhada (filha desta step). */\n startChild(op?: string, description?: string): Step {\n return this.transaction.createStep(this.stepId, op, description);\n }\n\n finish(): void {\n if (this.endTimestamp) return;\n this.endTimestamp = nowISO();\n this.transaction.emit(\n 'step',\n 'finish',\n stepLabel(this.op, this.description),\n this.startTimestamp,\n this.endTimestamp,\n this.status\n );\n }\n\n toJSON(): StepData {\n return {\n step_id: this.stepId,\n parent_step_id: this.parentStepId,\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 * Steps filhas medem as etapas internas (chamadas HTTP, queries, etc.).\n */\nexport class Transaction {\n readonly eventId = uuid4();\n readonly stepId = stepId();\n readonly startTimestamp = nowISO();\n status = 'ok';\n private readonly steps: Step[] = [];\n private readonly tags: Record<string, string> = {};\n private finished = false;\n private lifecycleSink?: LifecycleSink;\n // eventos emitidos antes do sink existir (o START da transaction sai no construtor,\n // antes do RunReporter conectar) — replay no setLifecycleSink\n private lifecycleBacklog: Array<[RunLogLevel, string]> = [];\n\n constructor(\n private readonly client: Client | undefined,\n public name: string,\n readonly op?: string,\n private readonly sampled = true,\n /** Correlaciona a uma execução de task — preenchido automaticamente em ctx.tx */\n private readonly runId?: string\n ) {\n this.emit('transaction', 'start', op ? `${name} (${op})` : name);\n }\n\n /**\n * Registra o início/fim de uma step ou transaction: espelha a linha no sink de\n * lifecycle, se conectado (é assim que os eventos de performance aparecem nos\n * logs da run no app), e ecoa no terminal apenas com `debug: true` — o SDK não\n * escreve no stdout do processo do usuário sem permissão.\n */\n emit(\n kind: 'transaction' | 'step',\n phase: 'start' | 'finish',\n label: string,\n startTs?: string,\n endTs?: string,\n status?: StepStatus | string\n ): void {\n const durationMs = startTs && endTs ? new Date(endTs).getTime() - new Date(startTs).getTime() : undefined;\n const suffix = durationMs != null ? ` (${durationMs}ms)` : '';\n\n if (this.client?.debug) {\n const tag = colorize(`[hobots:${kind}] ${phase.toUpperCase()}`, phase === 'finish' ? colorForStatus(status ?? 'ok') : 'cyan');\n console.log(`${tag} ${label}${suffix}`);\n }\n\n const level: RunLogLevel = phase === 'finish' ? levelForStatus(status ?? 'ok') : 'info';\n const message = `[${kind}] ${phase.toUpperCase()} ${label}${suffix}`;\n if (this.lifecycleSink) this.lifecycleSink(level, message);\n // sem sink (transaction fora de run): backlog capado — nunca vai ser drenado\n else if (this.lifecycleBacklog.length < 100) this.lifecycleBacklog.push([level, message]);\n }\n\n /** Conecta o espelho de lifecycle (RunReporter) e faz replay do backlog em ordem. */\n setLifecycleSink(sink: LifecycleSink): void {\n this.lifecycleSink = sink;\n const backlog = this.lifecycleBacklog;\n this.lifecycleBacklog = [];\n for (const [level, message] of backlog) sink(level, message);\n }\n\n createStep(parentStepId: string, op?: string, description?: string): Step {\n const step = new Step(this, parentStepId, op, description);\n this.steps.push(step);\n this.emit('step', 'start', stepLabel(op, description));\n return step;\n }\n\n /** Step direta da transaction. */\n startChild(op?: string, description?: string): Step {\n return this.createStep(this.stepId, 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 step of this.steps) step.finish();\n\n const endTimestamp = nowISO();\n this.emit(\n 'transaction',\n 'finish',\n this.op ? `${this.name} (${this.op})` : this.name,\n this.startTimestamp,\n endTimestamp,\n this.status\n );\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: endTimestamp,\n steps: this.steps.map(step => step.toJSON()),\n tags: Object.keys(this.tags).length > 0 ? this.tags : undefined,\n run_id: this.runId,\n };\n this.client.sendTransaction(payload);\n }\n}\n","import type {\n PollRequest,\n PollResponse,\n RunAttachmentConfirmRequest,\n RunAttachmentCreateRequest,\n RunAttachmentCreateResponse,\n RunDescriptor,\n RunItemsCreateRequest,\n RunItemsCreateResponse,\n RunUpdateRequest,\n} from './protocol';\nimport { fetchWithRetry, withTimeoutSignal, type Logger } from '../utils';\n\nconst POLL_TIMEOUT_MS = 30_000;\nconst UPDATE_TIMEOUT_MS = 10_000;\n/** O PUT carrega o binário inteiro — ladder mais curta e timeout mais folgado que os PATCHes. */\nconst UPLOAD_TIMEOUT_MS = 30_000;\nconst UPLOAD_RETRY_DELAYS_MS: readonly number[] = [1_000, 4_000];\n\nexport class TasksApiError extends Error {\n constructor(\n message: string,\n readonly status: number\n ) {\n super(message);\n this.name = 'TasksApiError';\n }\n}\n\nexport interface TasksApiOptions {\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 TasksApi {\n private readonly baseUrl: string;\n private readonly key: string;\n private readonly logger: Logger;\n\n constructor(options: TasksApiOptions) {\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: PollRequest, signal?: AbortSignal): Promise<PollResponse> {\n const { signal: timeoutSignal, cleanup } = withTimeoutSignal(POLL_TIMEOUT_MS, signal);\n let response: Response;\n try {\n response = await fetch(`${this.baseUrl}/poll`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal: timeoutSignal,\n });\n } finally {\n cleanup();\n }\n if (!response.ok) {\n throw new TasksApiError(`poll falhou (HTTP ${response.status})`, response.status);\n }\n return this.parsePollResponse(await response.json(), request.max ?? 1);\n }\n\n /** Nunca confia no shape da resposta: runs malformadas são descartadas e o `max` é respeitado. */\n private parsePollResponse(body: unknown, max: number): PollResponse {\n const runs = (body as { runs?: unknown } | null)?.runs;\n if (!Array.isArray(runs)) {\n throw new TasksApiError('resposta inválida do poll (campo runs ausente)', 0);\n }\n const valid: RunDescriptor[] = [];\n for (const run of runs.slice(0, Math.max(0, max)) as Array<Record<string, unknown> | null>) {\n if (typeof run?.id !== 'string' || typeof run.task !== 'string') continue;\n const params = run.params && typeof run.params === 'object' && !Array.isArray(run.params) ? run.params : {};\n valid.push({ ...run, id: run.id, task: run.task, params } as RunDescriptor);\n }\n if (valid.length < runs.length) {\n this.logger.warn(`poll retornou ${runs.length - valid.length} run(s) inválida(s)/excedente(s) — descartadas`);\n }\n return { runs: valid };\n }\n\n /**\n * PATCH de status/logs com retry em falha de rede/5xx/429.\n * 4xx é definitivo e vira TasksApiError imediato (409 = run cancelada/transição inválida).\n */\n async updateRun(runId: string, update: RunUpdateRequest): Promise<void> {\n let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}`, {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(update),\n signal: AbortSignal.timeout(UPDATE_TIMEOUT_MS),\n }),\n { logger: this.logger, label: `update da run ${runId}` }\n );\n } catch (error) {\n throw new Error(`update da run ${runId} descartado após retries: ${String(error)}`);\n }\n if (!response.ok) {\n // 4xx definitivo (409 = run cancelada/transição inválida) — o RunReporter trata por status\n throw new TasksApiError(`update rejeitado (HTTP ${response.status})`, response.status);\n }\n }\n\n /**\n * Um único PATCH com timeout curto — exit path (o processo está morrendo, o retry\n * ladder do updateRun é proibido aqui). Status HTTP é ignorado: 409/404 significa\n * que a run já foi cancelada/finalizada, o que é aceitável nesse caminho.\n */\n async updateRunOnce(runId: string, update: RunUpdateRequest, timeoutMs = 2_000): Promise<void> {\n await fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}`, {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(update),\n signal: AbortSignal.timeout(timeoutMs),\n });\n }\n\n /**\n * Envia um lote de itens de execução. Retry em falha de rede/5xx/429-transporte;\n * 4xx é definitivo (404 = servidor sem o recurso, 429 = cap de itens por run) —\n * o RunReporter trata por status.\n */\n async createItems(runId: string, request: RunItemsCreateRequest): Promise<RunItemsCreateResponse> {\n let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}/items`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal: AbortSignal.timeout(UPDATE_TIMEOUT_MS),\n }),\n { logger: this.logger, label: `itens da run ${runId}` }\n );\n } catch (error) {\n // 429 persistente após os retries = cap de itens da run (permanente) — o\n // reporter precisa do status para degradar em vez de devolver ao buffer\n if (error instanceof Error && error.message === 'HTTP 429') {\n throw new TasksApiError('envio de itens rejeitado (HTTP 429)', 429);\n }\n throw new Error(`envio de itens da run ${runId} descartado após retries: ${String(error)}`);\n }\n if (!response.ok) {\n throw new TasksApiError(`envio de itens rejeitado (HTTP ${response.status})`, response.status);\n }\n const body = (await response.json().catch(() => null)) as Partial<RunItemsCreateResponse> | null;\n return {\n accepted: typeof body?.accepted === 'number' ? body.accepted : request.items.length,\n duplicates: typeof body?.duplicates === 'number' ? body.duplicates : 0,\n };\n }\n\n /**\n * Registra o anexo e obtém a URL presignada de upload. 404/501/503 significam\n * \"esta instalação não tem anexos\" — o RunReporter degrada em silêncio a partir daí.\n */\n async createAttachment(\n runId: string,\n request: RunAttachmentCreateRequest,\n signal?: AbortSignal\n ): Promise<RunAttachmentCreateResponse> {\n const { signal: timeoutSignal, cleanup } = withTimeoutSignal(UPDATE_TIMEOUT_MS, signal);\n let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(`${this.baseUrl}/runs/${encodeURIComponent(runId)}/attachments`, {\n method: 'POST',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal: timeoutSignal,\n }),\n { logger: this.logger, label: `anexo da run ${runId}` }\n );\n } finally {\n cleanup();\n }\n if (!response.ok) {\n throw new TasksApiError(`criação de anexo rejeitada (HTTP ${response.status})`, response.status);\n }\n const body = (await response.json()) as Partial<RunAttachmentCreateResponse> | null;\n if (typeof body?.upload_url !== 'string') {\n throw new TasksApiError('resposta inválida do anexo (upload_url ausente)', 0);\n }\n return {\n id: body.id ?? request.id,\n upload_url: body.upload_url,\n headers: body.headers ?? { 'content-type': request.content_type },\n expires_in: body.expires_in ?? 900,\n };\n }\n\n /**\n * PUT do binário direto no S3. Deliberadamente sem `authorization`: a autorização\n * está na assinatura da URL, e mandar o client secret para fora da API seria vazamento.\n */\n async uploadAttachment(\n url: string,\n headers: Record<string, string>,\n body: Uint8Array,\n signal?: AbortSignal\n ): Promise<void> {\n const { signal: timeoutSignal, cleanup } = withTimeoutSignal(UPLOAD_TIMEOUT_MS, signal);\n let response: Response;\n try {\n response = await fetchWithRetry(\n () =>\n fetch(url, {\n method: 'PUT',\n headers,\n // BodyInit não aceita Uint8Array<ArrayBufferLike> em todos os lib.dom; o buffer é o mesmo\n body: body as BodyInit,\n signal: timeoutSignal,\n }),\n { delays: UPLOAD_RETRY_DELAYS_MS, logger: this.logger, label: 'upload de anexo' }\n );\n } finally {\n cleanup();\n }\n if (!response.ok) {\n throw new TasksApiError(`upload de anexo rejeitado (HTTP ${response.status})`, response.status);\n }\n }\n\n /** Marca o anexo como enviado (ou falho). Best-effort — a leitura não depende disso. */\n async confirmAttachment(\n runId: string,\n attachmentId: string,\n request: RunAttachmentConfirmRequest\n ): Promise<void> {\n const response = await fetch(\n `${this.baseUrl}/runs/${encodeURIComponent(runId)}/attachments/${encodeURIComponent(attachmentId)}`,\n {\n method: 'PATCH',\n headers: this.headers(),\n body: JSON.stringify(request),\n signal: AbortSignal.timeout(UPDATE_TIMEOUT_MS),\n }\n );\n if (!response.ok) {\n throw new TasksApiError(`confirmação de anexo rejeitada (HTTP ${response.status})`, response.status);\n }\n }\n}\n","import type { RunAttachmentContentType, RunLogLevel } from './protocol';\nimport { isNode } from '../utils';\n\n/** Tamanho máximo de um anexo. O servidor aplica o mesmo teto. */\nexport const MAX_ATTACHMENT_BYTES = 5_242_880; // 5 MB\n/** Teto de anexos por execução. O servidor aplica o mesmo teto (429). */\nexport const MAX_ATTACHMENTS_PER_RUN = 20;\n/** Uploads simultâneos por run — o resto fica na fila. */\nexport const MAX_CONCURRENT_UPLOADS = 3;\nexport const MAX_CAPTION_CHARS = 200;\n/** Tempo máximo que a run espera pelos uploads pendentes antes do PATCH terminal. */\nexport const ATTACHMENT_DRAIN_MS = 15_000;\n\nexport interface AttachOptions {\n /** Legenda curta, exibida sob a miniatura no app. Passa pelo scrub de segredos. */\n caption?: string;\n /** Nível da linha de log que carrega o anexo. Default: 'info' */\n level?: RunLogLevel;\n /** Texto da linha de log. Default: a legenda, ou 'captura de tela' */\n message?: string;\n /** Informe quando os magic bytes não bastarem (o SDK sempre prefere o que detectar). */\n contentType?: RunAttachmentContentType;\n}\n\nexport type AttachFailureReason =\n /** A instalação do Hobots não tem anexos habilitados (ou a API é anterior ao recurso) */\n | 'unsupported'\n | 'too-large'\n | 'quota'\n | 'read-failed'\n /** Formato não reconhecido ou fora de PNG/JPEG/WEBP */\n | 'unsupported-format'\n | 'upload-failed'\n | 'canceled';\n\nexport interface AttachResult {\n /** Id do anexo, o mesmo referenciado na linha de log */\n id: string;\n ok: boolean;\n /** Motivo do insucesso — para diagnóstico; `attach` nunca lança */\n reason?: AttachFailureReason;\n}\n\n/** Aceita tudo que o handler pode ter em mãos: bytes ou um caminho de arquivo (só Node). */\nexport type AttachInput = Uint8Array | ArrayBuffer | string;\n\n/**\n * Lê um arquivo de imagem do disco. Import dinâmico de `node:fs/promises` — nada de\n * import estático de builtin do Node, que quebraria o bundle neutro/browser.\n */\nexport async function readImageFile(path: string): Promise<Uint8Array> {\n if (!isNode()) {\n throw new Error('caminho de arquivo só é suportado em Node');\n }\n const { readFile } = await import('node:fs/promises');\n return new Uint8Array(await readFile(path));\n}\n\nfunction startsWith(bytes: Uint8Array, signature: readonly number[], offset = 0): boolean {\n if (bytes.length < offset + signature.length) return false;\n return signature.every((byte, index) => bytes[offset + index] === byte);\n}\n\nconst PNG_MAGIC = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] as const;\nconst JPEG_MAGIC = [0xff, 0xd8, 0xff] as const;\nconst RIFF_MAGIC = [0x52, 0x49, 0x46, 0x46] as const; // \"RIFF\"\nconst WEBP_MAGIC = [0x57, 0x45, 0x42, 0x50] as const; // \"WEBP\" no offset 8\n\n/** Detecta o formato pelos magic bytes. `undefined` quando não é PNG/JPEG/WEBP. */\nexport function sniffContentType(bytes: Uint8Array): RunAttachmentContentType | undefined {\n if (startsWith(bytes, PNG_MAGIC)) return 'image/png';\n if (startsWith(bytes, JPEG_MAGIC)) return 'image/jpeg';\n if (startsWith(bytes, RIFF_MAGIC) && startsWith(bytes, WEBP_MAGIC, 8)) return 'image/webp';\n return undefined;\n}\n\n/**\n * Dimensões pelo chunk IHDR de um PNG (bytes 16..23). Só PNG: é o formato de print\n * mais comum e o único que dá pra ler sem parser. Sem dimensões o app apenas não\n * reserva o espaço da miniatura antes do carregamento.\n */\nexport function readPngDimensions(bytes: Uint8Array): { width: number; height: number } | undefined {\n if (!startsWith(bytes, PNG_MAGIC) || bytes.length < 24) return undefined;\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const width = view.getUint32(16);\n const height = view.getUint32(20);\n if (width === 0 || height === 0) return undefined;\n return { width, height };\n}\n\n/** Normaliza a entrada do handler para bytes, lendo do disco quando for um caminho. */\nexport async function toBytes(input: AttachInput): Promise<Uint8Array> {\n if (typeof input === 'string') return readImageFile(input);\n if (input instanceof Uint8Array) return input;\n return new Uint8Array(input);\n}\n","import type {\n RunAttachmentContentType,\n RunError,\n RunItemInput,\n RunItemStatus,\n RunUpdateRequest,\n RunLogEntry,\n RunLogLevel,\n} from './protocol';\nimport type { RunContext, RunItems, RunLogger } from './types';\nimport { TasksApi, TasksApiError } from './api';\nimport {\n ATTACHMENT_DRAIN_MS,\n MAX_ATTACHMENTS_PER_RUN,\n MAX_ATTACHMENT_BYTES,\n MAX_CAPTION_CHARS,\n MAX_CONCURRENT_UPLOADS,\n readPngDimensions,\n sniffContentType,\n toBytes,\n type AttachFailureReason,\n type AttachInput,\n type AttachOptions,\n type AttachResult,\n} from './attachments';\nimport { colorize, nowISO, truncate, unrefTimer, uuid4, type Logger } from '../utils';\nimport { scrubSecrets } from '../scrub';\nimport type { Transaction } from '../transaction';\n\nconst LOG_LEVEL_COLOR = {\n debug: 'gray',\n info: 'cyan',\n warning: 'yellow',\n error: 'red',\n success: 'green',\n} as const;\n\n/** Ecoa o log da run no terminal local, colorido por nível — o buffer/envio ao servidor é independente disso. */\nfunction printRunLog(task: string, level: RunLogLevel, message: string): void {\n const line = colorize(`[hobots:${task}] ${level.toUpperCase()}`, LOG_LEVEL_COLOR[level]);\n const method = level === 'warning' ? 'warn' : level === 'success' ? 'info' : level;\n console[method](line, message);\n}\n\nfunction runCanceledError(): Error {\n return Object.assign(new Error('execução cancelada'), { name: 'RunCanceled' });\n}\n\n/**\n * Sleep que respeita o ctx.signal — rejeita com RunCanceled no abort.\n * O timer NÃO é unref'd de propósito: uma run em execução é trabalho legítimo e\n * deve segurar o processo vivo mesmo com o polling já parado (shutdown gracioso).\n */\nfunction cancelableSleep(ms: number, signal: AbortSignal): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (signal.aborted) {\n reject(runCanceledError());\n return;\n }\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(runCanceledError());\n };\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n signal.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nconst DEFAULT_LOG_FLUSH_INTERVAL_MS = 2_000;\nconst DEFAULT_CANCEL_CHECK_INTERVAL_MS = 5_000;\nconst MIN_CANCEL_CHECK_INTERVAL_MS = 1_000;\n// teto: o PATCH periódico é o sinal de vida da run — o servidor marca como\n// encerrada inesperadamente após ~120s sem reporte, então o intervalo não pode chegar perto disso\nconst MAX_CANCEL_CHECK_INTERVAL_MS = 15_000;\nconst MAX_LOG_MESSAGE_CHARS = 10_000;\nconst MAX_LOGS_PER_PATCH = 100;\nconst FLUSH_AT_BUFFERED = 20;\n\n// Itens de execução — limites espelham o servidor (apps/api/lib/tasks/items.ts)\nconst MAX_ITEMS_PER_RUN = 10_000;\nconst MAX_ITEMS_PER_REQUEST = 500;\nconst MAX_ITEM_MESSAGE_CHARS = 2_000;\nconst MAX_ITEM_PAYLOAD_BYTES = 16_384;\nconst ITEMS_FLUSH_AT_BUFFERED = 100;\n/** Teto do dreno de itens antes do PATCH terminal — como o dreno de anexos. */\nconst ITEMS_DRAIN_MS = 15_000;\n\n/** Scrub recursivo das strings do payload (profundidade capada — payload é raso por natureza). */\nfunction scrubPayloadValue(value: unknown, depth: number): unknown {\n if (typeof value === 'string') return scrubSecrets(value);\n if (depth >= 4 || value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(entry => scrubPayloadValue(entry, depth + 1));\n const out: Record<string, unknown> = {};\n for (const [key, entry] of Object.entries(value as Record<string, unknown>)) {\n out[key] = scrubPayloadValue(entry, depth + 1);\n }\n return out;\n}\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/finalizada no servidor): o handler não\n * pode ser morto, mas status posterior é suprimido e ctx.signal dispara para abort\n * cooperativo. Logs nunca são descartados em silêncio: falha de rede devolve ao\n * buffer, e depois da morte eles seguem best-effort como \"log tardio\" (o servidor\n * anexa logs a runs terminais mesmo respondendo 409).\n */\nexport class RunReporter {\n readonly context: RunContext;\n\n private buffer: RunLogEntry[] = [];\n private dead = false;\n private chain: Promise<void> = Promise.resolve();\n private pendingUpdates = 0;\n private timer: ReturnType<typeof setTimeout> | undefined;\n private watchTimer: ReturnType<typeof setInterval> | undefined;\n private readonly abortController = new AbortController();\n private readonly flushIntervalMs: number;\n private readonly cancelCheckIntervalMs: number;\n\n // Itens de execução vivem FORA de `this.chain` (status/liveness não pode ficar\n // atrás de milhares de itens), mas têm cadeia própria serializada — ordem de\n // envio preservada e sem lotes sobrepostos.\n private itemsBuffer: RunItemInput[] = [];\n private itemsChain: Promise<void> = Promise.resolve();\n private itemsTimer: ReturnType<typeof setTimeout> | undefined;\n private itemSeq = 0;\n private itemCount = 0;\n /** Servidor sem o recurso (404) — para de tentar (e de avisar) nesta run. */\n private itemsUnsupported = false;\n /** Cap de itens por run atingido (client-side ou 429) — degrada com um aviso só. */\n private itemsQuotaExceeded = false;\n /**\n * Só o kill() do exit path fecha os itens — `dead` (run cancelada/finalizada no\n * servidor) NÃO fecha: o servidor aceita itens de run terminal (trabalho já feito).\n */\n private itemsClosed = false;\n\n // Uploads de anexo vivem FORA de `this.chain`: a cadeia é um FIFO puro de\n // status/logs e não pode ficar bloqueada esperando um binário subir.\n private readonly pendingAttachments = new Set<Promise<void>>();\n private attachmentCount = 0;\n private uploadSlots = MAX_CONCURRENT_UPLOADS;\n private uploadQueue: Array<() => void> = [];\n /** Uma vez que a instalação recusa anexos, para de tentar (e de avisar) nesta run. */\n private attachmentsUnsupported = false;\n\n constructor(\n private readonly api: TasksApi,\n private readonly runId: string,\n task: string,\n private readonly logger: Logger,\n tx: Transaction,\n flushIntervalMs?: number,\n cancelCheckIntervalMs?: number\n ) {\n this.flushIntervalMs = flushIntervalMs ?? DEFAULT_LOG_FLUSH_INTERVAL_MS;\n this.cancelCheckIntervalMs = Math.min(\n MAX_CANCEL_CHECK_INTERVAL_MS,\n Math.max(MIN_CANCEL_CHECK_INTERVAL_MS, cancelCheckIntervalMs ?? DEFAULT_CANCEL_CHECK_INTERVAL_MS)\n );\n const log: RunLogger = {\n debug: message => this.log('debug', message),\n info: message => this.log('info', message),\n warn: message => this.log('warning', message),\n error: message => this.log('error', message),\n success: message => this.log('success', message),\n };\n // eventos de transaction/step da run espelham nos logs (o terminal já foi\n // ecoado pelo próprio emit da Transaction — aqui é só buffer/envio)\n tx.setLifecycleSink((level, message) => this.push(level, message));\n const items: RunItems = {\n add: item => this.addItem(item.status, item.message, item.payload, item.id),\n succeeded: (payload, options) => this.addItem('succeeded', undefined, payload, options?.id),\n failed: (message, payload, options) => this.addItem('failed', message, payload, options?.id),\n occurrence: (message, payload, options) => this.addItem('occurrence', message, payload, options?.id),\n };\n const signal = this.abortController.signal;\n this.context = {\n runId,\n task,\n log,\n items,\n tx,\n signal,\n throwIfCanceled: () => {\n if (signal.aborted) throw runCanceledError();\n },\n sleep: ms => cancelableSleep(ms, 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 this.stopCancelWatch(); // o heartbeat só existe para disparar o signal\n if (!this.abortController.signal.aborted) this.abortController.abort();\n }\n\n /**\n * Mata o reporter de vez: aborta o signal e suprime todo reporte futuro.\n * Usado no exit path — depois que o agente reportou AgentTerminated por fora\n * da fila, um handler zumbi não pode reenviar status por cima.\n */\n kill(): void {\n this.abort();\n this.dead = true;\n this.clearFlushTimer();\n this.buffer = [];\n // exit path: diferente dos logs, o volume de itens não justifica salvage best-effort\n this.itemsClosed = true;\n this.clearItemsTimer();\n if (this.itemsBuffer.length > 0) {\n this.logger.warn(`${this.itemsBuffer.length} item(ns) de execução descartados (processo encerrando)`);\n this.itemsBuffer = [];\n }\n // uploads na fila nunca vão rodar: solta quem espera slot para não vazar promises\n const waiting = this.uploadQueue.splice(0, this.uploadQueue.length);\n for (const resume of waiting) resume();\n }\n\n /**\n * Drena o buffer pendente para o PATCH único do exit path (chame ANTES de kill,\n * que descarta o buffer). Capado em um chunk — o exit path não tem retry nem fila,\n * então preserva os logs mais recentes, os mais valiosos na morte do processo.\n */\n drainLogs(): RunLogEntry[] {\n this.clearFlushTimer();\n return this.takeLogs().slice(-MAX_LOGS_PER_PATCH);\n }\n\n private log(level: RunLogLevel, message: string): void {\n if (this.dead) return;\n const scrubbed = scrubSecrets(message);\n printRunLog(this.context.task, level, scrubbed);\n this.push(level, scrubbed, true);\n }\n\n /** Bufferiza uma entrada de log sem eco no terminal (cap, truncate, flush). */\n private push(level: RunLogLevel, message: string, alreadyScrubbed = false, attachments?: string[]): string {\n const ts = nowISO();\n if (this.dead) return ts;\n const scrubbed = alreadyScrubbed ? message : scrubSecrets(message);\n this.buffer.push({\n ts,\n level,\n message: truncate(scrubbed, MAX_LOG_MESSAGE_CHARS),\n ...(attachments && attachments.length > 0 ? { attachments } : {}),\n });\n\n if (this.buffer.length >= FLUSH_AT_BUFFERED) {\n this.flushLogs();\n } else {\n this.scheduleFlush();\n }\n return ts;\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 return this.buffer.splice(0, this.buffer.length);\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 if (!this.dead) this.startCancelWatch();\n return !this.dead;\n }\n\n reportSuccess(): void {\n this.stopCancelWatch();\n this.clearFlushTimer();\n this.enqueue({ status: 'succeeded', logs: this.takeLogs() });\n }\n\n reportFailure(error: RunError): void {\n this.stopCancelWatch();\n this.clearFlushTimer();\n this.enqueue({ status: 'failed', error, logs: this.takeLogs() });\n }\n\n /**\n * Heartbeat de cancelamento: enquanto o handler roda, um PATCH 'running' vazio\n * periódico faz o servidor responder 409 se a run foi cancelada no app — o que\n * mata o reporter e dispara ctx.signal, mesmo em handlers que nunca logam.\n */\n private startCancelWatch(): void {\n if (this.watchTimer) return;\n this.watchTimer = setInterval(() => {\n // já há tráfego a caminho (logs/updates) — ele mesmo detecta o cancelamento\n if (this.dead || this.pendingUpdates > 0 || this.buffer.length > 0) return;\n this.enqueue({ status: 'running' });\n }, this.cancelCheckIntervalMs);\n unrefTimer(this.watchTimer);\n }\n\n private stopCancelWatch(): void {\n if (this.watchTimer) {\n clearInterval(this.watchTimer);\n this.watchTimer = undefined;\n }\n }\n\n /** Aguarda a fila de PATCHes esvaziar (chame depois do terminal). */\n finalize(): Promise<void> {\n return this.chain;\n }\n\n // ── Itens de execução ────────────────────────────────────────────────────────\n\n /**\n * Bufferiza um item (síncrono — a chamada nunca espera rede). Diferente do PATCH\n * de status, o servidor aceita itens mesmo com a run cancelada (trabalho já feito),\n * então um reporter morto não descarta: só um kill() de exit path descarta.\n */\n private addItem(\n status: RunItemStatus,\n message: string | undefined,\n payload: Record<string, unknown> | undefined,\n id: string | undefined\n ): void {\n if (this.itemsClosed || this.itemsUnsupported) return;\n if (this.itemCount >= MAX_ITEMS_PER_RUN) {\n if (!this.itemsQuotaExceeded) {\n this.itemsQuotaExceeded = true;\n this.log('warning', `itens descartados: limite de ${MAX_ITEMS_PER_RUN} por execução atingido`);\n }\n return;\n }\n this.itemCount++;\n\n let scrubbedPayload: Record<string, unknown> | undefined;\n if (payload) {\n scrubbedPayload = scrubPayloadValue(payload, 0) as Record<string, unknown>;\n let serializedLength: number | undefined;\n try {\n serializedLength = JSON.stringify(scrubbedPayload).length;\n } catch {\n // payload circular/não-serializável — sem ele o item ainda vale pelo status\n }\n if (serializedLength === undefined || serializedLength > MAX_ITEM_PAYLOAD_BYTES) {\n this.logger.warn(\n `payload do item descartado (${serializedLength === undefined ? 'não serializável' : `${serializedLength} bytes > ${MAX_ITEM_PAYLOAD_BYTES}`}) — o item foi mantido`\n );\n scrubbedPayload = undefined;\n }\n }\n\n this.itemsBuffer.push({\n id: id ? truncate(String(id), 255) : uuid4(),\n seq: this.itemSeq++,\n status,\n ...(message ? { message: truncate(scrubSecrets(message), MAX_ITEM_MESSAGE_CHARS) } : {}),\n ...(scrubbedPayload ? { payload: scrubbedPayload } : {}),\n ts: nowISO(),\n });\n\n if (this.itemsBuffer.length >= ITEMS_FLUSH_AT_BUFFERED) {\n this.flushItems();\n } else {\n this.scheduleItemsFlush();\n }\n }\n\n private scheduleItemsFlush(): void {\n if (this.itemsTimer) return;\n this.itemsTimer = setTimeout(() => {\n this.itemsTimer = undefined;\n this.flushItems();\n }, this.flushIntervalMs);\n unrefTimer(this.itemsTimer);\n }\n\n private clearItemsTimer(): void {\n if (this.itemsTimer) {\n clearTimeout(this.itemsTimer);\n this.itemsTimer = undefined;\n }\n }\n\n /** Envia o buffer de itens em lotes serializados na cadeia própria. */\n private flushItems(): void {\n this.clearItemsTimer();\n if (this.itemsBuffer.length === 0 || this.itemsUnsupported) return;\n const items = this.itemsBuffer.splice(0, this.itemsBuffer.length);\n for (let i = 0; i < items.length; i += MAX_ITEMS_PER_REQUEST) {\n const batch = items.slice(i, i + MAX_ITEMS_PER_REQUEST);\n this.itemsChain = this.itemsChain.then(() => this.sendItems(batch));\n }\n }\n\n private async sendItems(batch: RunItemInput[]): Promise<void> {\n if (this.itemsUnsupported) return;\n try {\n await this.api.createItems(this.runId, { items: batch });\n } catch (error) {\n if (error instanceof TasksApiError && error.status === 404) {\n // servidor anterior ao recurso (ou run apagada) — degrada em silêncio daqui em diante\n this.itemsUnsupported = true;\n this.logger.warn('itens de execução não são suportados por este servidor Hobots — descartados');\n return;\n }\n if (error instanceof TasksApiError && error.status === 429) {\n if (!this.itemsQuotaExceeded) {\n this.itemsQuotaExceeded = true;\n this.log('warning', 'itens descartados: limite de itens por execução atingido no servidor');\n }\n return;\n }\n if (error instanceof TasksApiError) {\n // 4xx definitivo (payload rejeitado) — reenviar não vai mudar o resultado\n this.logger.error(`lote de ${batch.length} item(ns) rejeitado pelo servidor:`, error);\n return;\n }\n // rede/5xx com retries esgotados: devolve ao buffer para a próxima tentativa\n this.itemsBuffer.unshift(...batch);\n this.scheduleItemsFlush();\n this.logger.error(`lote de ${batch.length} item(ns) não enviado (devolvido ao buffer):`, error);\n }\n }\n\n /**\n * Dreno final de itens antes do PATCH terminal (com teto): garante que os\n * totalizadores estejam completos quando a run vira succeeded/failed. Como o\n * servidor aceita itens tardios, perder a corrida aqui não perde dados.\n */\n async finalizeItems(timeoutMs = ITEMS_DRAIN_MS): Promise<void> {\n this.flushItems();\n await Promise.race([\n this.itemsChain,\n new Promise<void>(resolve => unrefTimer(setTimeout(resolve, timeoutMs))),\n ]);\n if (this.itemsBuffer.length > 0 && !this.itemsUnsupported && !this.itemsQuotaExceeded) {\n // sobrou lote devolvido por falha de rede — última tentativa antes do terminal\n this.flushItems();\n await Promise.race([\n this.itemsChain,\n new Promise<void>(resolve => unrefTimer(setTimeout(resolve, timeoutMs))),\n ]);\n }\n }\n\n // ── Anexos ───────────────────────────────────────────────────────────────────\n\n /**\n * Registra a linha de log com o id do anexo (síncrono, na ordem certa) e dispara\n * o upload em segundo plano. Nunca lança: todo caminho de erro vira `{ ok: false }`\n * com um aviso no log da run. Chega ao handler pelos capture* do SDK — o hint\n * `attachment` de Hobots.captureException/captureMessage cai aqui via run-context-store.\n */\n async attach(image: AttachInput, options: AttachOptions = {}): Promise<AttachResult> {\n const id = uuid4();\n const level = options.level ?? 'info';\n const caption = options.caption ? truncate(scrubSecrets(options.caption), MAX_CAPTION_CHARS) : undefined;\n const message = options.message ?? options.caption ?? 'captura de tela';\n\n if (this.dead) return { id, ok: false, reason: 'canceled' };\n if (this.attachmentsUnsupported) {\n // já avisamos uma vez nesta run — registra só a linha de log, sem anexo\n this.log(level, message);\n return { id, ok: false, reason: 'unsupported' };\n }\n if (this.attachmentCount >= MAX_ATTACHMENTS_PER_RUN) {\n this.log(level, message);\n this.log('warning', `anexo descartado: limite de ${MAX_ATTACHMENTS_PER_RUN} por execução atingido`);\n return { id, ok: false, reason: 'quota' };\n }\n this.attachmentCount++;\n\n // A linha de log entra ANTES de qualquer I/O — é isso que mantém a ordem dos\n // logs intacta e o handler livre da latência do upload.\n const scrubbed = scrubSecrets(message);\n printRunLog(this.context.task, level, `${scrubbed} [imagem]`);\n const logTs = this.push(level, scrubbed, true, [id]);\n\n let settle!: (result: AttachResult) => void;\n const result = new Promise<AttachResult>(resolve => {\n settle = resolve;\n });\n const work = this.uploadAttachment(id, image, { caption, logTs, contentType: options.contentType })\n .then(reason => settle(reason ? { id, ok: false, reason } : { id, ok: true }))\n .catch(() => settle({ id, ok: false, reason: 'upload-failed' }));\n this.pendingAttachments.add(work);\n void work.finally(() => this.pendingAttachments.delete(work));\n\n return result;\n }\n\n /** Retorna o motivo da falha, ou undefined em sucesso. */\n private async uploadAttachment(\n id: string,\n image: AttachInput,\n meta: { caption?: string; logTs: string; contentType?: RunAttachmentContentType }\n ): Promise<AttachFailureReason | undefined> {\n let bytes: Uint8Array;\n try {\n bytes = await toBytes(image);\n } catch (error) {\n this.log('warning', `anexo não pôde ser lido: ${String(error)}`);\n return 'read-failed';\n }\n\n // magic bytes ganham do que o chamador declarou — o S3 rejeita a assinatura se divergir\n const contentType = sniffContentType(bytes) ?? meta.contentType;\n if (!contentType) {\n this.log('warning', 'anexo descartado: formato não reconhecido (aceitos: PNG, JPEG, WEBP)');\n return 'unsupported-format';\n }\n if (bytes.byteLength > MAX_ATTACHMENT_BYTES) {\n this.log(\n 'warning',\n `anexo descartado: ${Math.round(bytes.byteLength / 1024)} KB excede o limite de ${MAX_ATTACHMENT_BYTES / 1024 / 1024} MB`\n );\n return 'too-large';\n }\n\n const dimensions = readPngDimensions(bytes);\n const release = await this.acquireUploadSlot();\n try {\n if (this.abortController.signal.aborted || this.dead) return 'canceled';\n const created = await this.api.createAttachment(\n this.runId,\n {\n id,\n content_type: contentType,\n size_bytes: bytes.byteLength,\n log_ts: meta.logTs,\n ...(meta.caption ? { caption: meta.caption } : {}),\n ...(dimensions ?? {}),\n },\n this.abortController.signal\n );\n await this.api.uploadAttachment(created.upload_url, created.headers, bytes, this.abortController.signal);\n // confirmação é conforto de UX (some o placeholder \"enviando…\"): falha não invalida o upload\n await this.api\n .confirmAttachment(this.runId, id, { status: 'uploaded', size_bytes: bytes.byteLength, ...(dimensions ?? {}) })\n .catch(() => {});\n return undefined;\n } catch (error) {\n if (this.isUnsupported(error)) {\n this.attachmentsUnsupported = true;\n this.log('warning', 'anexos não estão habilitados nesta instalação do Hobots — imagem não enviada');\n return 'unsupported';\n }\n if (error instanceof TasksApiError && error.status === 429) {\n this.log('warning', 'anexo descartado: limite de anexos por execução atingido no servidor');\n return 'quota';\n }\n if (this.abortController.signal.aborted) return 'canceled';\n this.log('warning', `falha ao enviar o anexo: ${String(error)}`);\n void this.api.confirmAttachment(this.runId, id, { status: 'failed' }).catch(() => {});\n return 'upload-failed';\n } finally {\n release();\n }\n }\n\n /** 404 = API anterior ao recurso; 501/503 = instalação sem S3 configurado. */\n private isUnsupported(error: unknown): boolean {\n return error instanceof TasksApiError && (error.status === 404 || error.status === 501 || error.status === 503);\n }\n\n /** Semáforo simples: no máximo MAX_CONCURRENT_UPLOADS binários em voo por run. */\n private acquireUploadSlot(): Promise<() => void> {\n const release = (): void => {\n const next = this.uploadQueue.shift();\n if (next) next();\n else this.uploadSlots++;\n };\n if (this.uploadSlots > 0) {\n this.uploadSlots--;\n return Promise.resolve(release);\n }\n return new Promise<() => void>(resolve => {\n this.uploadQueue.push(() => resolve(release));\n });\n }\n\n /**\n * Espera os uploads pendentes antes do PATCH terminal, para a run não terminar\n * exibindo miniaturas em \"enviando…\". Capado: um upload lento não segura a run.\n */\n async finalizeAttachments(timeoutMs = ATTACHMENT_DRAIN_MS): Promise<void> {\n if (this.pendingAttachments.size === 0) return;\n await Promise.race([\n Promise.allSettled([...this.pendingAttachments]),\n new Promise<void>(resolve => unrefTimer(setTimeout(resolve, timeoutMs))),\n ]);\n }\n\n private enqueue(update: RunUpdateRequest): void {\n if (this.dead) {\n this.salvageLogs(update.logs);\n return;\n }\n this.pendingUpdates++;\n this.chain = this.chain.then(async () => {\n if (this.dead) {\n // update enfileirado atrás do PATCH que morreu (ex.: chunks de flush): logs seguem tardios\n this.salvageLogs(update.logs);\n return;\n }\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 TasksApiError && (error.status === 409 || error.status === 404)) {\n this.dead = true;\n this.stopCancelWatch();\n this.abort();\n // os logs deste payload já foram anexados pelo servidor (append tardio no 409);\n // o que resta no buffer segue best-effort pelo mesmo caminho\n const pending = this.buffer.splice(0, this.buffer.length);\n this.salvageLogs(pending);\n this.logger.warn(\n `run ${this.runId} cancelada/finalizada no servidor — status suprimido` +\n (pending.length > 0 ? `, ${pending.length} log(s) enviados como log tardio` : '')\n );\n return;\n }\n // rede/5xx com retries esgotados: devolve os logs ao buffer para o próximo PATCH\n if (update.logs && update.logs.length > 0) {\n this.buffer.unshift(...update.logs);\n this.scheduleFlush();\n }\n this.logger.error(`update da run ${this.runId} perdido:`, error);\n }\n }).finally(() => {\n this.pendingUpdates--;\n });\n }\n\n /**\n * Best-effort de log tardio: envia logs para uma run já terminal, fora da fila.\n * O servidor anexa os logs mesmo respondendo 409; erros são engolidos — este é\n * o último recurso, não um canal confiável.\n */\n private salvageLogs(logs: RunLogEntry[] | undefined): void {\n if (!logs || logs.length === 0) return;\n for (let i = 0; i < logs.length; i += MAX_LOGS_PER_PATCH) {\n void this.api\n .updateRunOnce(this.runId, { status: 'running', logs: logs.slice(i, i + MAX_LOGS_PER_PATCH) })\n .catch(() => {});\n }\n }\n}\n","import type { AsyncLocalStorage } from 'node:async_hooks';\n\nimport { isNode } from '../utils';\nimport type { Transaction } from '../transaction';\nimport type { AttachInput, AttachOptions, AttachResult } from './attachments';\n\nexport type RunAttach = (image: AttachInput, options?: AttachOptions) => Promise<AttachResult>;\n\ninterface RunStore {\n runId: string;\n /** Transaction da run (ctx.tx) — a única transaction da execução. */\n tx: Transaction;\n /** Anexa uma imagem a uma linha de log da run — a ponte dos capture* até o reporter. */\n attach: RunAttach;\n}\n\n// Inicializado sob demanda só em Node (import dinâmico → não entra no bundle do browser).\n// import type acima é apagado em compilação, então não há import estático de node:async_hooks.\nlet storage: AsyncLocalStorage<RunStore> | undefined;\nlet initPromise: Promise<void> | undefined;\n\nasync function ensureStorage(): Promise<void> {\n if (storage || !isNode()) return;\n initPromise ??= import('node:async_hooks').then(({ AsyncLocalStorage: ALS }) => {\n storage = new ALS<RunStore>();\n });\n await initPromise;\n}\n\n/**\n * Executa `fn` com a run ativa no contexto async atual. Qualquer chamada a\n * Hobots.startTransaction() por dentro reutiliza a transaction da run (ctx.tx) —\n * a execução tem sempre UMA transaction, com as steps do handler no waterfall.\n */\nexport async function runWithRunContext<T>(store: RunStore, fn: () => Promise<T>): Promise<T> {\n await ensureStorage();\n return storage ? storage.run(store, fn) : fn();\n}\n\n/** Transaction da run em execução no contexto async atual, se houver. */\nexport function currentRunTransaction(): Transaction | undefined {\n return storage?.getStore()?.tx;\n}\n\n/** Pipeline de anexos da run em execução no contexto async atual, se houver. */\nexport function currentRunAttach(): RunAttach | undefined {\n return storage?.getStore()?.attach;\n}\n","import type { TaskAgent } from './agent';\nimport { hasInstalledGlobalHandlers } from '../instrument';\nimport { addEmergencyTask, externalListenerCount, markInternal } from '../internal-handlers';\nimport { isNode } from '../utils';\n\nconst WATCHED_SIGNALS = ['SIGINT', 'SIGTERM'] as const;\ntype WatchedSignal = (typeof WATCHED_SIGNALS)[number];\n\n/**\n * Rede de segurança do agente: quando o processo morre (sinal ou erro não tratado)\n * com runs em execução, tenta reportar 'failed'/AgentTerminated antes de sair —\n * assim o app mostra a falha na hora, sem esperar o sweep server-side (~60s).\n *\n * Nunca interfere no shutdown gracioso: se o programa tem handler próprio para o\n * sinal (ex: SIGINT → close()), o SDK fica quieto e deixa o caminho normal reportar.\n */\nexport function installShutdownHandlers(agent: TaskAgent): () => void {\n if (!isNode()) return () => {};\n\n let signaled = false;\n const signalHandlers = new Map<WatchedSignal, () => void>();\n\n for (const signal of WATCHED_SIGNALS) {\n const handler = markInternal(() => {\n // o programa tem handler próprio (shutdown gracioso) — o caminho normal reporta\n if (externalListenerCount(signal) > 0) return;\n if (signaled) return;\n signaled = true;\n\n const reraise = (): void => {\n process.removeListener(signal, handler);\n process.kill(process.pid, signal); // exit default do sinal (código 130/143)\n };\n if (agent.activeCount === 0) {\n reraise();\n return;\n }\n const report = agent.reportAgentTerminated(`o processo do agente recebeu ${signal} durante a execução`);\n addEmergencyTask(report);\n void report.finally(reraise);\n });\n process.on(signal, handler);\n signalHandlers.set(signal, handler);\n }\n\n const onFatal = markInternal((error: Error) => {\n const report =\n agent.activeCount > 0\n ? agent.reportAgentTerminated('o processo do agente morreu com um erro não tratado durante a execução')\n : Promise.resolve();\n addEmergencyTask(report);\n // o exit é decidido pelo instrument (captureUnhandled) ou pelo handler do programa;\n // sem nenhum dos dois, preservamos o comportamento default do Node aqui\n if (!hasInstalledGlobalHandlers() && externalListenerCount('uncaughtException') === 0) {\n void report.finally(() => {\n console.error(error);\n process.exit(1);\n });\n }\n });\n process.on('uncaughtException', onFatal);\n\n return () => {\n for (const [signal, handler] of signalHandlers) process.removeListener(signal, handler);\n process.removeListener('uncaughtException', onFatal);\n };\n}\n","import type { RunDescriptor, RunError } from './protocol';\nimport type { TaskAgentOptions, TaskHandler } from './types';\nimport { TasksApi, TasksApiError } from './api';\nimport { RunReporter } from './context';\nimport { runWithRunContext } from './run-context-store';\nimport { installShutdownHandlers } from './shutdown';\nimport { Transaction } from '../transaction';\nimport { isNode, jitter, makeLogger, sleep, truncate, SDK_VERSION, type Logger } from '../utils';\nimport { scrubSecrets } from '../scrub';\nimport type { Client } from '../client';\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;\nconst DEFAULT_CANCEL_GRACE_MS = 10_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 de tasks: busca runs pendentes, executa os handlers registrados\n * e reporta status/logs/result. Ao contrário da Telemetria, o timer de polling NÃO é\n * unref'd — um agente iniciado mantém o processo vivo até stop().\n */\nexport class TaskAgent {\n readonly logger: Logger;\n\n private readonly api: TasksApi;\n private readonly client: Client | undefined;\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 private readonly cancelCheckIntervalMs?: number;\n private readonly cancelGraceMs: 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 private uninstallShutdown: (() => void) | undefined;\n\n constructor(\n private readonly options: TaskAgentOptions,\n private readonly registry: Map<string, TaskHandler>\n ) {\n this.logger = makeLogger(options.debug ?? false);\n const config = options.config;\n this.api = new TasksApi({ baseUrl: config.tasksBaseUrl, key: config.key, logger: this.logger });\n this.client = options.client;\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.cancelCheckIntervalMs = options.cancelCheckIntervalMs;\n this.cancelGraceMs = options.cancelGraceMs ?? DEFAULT_CANCEL_GRACE_MS;\n this.logger.debug('agente configurado', { baseUrl: config.tasksBaseUrl });\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] start() chamado durante stop() — aguarde o stop terminar');\n }\n if (this.registry.size === 0) {\n throw new Error('[hobots] nenhuma task registrada — chame register() antes de start()');\n }\n this.state = 'started';\n if (this.options.installExitHandlers !== false && !this.uninstallShutdown) {\n this.uninstallShutdown = installShutdownHandlers(this);\n }\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 // o processo vai morrer com as runs no meio: falha imediata no app em vez\n // de esperar o sweep server-side marcar o encerramento inesperado\n await this.reportAgentTerminated('agente encerrado durante a execução (shutdown excedeu o tempo de espera)');\n }\n this.uninstallShutdown?.();\n this.uninstallShutdown = undefined;\n this.state = 'idle';\n return finished;\n }\n\n /**\n * Best-effort do exit path: reporta 'failed'/AgentTerminated para as runs ativas\n * antes do processo morrer, fora da fila do reporter e com timeout curto. Runs já\n * canceladas no app (reporter morto) são puladas; erros de rede são engolidos —\n * o sweep server-side é o backstop.\n */\n async reportAgentTerminated(message: string, timeoutMs = 2_500): Promise<void> {\n const pending: Promise<void>[] = [];\n for (const reporter of this.reporters) {\n if (reporter.isDead) continue;\n // drena os logs pendentes antes do kill (que descarta o buffer) e mata o\n // reporter: o handler zumbi não pode reenviar status por cima do failed\n const logs = reporter.drainLogs();\n reporter.kill();\n pending.push(\n this.api\n .updateRunOnce(\n reporter.context.runId,\n { status: 'failed', error: { type: 'AgentTerminated', message }, logs: logs.length > 0 ? logs : undefined },\n timeoutMs\n )\n .catch(() => {})\n );\n }\n if (pending.length === 0) return;\n await Promise.race([Promise.allSettled(pending), sleep(timeoutMs)]);\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 instance: {\n // identidade canônica do agente no painel — o mesmo instanceId do\n // heartbeat da Telemetria, 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 // o servidor calcula a tolerância de offline (3×) a partir disto em\n // agentes poll-only — sem o campo, um poll lento flaparia offline/online.\n // Clampado à faixa aceita pelo schema do poll (1s..15min).\n poll_interval_ms: Math.min(Math.max(this.pollIntervalMs, 1_000), 900_000),\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 // defesa em profundidade: nunca exceder a concorrência, mesmo com resposta acima do max\n if (this.activeRuns.size >= this.concurrency) break;\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 TasksApiError && 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 agente em Configurações → Agentes');\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(jitter(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: RunDescriptor): 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: RunDescriptor): Promise<void> {\n // correlacionada à run via run_id — as steps que o handler criar em ctx.tx.startChild()\n // viram o waterfall de performance da execução no dashboard\n const tx = new Transaction(this.client, `run:${run.task}`, 'hobots.task', true, run.id);\n const reporter = new RunReporter(this.api, run.id, run.task, this.logger, tx, this.logFlushIntervalMs, this.cancelCheckIntervalMs);\n this.reporters.add(reporter);\n\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 tx.setStatus('error');\n tx.finish();\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 tx.setStatus('cancelled');\n tx.finish();\n return;\n }\n\n this.logger.debug(`executando run ${run.id} (${run.task})`);\n try {\n // corre dentro do contexto de run: startTransaction() no handler reutiliza a tx da run\n // e o hint `attachment` dos capture* chega ao pipeline de anexos desta run\n await runWithRunContext(\n { runId: run.id, tx, attach: (image, options) => reporter.attach(image, options) },\n () => this.invokeWithTimeout(handler, run, reporter)\n );\n // anexos disparados sem await (fire-and-forget) ainda podem estar subindo:\n // espera (com teto) para a run não terminar com miniaturas em \"enviando…\"\n await reporter.finalizeAttachments();\n // dreno dos itens antes do terminal: os totalizadores da run ficam completos\n // quando ela vira succeeded (itens tardios ainda são aceitos se perder a corrida)\n await reporter.finalizeItems();\n // finish antes do terminal: as linhas FINISH de tx/steps entram no mesmo PATCH\n tx.setStatus('ok');\n tx.finish();\n reporter.reportSuccess();\n this.logger.debug(`run ${run.id} concluída`);\n } catch (error) {\n // uma falha é justamente quando o print importa — vale esperar o upload aqui também\n await reporter.finalizeAttachments();\n // itens já processados antes da falha fazem parte da entrega — drena antes do terminal\n await reporter.finalizeItems();\n tx.setStatus('error');\n tx.finish();\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(handler: TaskHandler, run: RunDescriptor, reporter: RunReporter): Promise<void> {\n const invocation = Promise.resolve().then(() => handler(run.params, reporter.context));\n const races: Promise<typeof TIMEOUT_SENTINEL | typeof CANCEL_SENTINEL>[] = [];\n if (this.taskTimeoutMs && this.taskTimeoutMs > 0) {\n races.push(sleep(this.taskTimeoutMs).then(() => TIMEOUT_SENTINEL));\n }\n if (this.cancelGraceMs > 0) {\n races.push(waitForCancelGrace(reporter.context.signal, this.cancelGraceMs).then(() => CANCEL_SENTINEL));\n }\n if (races.length === 0) {\n await invocation;\n return;\n }\n\n const outcome = await Promise.race([invocation, ...races]);\n if (outcome !== TIMEOUT_SENTINEL && outcome !== CANCEL_SENTINEL) return; // invocation venceu a corrida\n\n if (outcome === CANCEL_SENTINEL) {\n // run já cancelada no app (409) há cancelGraceMs — o handler não respondeu a\n // ctx.signal a tempo; não dá para matar o código do usuário, então o agente\n // para de esperar e libera o slot. Reportes subsequentes são no-op (reporter morto).\n this.logger.warn(\n `run ${run.id} cancelada — handler não respondeu a ctx.signal em ${this.cancelGraceMs}ms, ` +\n 'liberando o slot (o handler pode continuar rodando em segundo plano)'\n );\n return;\n }\n\n // TIMEOUT_SENTINEL: não dá para matar o código do usuário — reporta, aborta o signal e libera o slot\n const timeoutMs = this.taskTimeoutMs!;\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');\nconst CANCEL_SENTINEL = Symbol('task-canceled');\n\n/** Resolve só depois que `signal` abortar + `graceMs` — nunca resolve se o signal nunca disparar. */\nfunction waitForCancelGrace(signal: AbortSignal, graceMs: number): Promise<void> {\n return new Promise<void>(resolve => {\n if (signal.aborted) {\n setTimeout(resolve, graceMs);\n return;\n }\n signal.addEventListener('abort', () => setTimeout(resolve, graceMs), { once: true });\n });\n}\n\nconst MAX_ERROR_MESSAGE_CHARS = 10_000;\nconst MAX_ERROR_STACK_CHARS = 20_000;\n\nfunction toRunError(error: unknown): RunError {\n if (error instanceof Error) {\n return {\n type: error.name,\n message: scrubSecrets(truncate(error.message, MAX_ERROR_MESSAGE_CHARS)),\n stack: error.stack ? scrubSecrets(truncate(error.stack, MAX_ERROR_STACK_CHARS)) : undefined,\n };\n }\n return { message: scrubSecrets(truncate(String(error), MAX_ERROR_MESSAGE_CHARS)) };\n}\n","import type { EventUser, Severity } from './protocol';\nimport type { CaptureAttachment, 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 { TaskAgent } from './tasks/agent';\nimport type { AttachInput } from './tasks/attachments';\nimport type { RunLogLevel } from './tasks/protocol';\nimport { currentRunAttach, currentRunTransaction } from './tasks/run-context-store';\nimport type { TaskHandler } from './tasks/types';\nimport { resolveConfig } from './config';\n\nconst DEFAULT_MAX_BREADCRUMBS = 100;\n\nlet client: Client | undefined;\nlet scope = new Scope();\nlet heartbeat: Heartbeat | undefined;\nlet agent: TaskAgent | undefined;\nconst registry = new Map<string, TaskHandler>();\nlet warnedTasksDisabled = 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 warnedTasksDisabled = false;\n\n // resolvida uma única vez por init() — Client e TaskAgent recebem a mesma config\n const config = resolveConfig(options);\n client = new Client(options, config);\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.tasks) {\n const tasksOptions = options.tasks === true ? {} : options.tasks;\n agent = new TaskAgent(\n { ...tasksOptions, config, instanceId: options.instanceId, debug: options.debug, client },\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/** O log da run não tem 'fatal' — rebaixa para 'error'. */\nfunction toRunLogLevel(level: Severity): RunLogLevel {\n return level === 'fatal' ? 'error' : level;\n}\n\n/**\n * Encaminha o `attachment` de um capture* para o pipeline de anexos da run ativa\n * (fire-and-forget): a imagem vira anexo da linha de log que espelha o evento.\n * Fora de uma execução de task não há onde pendurar a imagem — descarta com aviso.\n */\nfunction forwardAttachment(attachment: AttachInput | CaptureAttachment, message: string, level: Severity): void {\n const attach = currentRunAttach();\n if (!attach) {\n client?.logger.warn('attachment descartado — só é suportado dentro de uma execução de task (register/start)');\n return;\n }\n const withMeta = typeof attachment === 'object' && 'image' in attachment ? attachment : { image: attachment };\n void attach(withMeta.image, {\n message,\n level: toRunLogLevel(level),\n caption: withMeta.caption,\n contentType: withMeta.contentType,\n });\n}\n\n/**\n * Captura uma exceção e retorna o event_id (undefined se o SDK não foi inicializado).\n * `hint.attachment` envia um print junto — dentro de uma execução de task, ele aparece\n * como miniatura na linha de log da run correspondente ao erro.\n */\nexport function captureException(error: unknown, hint?: CaptureHint): string | undefined {\n if (hint?.attachment) {\n const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);\n forwardAttachment(hint.attachment, message, hint.level ?? 'error');\n }\n return client?.captureException(error, hint, scope);\n}\n\nexport function captureMessage(message: string, level: Severity = 'info', hint?: CaptureHint): string | undefined {\n if (hint?.attachment) {\n forwardAttachment(hint.attachment, message, hint.level ?? level);\n }\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 // dentro de um handler, a execução já tem a sua transaction (ctx.tx) —\n // reutiliza em vez de criar uma segunda com o mesmo run_id\n const active = currentRunTransaction();\n if (active) {\n client?.logger.debug(`startTransaction('${name}') dentro de uma execução — reutilizando a transaction da run`);\n return active;\n }\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/** 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 (o task_slug configurado no formulário do app, em Configurações → Formulários). */\nexport function register<P = Record<string, unknown>>(task: string, handler: TaskHandler<P>): void {\n if (registry.has(task)) {\n (agent?.logger ?? client?.logger)?.warn(`register('${task}') sobrescreveu um handler existente`);\n }\n if (client && !agent && !warnedTasksDisabled) {\n warnedTasksDisabled = true;\n client.logger.warn(\n `register('${task}') com tasks desabilitadas — passe tasks: true (ou opções) no init()`\n );\n }\n registry.set(task, handler as TaskHandler);\n}\n\n/**\n * Inicia o polling de tasks. O timer NÃO é unref'd: o processo fica vivo\n * aguardando trabalho até stop()/close() — o inverso deliberado da telemetria.\n */\nexport function start(): void {\n if (!agent) {\n throw new Error('[hobots] tasks não configuradas — passe tasks: true (ou opções) no init() antes de start()');\n }\n agent.start();\n}\n\n/** Para só o polling de tasks 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 polling de tasks (aguardando runs em voo), o heartbeat\n * e faz o 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":["hostname","scope","client","client","client","agent","registry"]}