npm package: @runtime-digital-twin/sdk
Description: SDK for capturing runtime behavior - automatic incident response and debugging with enhanced autofix support
Latest version: 1.0.3

# @runtime-digital-twin/sdk

In-process instrumentation library for capturing runtime behavior and enabling automatic incident response.

## Installation

```bash
npm install @runtime-digital-twin/sdk
# or
pnpm add @runtime-digital-twin/sdk
# or
yarn add @runtime-digital-twin/sdk
```

## Quick Start

### 1. Install the SDK

```bash
npm install @runtime-digital-twin/sdk
```

### 2. Add to Your Fastify App

```typescript
import Fastify from 'fastify';
import { fastifyTracing } from '@runtime-digital-twin/sdk';

const fastify = Fastify();

// Register the tracing plugin
await fastify.register(fastifyTracing, {
  mode: 'record', // or 'replay'
  outputDir: './traces',
});

// Your routes work as normal
fastify.get('/api/users', async (request, reply) => {
  return { users: [] };
});

await fastify.listen({ port: 3000 });
```

### 3. Wrap Your Database Client

```typescript
import { createWrappedDbClient } from '@runtime-digital-twin/sdk';
import { Pool } from 'pg';

const db = await createWrappedDbClient({
  realClient: new Pool({ connectionString: process.env.DATABASE_URL }),
});

// Use it like a normal DB client
const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
```

### 4. Wrap Your HTTP Client (Optional)

```typescript
import { wrapFetch } from '@runtime-digital-twin/sdk';

// Wrap global fetch
const wrappedFetch = wrapFetch(fetch);

// Use wrapped fetch for outbound calls
const response = await wrappedFetch('https://api.example.com/data');
```

## Features

- ✅ **HTTP Request/Response Capture** - Automatic Fastify plugin
- ✅ **Database Query Capture** - Postgres wrapper with query/result recording
- ✅ **HTTP Client Wrapping** - Capture outbound HTTP calls
- ✅ **Error Capture** - Automatic error and stack trace recording
- ✅ **Trace Bundle Writing** - Self-contained trace format
- ✅ **Correlation ID Generation** - Cross-service tracing
- ✅ **Span Tracking** - Request/response span relationships

## Configuration

### Fastify Plugin Options

```typescript
await fastify.register(fastifyTracing, {
  serviceName: 'my-service',   // Required: Service identifier
  serviceVersion: '1.0.0',     // Optional: Service version
  environment: 'production',   // Optional: Environment name
  traceDir: './traces',        // Optional: Where to store traces (default: './traces')
  headerAllowlist: [],         // Optional: Headers to capture
  maxBodySize: 10 * 1024 * 1024, // Optional: Max body size to capture (default: 10MB)
  enabled: true,              // Optional: Enable/disable tracing (default: true)
  traceSampleRate: 1,         // Optional: 0–1; 1 = always, 0.1 = 10% of requests (default: 1)
  alwaysTraceErrors: true,     // Optional: always capture trace for requests that error (default: true)
  // Upload options (optional)
  uploadUrl: process.env.WRAITH_API_URL + '/api/traces/ingest',
  apiKey: process.env.WRAITH_API_KEY,
  uploadOnComplete: true,      // Optional: Auto-upload after completion (default: true)
});
```

### Database Client Options

```typescript
const db = await createWrappedDbClient({
  realClient: new Pool({ connectionString: process.env.DATABASE_URL }),
  traceDir: './traces',  // Optional: custom trace directory
});
```

## Trace Ingestion (Automatic Upload)

To automatically upload traces to your Wraith control plane:

```typescript
import { fastifyTracing } from '@runtime-digital-twin/sdk';

await fastify.register(fastifyTracing, {
  serviceName: 'my-service',
  serviceVersion: '1.0.0',
  environment: process.env.ENVIRONMENT || 'production',
  traceDir: './traces',
  // Auto-upload traces after request completes
  uploadUrl: process.env.WRAITH_API_URL 
    ? `${process.env.WRAITH_API_URL}/api/traces/ingest`
    : undefined,
  apiKey: process.env.WRAITH_API_KEY,
  uploadOnComplete: true, // Default: true
});
```

**Environment Variables:**
```bash
WRAITH_API_URL=https://your-wraith-app.vercel.app
WRAITH_API_KEY=your-api-key-here
```

Traces are uploaded asynchronously after each request completes, so they don't slow down your application.

### Sampling and errors

- **traceSampleRate** (0–1): When set below 1, only that fraction of requests are traced (e.g. 0.1 = 10%). Reduces volume and cost while keeping a representative sample.
- **alwaysTraceErrors**: When true (default), any request that ends in an error (Fastify `onError`) is traced and uploaded even if it was not sampled. Ensures failures are never missed.

### Rate limits and 429

If the ingest endpoint returns **429 Too Many Requests**, the uploader retries with exponential backoff (same as for 5xx). Use the **Retry-After** response header when present; the SDK respects backoff between attempts. To avoid hitting limits, reduce volume with **traceSampleRate** or increase **TRACE_INGEST_RATE_LIMIT_REQUESTS_PER_MIN** on the server.

## Modes

### Record Mode

Active instrumentation that captures all runtime behavior:
- HTTP requests/responses
- Database queries and results
- Outbound HTTP calls
- Errors and stack traces

### Replay Mode

Disabled instrumentation (used during trace replay):
- No events written
- Service runs with mocked dependencies
- Used by replay engine for deterministic debugging

## Environment Variables

- `RDT_MODE` - Set to `record` or `replay` (default: `record`)
- `RDT_TRACE_DIR` - Directory for trace storage (default: `./traces`)
- `WRAITH_API_URL` - Control plane URL for trace ingestion
- `WRAITH_API_KEY` - API key for authentication

## API Reference

### Fastify Plugin

```typescript
import { fastifyTracing, FastifyTracingOptions } from '@runtime-digital-twin/sdk';
```

### Database Wrapper

```typescript
import { 
  createWrappedDbClient,
  wrapDbClient,
  CreateWrappedDbClientOptions 
} from '@runtime-digital-twin/sdk';
```

### HTTP Wrapper

```typescript
import { wrapFetch, setTraceContext, getTraceContext } from '@runtime-digital-twin/sdk';
```

### Trace Management

```typescript
import { 
  createTrace,
  loadTraceMeta,
  validateTraceStructure,
  TraceBundle 
} from '@runtime-digital-twin/sdk';
```

### Trace Upload

```typescript
import { 
  uploadTrace,
  type TraceUploadOptions,
  type TraceUploadResult 
} from '@runtime-digital-twin/sdk';
```

## Examples

See the [Quickstart Guide](../../QUICKSTART.md) for complete examples.

## Changelog

### v1.1.0
- Enhanced trace upload with automatic retry
- Improved CORS support for browser-based services
- Better error handling and logging
- Support for demo mode autofix integration

### v1.0.0
- Initial release
- Fastify tracing plugin
- Database query capture
- HTTP client wrapping
- Trace bundle writing

## License

MIT