hobots 1.7.2 → 1.7.4

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.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { Breadcrumb, EventUser, Severity, EventPayload, TransactionPayload, CheckInPayload, HeartbeatPayload, SpanStatus, SpanData, CheckInStatus } from './protocol.cjs';
2
- export { AgentInfo, Envelope, EnvelopeItem, ExceptionData, PollRequest, PollResponse, RunDescriptor, RunError, RunLogEntry, RunLogLevel, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame } from './protocol.cjs';
1
+ import { Breadcrumb, EventUser, Severity, EventPayload, TransactionPayload, CheckInPayload, HeartbeatPayload, RunLogLevel, SpanStatus, SpanData, CheckInStatus } from './protocol.cjs';
2
+ export { AgentInfo, Envelope, EnvelopeItem, ExceptionData, PollRequest, PollResponse, RunDescriptor, RunError, RunLogEntry, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame } from './protocol.cjs';
3
3
 
4
4
  /** API oficial da Hobots — o SDK sempre fala com ela em produção. */
5
5
  declare const DEFAULT_BASE_URL = "https://api2.hobots.app";
@@ -64,6 +64,8 @@ declare class Client {
64
64
  close(timeoutMs?: number): Promise<boolean>;
65
65
  }
66
66
 
67
+ /** Recebe os eventos de lifecycle da transaction para espelhá-los nos logs da run. */
68
+ type LifecycleSink = (level: RunLogLevel, message: string) => void;
67
69
  declare class Span {
68
70
  private readonly transaction;
69
71
  readonly parentSpanId: string;
@@ -100,9 +102,19 @@ declare class Transaction {
100
102
  private readonly spans;
101
103
  private readonly tags;
102
104
  private finished;
105
+ private lifecycleSink?;
106
+ private lifecycleBacklog;
103
107
  constructor(client: Client | undefined, name: string, op?: string | undefined, sampled?: boolean,
104
108
  /** Correlaciona a uma execução de task — preenchido automaticamente em ctx.tx */
105
109
  runId?: string | undefined);
110
+ /**
111
+ * Ecoa no terminal o início/fim de um span ou transaction (sempre, independente de
112
+ * sampling ou do debug) e espelha a linha no sink de lifecycle, se conectado — é
113
+ * assim que os eventos de performance também aparecem nos logs da run no app.
114
+ */
115
+ emit(kind: 'transaction' | 'span', phase: 'start' | 'finish', label: string, startTs?: string, endTs?: string): void;
116
+ /** Conecta o espelho de lifecycle (RunReporter) e faz replay do backlog em ordem. */
117
+ setLifecycleSink(sink: LifecycleSink): void;
106
118
  createSpan(parentSpanId: string, op?: string, description?: string): Span;
107
119
  /** Span direto da transaction. */
108
120
  startChild(op?: string, description?: string): Span;
@@ -272,4 +284,4 @@ declare function close(timeoutMs?: number): Promise<boolean>;
272
284
 
273
285
  declare function scrubSecrets(text: string): string;
274
286
 
275
- export { Breadcrumb, type BreadcrumbInput, type CaptureHint, type CheckInOptions, CheckInPayload, CheckInStatus, Client, DEFAULT_BASE_URL, EventPayload, EventUser, type HeartbeatOptions, HeartbeatPayload, type InitOptions, type RunContext, Scope, Severity, Span, SpanData, type TaskHandler, type TasksOptions, Transaction, TransactionPayload, type WithMonitorOptions, addBreadcrumb, captureException, captureMessage, checkIn, close, flush, getClient, init, register, scrubSecrets, setContext, setExtra, setTag, setTags, setUser, start, startTransaction, stop, withMonitor, withScope };
287
+ export { Breadcrumb, type BreadcrumbInput, type CaptureHint, type CheckInOptions, CheckInPayload, CheckInStatus, Client, DEFAULT_BASE_URL, EventPayload, EventUser, type HeartbeatOptions, HeartbeatPayload, type InitOptions, type RunContext, RunLogLevel, Scope, Severity, Span, SpanData, type TaskHandler, type TasksOptions, Transaction, TransactionPayload, type WithMonitorOptions, addBreadcrumb, captureException, captureMessage, checkIn, close, flush, getClient, init, register, scrubSecrets, setContext, setExtra, setTag, setTags, setUser, start, startTransaction, stop, withMonitor, withScope };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Breadcrumb, EventUser, Severity, EventPayload, TransactionPayload, CheckInPayload, HeartbeatPayload, SpanStatus, SpanData, CheckInStatus } from './protocol.js';
2
- export { AgentInfo, Envelope, EnvelopeItem, ExceptionData, PollRequest, PollResponse, RunDescriptor, RunError, RunLogEntry, RunLogLevel, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame } from './protocol.js';
1
+ import { Breadcrumb, EventUser, Severity, EventPayload, TransactionPayload, CheckInPayload, HeartbeatPayload, RunLogLevel, SpanStatus, SpanData, CheckInStatus } from './protocol.js';
2
+ export { AgentInfo, Envelope, EnvelopeItem, ExceptionData, PollRequest, PollResponse, RunDescriptor, RunError, RunLogEntry, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame } from './protocol.js';
3
3
 
4
4
  /** API oficial da Hobots — o SDK sempre fala com ela em produção. */
5
5
  declare const DEFAULT_BASE_URL = "https://api2.hobots.app";
@@ -64,6 +64,8 @@ declare class Client {
64
64
  close(timeoutMs?: number): Promise<boolean>;
65
65
  }
66
66
 
67
+ /** Recebe os eventos de lifecycle da transaction para espelhá-los nos logs da run. */
68
+ type LifecycleSink = (level: RunLogLevel, message: string) => void;
67
69
  declare class Span {
68
70
  private readonly transaction;
69
71
  readonly parentSpanId: string;
@@ -100,9 +102,19 @@ declare class Transaction {
100
102
  private readonly spans;
101
103
  private readonly tags;
102
104
  private finished;
105
+ private lifecycleSink?;
106
+ private lifecycleBacklog;
103
107
  constructor(client: Client | undefined, name: string, op?: string | undefined, sampled?: boolean,
104
108
  /** Correlaciona a uma execução de task — preenchido automaticamente em ctx.tx */
105
109
  runId?: string | undefined);
110
+ /**
111
+ * Ecoa no terminal o início/fim de um span ou transaction (sempre, independente de
112
+ * sampling ou do debug) e espelha a linha no sink de lifecycle, se conectado — é
113
+ * assim que os eventos de performance também aparecem nos logs da run no app.
114
+ */
115
+ emit(kind: 'transaction' | 'span', phase: 'start' | 'finish', label: string, startTs?: string, endTs?: string): void;
116
+ /** Conecta o espelho de lifecycle (RunReporter) e faz replay do backlog em ordem. */
117
+ setLifecycleSink(sink: LifecycleSink): void;
106
118
  createSpan(parentSpanId: string, op?: string, description?: string): Span;
107
119
  /** Span direto da transaction. */
108
120
  startChild(op?: string, description?: string): Span;
@@ -272,4 +284,4 @@ declare function close(timeoutMs?: number): Promise<boolean>;
272
284
 
273
285
  declare function scrubSecrets(text: string): string;
274
286
 
275
- export { Breadcrumb, type BreadcrumbInput, type CaptureHint, type CheckInOptions, CheckInPayload, CheckInStatus, Client, DEFAULT_BASE_URL, EventPayload, EventUser, type HeartbeatOptions, HeartbeatPayload, type InitOptions, type RunContext, Scope, Severity, Span, SpanData, type TaskHandler, type TasksOptions, Transaction, TransactionPayload, type WithMonitorOptions, addBreadcrumb, captureException, captureMessage, checkIn, close, flush, getClient, init, register, scrubSecrets, setContext, setExtra, setTag, setTags, setUser, start, startTransaction, stop, withMonitor, withScope };
287
+ export { Breadcrumb, type BreadcrumbInput, type CaptureHint, type CheckInOptions, CheckInPayload, CheckInStatus, Client, DEFAULT_BASE_URL, EventPayload, EventUser, type HeartbeatOptions, HeartbeatPayload, type InitOptions, type RunContext, RunLogLevel, Scope, Severity, Span, SpanData, type TaskHandler, type TasksOptions, Transaction, TransactionPayload, type WithMonitorOptions, addBreadcrumb, captureException, captureMessage, checkIn, close, flush, getClient, init, register, scrubSecrets, setContext, setExtra, setTag, setTags, setUser, start, startTransaction, stop, withMonitor, withScope };
package/dist/index.js CHANGED
@@ -103,7 +103,7 @@ function scrubSecrets(text) {
103
103
 
104
104
  // src/utils.ts
105
105
  var SDK_NAME = "hobots";
106
- var SDK_VERSION = true ? "1.7.1" : "0.0.0-dev";
106
+ var SDK_VERSION = true ? "1.7.2" : "0.0.0-dev";
107
107
  function isNode() {
108
108
  return typeof process !== "undefined" && typeof process.versions?.node === "string";
109
109
  }
@@ -662,12 +662,6 @@ var Scope = class _Scope {
662
662
  function spanId() {
663
663
  return uuid4().slice(0, 16);
664
664
  }
665
- function printSpanLog(kind, phase, label, startTs, endTs) {
666
- const durationMs = startTs && endTs ? new Date(endTs).getTime() - new Date(startTs).getTime() : void 0;
667
- const tag = colorize(`[hobots:${kind}] ${phase.toUpperCase()}`, phase === "finish" ? "green" : "cyan");
668
- const suffix = durationMs != null ? ` (${durationMs}ms)` : "";
669
- console.log(`${tag} ${label}${suffix}`);
670
- }
671
665
  function spanLabel(op, description) {
672
666
  return [op, description].filter(Boolean).join(" \u2014 ") || "(sem nome)";
673
667
  }
@@ -698,7 +692,7 @@ var Span = class {
698
692
  finish() {
699
693
  if (this.endTimestamp) return;
700
694
  this.endTimestamp = nowISO();
701
- printSpanLog("span", "finish", spanLabel(this.op, this.description), this.startTimestamp, this.endTimestamp);
695
+ this.transaction.emit("span", "finish", spanLabel(this.op, this.description), this.startTimestamp, this.endTimestamp);
702
696
  }
703
697
  toJSON() {
704
698
  return {
@@ -720,7 +714,7 @@ var Transaction = class {
720
714
  this.op = op;
721
715
  this.sampled = sampled;
722
716
  this.runId = runId;
723
- printSpanLog("transaction", "start", op ? `${name} (${op})` : name);
717
+ this.emit("transaction", "start", op ? `${name} (${op})` : name);
724
718
  }
725
719
  eventId = uuid4();
726
720
  spanId = spanId();
@@ -729,10 +723,36 @@ var Transaction = class {
729
723
  spans = [];
730
724
  tags = {};
731
725
  finished = false;
726
+ lifecycleSink;
727
+ // eventos emitidos antes do sink existir (o START da transaction sai no construtor,
728
+ // antes do RunReporter conectar) — replay no setLifecycleSink
729
+ lifecycleBacklog = [];
730
+ /**
731
+ * Ecoa no terminal o início/fim de um span ou transaction (sempre, independente de
732
+ * sampling ou do debug) e espelha a linha no sink de lifecycle, se conectado — é
733
+ * assim que os eventos de performance também aparecem nos logs da run no app.
734
+ */
735
+ emit(kind, phase, label, startTs, endTs) {
736
+ const durationMs = startTs && endTs ? new Date(endTs).getTime() - new Date(startTs).getTime() : void 0;
737
+ const tag = colorize(`[hobots:${kind}] ${phase.toUpperCase()}`, phase === "finish" ? "green" : "cyan");
738
+ const suffix = durationMs != null ? ` (${durationMs}ms)` : "";
739
+ console.log(`${tag} ${label}${suffix}`);
740
+ const level = phase === "finish" ? "success" : "info";
741
+ const message = `[${kind}] ${phase.toUpperCase()} ${label}${suffix}`;
742
+ if (this.lifecycleSink) this.lifecycleSink(level, message);
743
+ else if (this.lifecycleBacklog.length < 100) this.lifecycleBacklog.push([level, message]);
744
+ }
745
+ /** Conecta o espelho de lifecycle (RunReporter) e faz replay do backlog em ordem. */
746
+ setLifecycleSink(sink) {
747
+ this.lifecycleSink = sink;
748
+ const backlog = this.lifecycleBacklog;
749
+ this.lifecycleBacklog = [];
750
+ for (const [level, message] of backlog) sink(level, message);
751
+ }
732
752
  createSpan(parentSpanId, op, description) {
733
753
  const span = new Span(this, parentSpanId, op, description);
734
754
  this.spans.push(span);
735
- printSpanLog("span", "start", spanLabel(op, description));
755
+ this.emit("span", "start", spanLabel(op, description));
736
756
  return span;
737
757
  }
738
758
  /** Span direto da transaction. */
@@ -756,7 +776,7 @@ var Transaction = class {
756
776
  this.finished = true;
757
777
  for (const span of this.spans) span.finish();
758
778
  const endTimestamp = nowISO();
759
- printSpanLog(
779
+ this.emit(
760
780
  "transaction",
761
781
  "finish",
762
782
  this.op ? `${this.name} (${this.op})` : this.name,
@@ -964,6 +984,7 @@ var RunReporter = class {
964
984
  error: (message) => this.log("error", message),
965
985
  success: (message) => this.log("success", message)
966
986
  };
987
+ tx.setLifecycleSink((level, message) => this.push(level, message));
967
988
  const signal = this.abortController.signal;
968
989
  this.context = {
969
990
  runId,
@@ -1021,6 +1042,12 @@ var RunReporter = class {
1021
1042
  if (this.dead) return;
1022
1043
  const scrubbed = scrubSecrets(message);
1023
1044
  printRunLog(this.context.task, level, scrubbed);
1045
+ this.push(level, scrubbed, true);
1046
+ }
1047
+ /** Bufferiza uma entrada de log sem eco no terminal (cap, truncate, flush). */
1048
+ push(level, message, alreadyScrubbed = false) {
1049
+ if (this.dead) return;
1050
+ const scrubbed = alreadyScrubbed ? message : scrubSecrets(message);
1024
1051
  if (this.loggedCount >= MAX_LOGS_PER_RUN) {
1025
1052
  this.droppedCount++;
1026
1053
  return;
@@ -1417,15 +1444,16 @@ var TaskAgent = class {
1417
1444
  this.logger.debug(`executando run ${run.id} (${run.task})`);
1418
1445
  try {
1419
1446
  await runWithRunContext({ runId: run.id, tx }, () => this.invokeWithTimeout(handler, run, reporter));
1420
- reporter.reportSuccess();
1421
1447
  tx.setStatus("ok");
1448
+ tx.finish();
1449
+ reporter.reportSuccess();
1422
1450
  this.logger.debug(`run ${run.id} conclu\xEDda`);
1423
1451
  } catch (error) {
1424
- reporter.reportFailure(toRunError(error));
1425
1452
  tx.setStatus("error");
1453
+ tx.finish();
1454
+ reporter.reportFailure(toRunError(error));
1426
1455
  this.logger.debug(`run ${run.id} falhou: ${String(error)}`);
1427
1456
  }
1428
- tx.finish();
1429
1457
  await reporter.finalize();
1430
1458
  } finally {
1431
1459
  this.reporters.delete(reporter);