autotel 5.0.0 → 6.1.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.
Files changed (94) hide show
  1. package/README.md +14 -1
  2. package/dist/auto.cjs +1 -1
  3. package/dist/auto.js +1 -1
  4. package/dist/correlation-id.cjs +9 -9
  5. package/dist/correlation-id.js +1 -1
  6. package/dist/decorators.cjs +2 -2
  7. package/dist/decorators.cjs.map +1 -1
  8. package/dist/decorators.js +1 -1
  9. package/dist/drain-pipeline.cjs +10 -1
  10. package/dist/drain-pipeline.cjs.map +1 -1
  11. package/dist/drain-pipeline.d.cts +5 -0
  12. package/dist/drain-pipeline.d.cts.map +1 -1
  13. package/dist/drain-pipeline.d.ts +5 -0
  14. package/dist/drain-pipeline.d.ts.map +1 -1
  15. package/dist/drain-pipeline.js +10 -1
  16. package/dist/drain-pipeline.js.map +1 -1
  17. package/dist/event.cjs +4 -4
  18. package/dist/event.js +1 -1
  19. package/dist/{functional-Bit6noRu.js → functional-BnDUxnSl.js} +2 -4
  20. package/dist/{functional-Bit6noRu.js.map → functional-BnDUxnSl.js.map} +1 -1
  21. package/dist/{functional-Cj7PSItS.cjs → functional-DcLBuCPz.cjs} +12 -14
  22. package/dist/{functional-Cj7PSItS.cjs.map → functional-DcLBuCPz.cjs.map} +1 -1
  23. package/dist/functional.cjs +1 -1
  24. package/dist/functional.js +1 -1
  25. package/dist/http.cjs +2 -2
  26. package/dist/http.cjs.map +1 -1
  27. package/dist/http.js +1 -1
  28. package/dist/index.cjs +33 -166
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.d.cts +5 -2
  31. package/dist/index.d.cts.map +1 -1
  32. package/dist/index.d.ts +5 -2
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +14 -147
  35. package/dist/index.js.map +1 -1
  36. package/dist/init-C3RApHKJ.cjs +3371 -0
  37. package/dist/init-C3RApHKJ.cjs.map +1 -0
  38. package/dist/{init-CTyqG9qR.d.ts → init-D6n2diBy.d.ts} +21 -2
  39. package/dist/init-D6n2diBy.d.ts.map +1 -0
  40. package/dist/init-R-gSEXkJ.js +3190 -0
  41. package/dist/init-R-gSEXkJ.js.map +1 -0
  42. package/dist/{init-a4yPDYqC.d.cts → init-XzXzrarP.d.cts} +21 -2
  43. package/dist/init-XzXzrarP.d.cts.map +1 -0
  44. package/dist/instrumentation.cjs +1 -1
  45. package/dist/instrumentation.js +1 -1
  46. package/dist/messaging.cjs +1 -1
  47. package/dist/messaging.js +1 -1
  48. package/dist/semantic-helpers.cjs +1 -1
  49. package/dist/semantic-helpers.js +1 -1
  50. package/dist/webhook.cjs +1 -1
  51. package/dist/webhook.js +1 -1
  52. package/dist/workflow-distributed.cjs +1 -1
  53. package/dist/workflow-distributed.js +1 -1
  54. package/dist/workflow.cjs +1 -1
  55. package/dist/workflow.js +1 -1
  56. package/dist/yaml-config.d.cts +1 -1
  57. package/dist/yaml-config.d.ts +1 -1
  58. package/package.json +2 -3
  59. package/dist/event-CwIpFdoY.cjs +0 -778
  60. package/dist/event-CwIpFdoY.cjs.map +0 -1
  61. package/dist/event-pLMF5b3d.js +0 -761
  62. package/dist/event-pLMF5b3d.js.map +0 -1
  63. package/dist/init-B2uvZReD.cjs +0 -1120
  64. package/dist/init-B2uvZReD.cjs.map +0 -1
  65. package/dist/init-CTyqG9qR.d.ts.map +0 -1
  66. package/dist/init-CdEWjhvl.js +0 -1043
  67. package/dist/init-CdEWjhvl.js.map +0 -1
  68. package/dist/init-a4yPDYqC.d.cts.map +0 -1
  69. package/dist/operation-context-CKBoA4Qy.js +0 -59
  70. package/dist/operation-context-CKBoA4Qy.js.map +0 -1
  71. package/dist/operation-context-hzKbTKnt.cjs +0 -72
  72. package/dist/operation-context-hzKbTKnt.cjs.map +0 -1
  73. package/dist/track-BBcxEJEC.js +0 -1110
  74. package/dist/track-BBcxEJEC.js.map +0 -1
  75. package/dist/track-BI6dmZ2X.cjs +0 -1207
  76. package/dist/track-BI6dmZ2X.cjs.map +0 -1
  77. package/skills/analyze-traces/SKILL.md +0 -209
  78. package/skills/autotel-core/SKILL.md +0 -166
  79. package/skills/autotel-events/SKILL.md +0 -84
  80. package/skills/autotel-frameworks/SKILL.md +0 -125
  81. package/skills/autotel-instrumentation/SKILL.md +0 -150
  82. package/skills/autotel-request-logging/SKILL.md +0 -99
  83. package/skills/autotel-structured-errors/SKILL.md +0 -125
  84. package/skills/build-audit-trails/SKILL.md +0 -460
  85. package/skills/build-audit-trails/references/audit-queries.md +0 -73
  86. package/skills/build-audit-trails/references/framework-wiring.md +0 -196
  87. package/skills/debug-missing-spans/SKILL.md +0 -250
  88. package/skills/migrate-to-autotel/SKILL.md +0 -269
  89. package/skills/review-otel-patterns/SKILL.md +0 -540
  90. package/skills/review-otel-patterns/references/code-review.md +0 -76
  91. package/skills/review-otel-patterns/references/processor-pipeline.md +0 -205
  92. package/skills/review-otel-patterns/references/structured-errors.md +0 -102
  93. package/skills/review-otel-patterns/references/wide-spans.md +0 -85
  94. package/skills/tune-sampling/SKILL.md +0 -290
@@ -1,125 +0,0 @@
1
- ---
2
- name: autotel-frameworks
3
- description: >
4
- Hono, Fastify, TanStack Start, Cloudflare Workers, NestJS, SvelteKit, Elysia, Nuxt. Middleware and init; getRequestLogger() in handlers. Load when adding Autotel to a web framework.
5
- ---
6
-
7
- # Autotel: Framework Integration
8
-
9
- This skill builds on autotel-instrumentation. Read it first for init() and span creation.
10
-
11
- Use framework-specific middleware or wrappers to create a span per request; then call `getRequestLogger()` inside handlers. Most frameworks use `autotel-adapters` subpaths (or a thin wrapper package like `autotel-hono`, `autotel-tanstack`, `autotel-cloudflare`, `autotel-nuxt`).
12
-
13
- When adding new request/exception events in framework handlers, prefer correlated logs (`getRequestLogger().info/warn/error`) instead of introducing new `span.addEvent()` usage.
14
-
15
- For custom HTTP frameworks, start from `autotel-adapters/toolkit` (`defineFrameworkIntegration`, `createMiddlewareLogger`, `finishResponse` for streaming, `waitUntil` on edge runtimes).
16
-
17
- ## Setup
18
-
19
- ### Hono
20
-
21
- ```typescript
22
- import { Hono } from 'hono';
23
- import { init, getRequestLogger } from 'autotel';
24
- import { otel } from 'autotel-hono';
25
-
26
- init({ service: 'my-api' });
27
-
28
- const app = new Hono();
29
- app.use('*', otel({ serviceName: 'my-api' }));
30
-
31
- app.post('/api/checkout', async (c) => {
32
- const log = getRequestLogger();
33
- log.set({ route: 'checkout' });
34
- const body = await c.req.json();
35
- log.set({ cart: { items: body.items?.length } });
36
- log.emitNow();
37
- return c.json({ ok: true });
38
- });
39
- ```
40
-
41
- ### Fastify
42
-
43
- Use middleware or a wrapper that creates a span per request (see apps/example-fastify). Inside the route, wrap with `trace()` or ensure a span is active, then `getRequestLogger(ctx)` or `getRequestLogger()`.
44
-
45
- ### TanStack Start
46
-
47
- See packages/autotel-tanstack and apps/example-tanstack-start: middleware and env config. Use `getRequestLogger()` inside server handlers when a span is active.
48
-
49
- ### Cloudflare Workers
50
-
51
- See packages/autotel-cloudflare: init at top level, wrap the fetch handler so each request gets a span. Use `getRequestLogger()` or trace context inside the handler. Pass `ctx.waitUntil` through adapter options so emit/drain completes after the response.
52
-
53
- ### NestJS
54
-
55
- Use `AutotelInterceptor` from `autotel-adapters/nestjs` and `useLogger()` in controllers/services (see apps/example-nestjs):
56
-
57
- ```typescript
58
- import { APP_INTERCEPTOR } from '@nestjs/core';
59
- import { AutotelInterceptor } from 'autotel-adapters/nestjs';
60
-
61
- @Module({
62
- providers: [{ provide: APP_INTERCEPTOR, useClass: AutotelInterceptor }],
63
- })
64
- export class AppModule {}
65
- ```
66
-
67
- ### SvelteKit
68
-
69
- Add `autotelHandle()` in `hooks.server.ts` from `autotel-adapters/sveltekit`; call `useLogger()` in `+server.ts` / server loads. Use `finishResponse` semantics for streaming routes (see toolkit `stream-response`).
70
-
71
- ### Elysia
72
-
73
- Wrap handlers with `withAutotelHandler()` from `autotel-adapters/elysia` (or the `autotel` alias); use `useLogger()` inside handlers (see apps/example-elysia).
74
-
75
- ### Nuxt
76
-
77
- Add the `autotel-nuxt` module for zero-config Nitro wiring; server code can use `useLogger()` via `autotel-adapters/nitro` re-exports from `autotel-nuxt/runtime/nitro`.
78
-
79
- ## Core Patterns
80
-
81
- **Register middleware before routes:** Middleware creates the span; getRequestLogger() needs that active span.
82
-
83
- **Framework-specific packages:** autotel-hono, autotel-tanstack, autotel-cloudflare, autotel-nuxt. Adapter subpaths: autotel-adapters/{express,fastify,next,nitro,nestjs,sveltekit,elysia,...}. Install the package for your framework and follow its README or CLAUDE.md.
84
-
85
- **Streaming responses:** defer `emitNow` until the body finishes via adapter `finishResponse` / toolkit `bindStreamingResponseLifecycle`.
86
-
87
- **Edge drain:** pass `waitUntil` (Cloudflare `ExecutionContext`, etc.) so async emit/drain does not block the response.
88
-
89
- ## Common Mistakes
90
-
91
- ### HIGH Use getRequestLogger() in Hono without registering middleware first
92
-
93
- Wrong:
94
-
95
- ```typescript
96
- const app = new Hono();
97
- app.get('/api/x', (c) => {
98
- const log = getRequestLogger();
99
- return c.json({});
100
- });
101
- ```
102
-
103
- Correct:
104
-
105
- ```typescript
106
- const app = new Hono();
107
- app.use('*', otel());
108
- app.get('/api/x', (c) => {
109
- const log = getRequestLogger();
110
- return c.json({});
111
- });
112
- ```
113
-
114
- Middleware creates the span per request. Without it, getRequestLogger() has no active span and will throw.
115
-
116
- Source: packages/autotel-hono, docs/AGENT-GUIDE.md
117
-
118
- ## Version
119
-
120
- Targets autotel v2.23.x.
121
-
122
- See also:
123
-
124
- - `autotel-instrumentation/SKILL.md` for init and spans
125
- - `autotel-request-logging/SKILL.md` for request logger usage
@@ -1,150 +0,0 @@
1
- ---
2
- name: autotel-instrumentation
3
- description: >
4
- trace(), span(), instrument(), init(). Factory vs direct pattern, name inference. Sync init; use node-require for optional deps. Load when wrapping handlers or functions with spans.
5
- ---
6
-
7
- # Autotel: Instrumentation
8
-
9
- Wrap functions and handlers with `trace()`, `span()`, or `instrument()`. Call `init()` once at app startup. Keep init synchronous; use `safeRequire`/`requireModule` for optional dependencies.
10
-
11
- For new event emission, prefer correlated logs (OTel Logs API path) over adding new direct span-event calls.
12
-
13
- ## Setup
14
-
15
- ```typescript
16
- import { init, trace, withTracing } from 'autotel';
17
-
18
- init({ service: 'my-app' });
19
-
20
- const handler = trace(async (req: Request) => {
21
- return processRequest(req);
22
- });
23
- ```
24
-
25
- With span context (attributes, request logger):
26
-
27
- ```typescript
28
- const handler = withTracing({ name: 'http.request' })(
29
- (ctx) => async (req: Request) => {
30
- ctx.setAttribute('http.route', '/api/checkout');
31
- const log = getRequestLogger(ctx);
32
- log.set({ path: req.url });
33
- return processRequest(req);
34
- },
35
- );
36
- ```
37
-
38
- ## Core Patterns
39
-
40
- **Explicit span name:**
41
-
42
- ```typescript
43
- const checkout = trace('checkout', async (body) => {
44
- return processCheckout(body);
45
- });
46
- ```
47
-
48
- **instrument() with key:**
49
-
50
- ```typescript
51
- import { instrument } from 'autotel';
52
- const fn = instrument({
53
- key: 'processOrder',
54
- fn: async (id) => db.orders.get(id),
55
- });
56
- ```
57
-
58
- **span() for a child span:**
59
-
60
- ```typescript
61
- import { span } from 'autotel';
62
- const result = await span('db.query', async () => db.query(sql));
63
- ```
64
-
65
- **Init with optional config:**
66
-
67
- ```typescript
68
- init({
69
- service: 'my-api',
70
- // see docs/CONFIGURATION.md for full options
71
- });
72
- ```
73
-
74
- **Single backend vs multi-backend OTLP:**
75
-
76
- ```typescript
77
- init({
78
- service: 'my-api',
79
- endpoint: 'https://otlp-gateway-prod.grafana.net/otlp', // single destination
80
- });
81
-
82
- init({
83
- service: 'my-api',
84
- logs: true,
85
- destinations: [
86
- {
87
- endpoint: 'https://otlp-gateway-prod.grafana.net/otlp',
88
- headers: 'Authorization=Basic ...',
89
- },
90
- {
91
- endpoint: 'https://api.honeycomb.io',
92
- headers: { 'x-honeycomb-team': process.env.HONEYCOMB_API_KEY! },
93
- signals: ['traces'],
94
- },
95
- ],
96
- });
97
- ```
98
-
99
- ## Common Mistakes
100
-
101
- ### HIGH Forget to call init() before using trace/span
102
-
103
- Wrong:
104
-
105
- ```typescript
106
- import { trace } from 'autotel';
107
- export const fn = trace(async () => {});
108
- ```
109
-
110
- Correct:
111
-
112
- ```typescript
113
- import { init, trace } from 'autotel';
114
- init({ service: 'my-app' });
115
- export const fn = trace(async () => {});
116
- ```
117
-
118
- SDK must be initialized; trace() and span() rely on the global tracer.
119
-
120
- Source: packages/autotel/CLAUDE.md
121
-
122
- ### MEDIUM Wrong export path for submodules
123
-
124
- Wrong:
125
-
126
- ```typescript
127
- import { Event } from 'autotel'; // Event is on autotel/event
128
- import { createTraceCollector } from 'autotel'; // testing subpath
129
- ```
130
-
131
- Correct:
132
-
133
- ```typescript
134
- import { trace, init, getRequestLogger } from 'autotel';
135
- import { Event } from 'autotel/event';
136
- import { createTraceCollector } from 'autotel/testing';
137
- ```
138
-
139
- Use the exact export paths from package.json (autotel/event, autotel/testing, autotel/attributes, etc.).
140
-
141
- Source: packages/autotel/package.json exports
142
-
143
- ## Version
144
-
145
- Targets autotel v2.23.x.
146
-
147
- See also:
148
-
149
- - `autotel-core/SKILL.md` for when to use what
150
- - `autotel-request-logging/SKILL.md`, since `getRequestLogger` requires an active span
@@ -1,99 +0,0 @@
1
- ---
2
- name: autotel-request-logging
3
- description: >
4
- getRequestLogger(), set(), info/warn/error, emitNow(). One snapshot per request; requires active span. Use when adding request-scoped context or replacing scattered console.log.
5
- ---
6
-
7
- # Autotel: Request Logging
8
-
9
- This skill builds on autotel-instrumentation. Read it first for init and span creation.
10
-
11
- Accumulate context with `getRequestLogger(ctx)`, `.set()`, and `.info()`/`.warn()`/`.error()`. Call `.emitNow()` (or rely on middleware) to emit one snapshot per request. Request logger requires an active span. Use inside `trace()` or framework middleware.
12
-
13
- Preferred event model: treat request logger emissions as the default way to capture request-correlated events in new code. If a backend still expects span-event rendering, keep compatibility at export/processor level rather than adding new `span.addEvent()` calls in application code.
14
-
15
- ## Setup
16
-
17
- ```typescript
18
- import { init, withTracing, getRequestLogger } from 'autotel';
19
-
20
- init({ service: 'my-app' });
21
-
22
- const handler = withTracing({ name: 'http.request' })(
23
- (ctx) => async (req: Request, res: Response) => {
24
- const log = getRequestLogger(ctx);
25
- log.set({ method: req.method, path: req.url });
26
-
27
- const user = await getAuth(req);
28
- log.set({ user: { id: user.id } });
29
-
30
- const result = await doWork(req);
31
- log.set({ result: { id: result.id } });
32
- log.emitNow();
33
- return res.json(result);
34
- },
35
- );
36
- ```
37
-
38
- When the framework creates the span (e.g. Hono middleware), call `getRequestLogger()` with no args:
39
-
40
- ```typescript
41
- app.use(autotelMiddleware());
42
- app.get('/api/users', (c) => {
43
- const log = getRequestLogger();
44
- log.set({ route: 'users' });
45
- return c.json({ users: [] });
46
- });
47
- ```
48
-
49
- ## Core Patterns
50
-
51
- **Accumulate then emit:**
52
-
53
- ```typescript
54
- const log = getRequestLogger(ctx);
55
- log.set({ cart: { items: body.items.length } });
56
- log.set({ payment: { method: body.method } });
57
- log.error(err, { step: 'payment' });
58
- log.emitNow();
59
- ```
60
-
61
- **RequestLogSnapshot:** `emitNow()` returns `{ timestamp, traceId, spanId, correlationId, context }`. You can pass `onEmit` in options to forward it.
62
-
63
- **Options:** `getRequestLogger(ctx?, { onEmit?: (snapshot) => void })` for custom fan-out on emit.
64
-
65
- ## Common Mistakes
66
-
67
- ### HIGH Call getRequestLogger() outside a span
68
-
69
- Wrong:
70
-
71
- ```typescript
72
- function helper() {
73
- const log = getRequestLogger();
74
- log.set({ step: 'helper' });
75
- }
76
- ```
77
-
78
- Correct:
79
-
80
- ```typescript
81
- // Ensure helper runs inside trace() or middleware-created span
82
- function helper(ctx?: TraceContext) {
83
- const log = getRequestLogger(ctx);
84
- log.set({ step: 'helper' });
85
- }
86
- ```
87
-
88
- Request logger attaches to the active span. If there is no active span, it throws. Wrap the call path with `trace()` or register middleware that creates a span per request.
89
-
90
- Source: packages/autotel/src/request-logger.ts
91
-
92
- ## Version
93
-
94
- Targets autotel v2.23.x.
95
-
96
- See also:
97
-
98
- - `autotel-instrumentation/SKILL.md` for creating the span
99
- - `autotel-structured-errors/SKILL.md`, which uses `.error()` to record errors in the snapshot
@@ -1,125 +0,0 @@
1
- ---
2
- name: autotel-structured-errors
3
- description: >
4
- createStructuredError, parseError, recordStructuredError. API errors with message, why, fix, link; client parsing for UI. Use in API routes and client catch blocks.
5
- ---
6
-
7
- # Autotel: Structured Errors
8
-
9
- Throw errors with `createStructuredError({ message, why?, fix?, link?, status?, cause? })` in API routes and services. On the client, use `parseError(caught)` to get `message`, `status`, `why`, `fix`, `link` for toasts and UI.
10
-
11
- ## Setup
12
-
13
- **Server (API route or service):**
14
-
15
- ```typescript
16
- import { createStructuredError } from 'autotel';
17
-
18
- if (!user) {
19
- throw createStructuredError({
20
- message: 'User not found',
21
- status: 404,
22
- why: `No user with ID "${userId}"`,
23
- fix: 'Check the user ID and try again',
24
- link: 'https://docs.example.com/errors/user-not-found',
25
- });
26
- }
27
- ```
28
-
29
- **Client:**
30
-
31
- ```typescript
32
- import { parseError } from 'autotel';
33
-
34
- try {
35
- await fetch('/api/checkout', { method: 'POST', body: JSON.stringify(data) });
36
- } catch (err) {
37
- const e = parseError(err);
38
- toast.error(e.message, { description: e.why });
39
- if (e.fix) setHelp(e.fix);
40
- if (e.link) setDocLink(e.link);
41
- }
42
- ```
43
-
44
- ## Core Patterns
45
-
46
- **Wrap a caught error (preserve cause):**
47
-
48
- ```typescript
49
- try {
50
- await stripe.charges.create(data);
51
- } catch (err) {
52
- throw createStructuredError({
53
- message: 'Payment failed',
54
- status: 402,
55
- why: err instanceof Error ? err.message : 'Unknown error',
56
- fix: 'Try a different payment method or contact support',
57
- link: 'https://docs.stripe.com/declines',
58
- cause: err,
59
- });
60
- }
61
- ```
62
-
63
- **Record on current span:** Use `recordStructuredError(ctx, error)` or the request logger's `.error(error, fields)` so the span gets error attributes and status.
64
-
65
- For new exception event flows, prefer request-logger/log-based correlation and keep span-event compatibility as an implementation detail (processors/export path), not a new app-level dependency.
66
-
67
- **parseError** handles FetchError (ofetch), nested `data.data`, and plain Error. Returns `{ message, status, why?, fix?, link?, raw }`.
68
-
69
- ## Common Mistakes
70
-
71
- ### HIGH Throw new Error() in API routes instead of createStructuredError
72
-
73
- Wrong:
74
-
75
- ```typescript
76
- throw new Error('Payment failed');
77
- ```
78
-
79
- Correct:
80
-
81
- ```typescript
82
- throw createStructuredError({
83
- message: 'Payment failed',
84
- status: 402,
85
- why: 'Card declined by issuer',
86
- fix: 'Try a different payment method',
87
- link: 'https://docs.example.com/payments',
88
- });
89
- ```
90
-
91
- Clients and agents need structured fields (why, fix, link) for actionable errors. parseError() reads these from API responses.
92
-
93
- Source: docs/AGENT-GUIDE.md, AGENTS.md
94
-
95
- ### MEDIUM Client only shows error.message and ignores why/fix/link
96
-
97
- Wrong:
98
-
99
- ```typescript
100
- catch (err) {
101
- toast.error(err.message);
102
- }
103
- ```
104
-
105
- Correct:
106
-
107
- ```typescript
108
- import { parseError } from 'autotel';
109
- catch (err) {
110
- const e = parseError(err);
111
- toast.error(e.message, { description: e.why });
112
- if (e.fix) showFix(e.fix);
113
- if (e.link) setDocLink(e.link);
114
- }
115
- ```
116
-
117
- parseError() extracts status, why, fix, and link from API error responses and FetchError so the UI can show them.
118
-
119
- Source: docs/AGENT-GUIDE.md
120
-
121
- ## Version
122
-
123
- Targets autotel v2.23.x.
124
-
125
- See also: autotel-request-logging/SKILL.md. Use .error() to record errors in the request snapshot.