@tracemem/ts-sdk
v0.1.1
Published
TypeScript SDK for Tracemem
Readme
@tracemem/ts-sdk
TypeScript SDK for TraceMem - Decision tracking and traceability for AI agents and automation systems.
Quick Start (60 seconds)
import { TraceMemClient } from '@tracemem/ts-sdk';
// Create client (only apiKey required)
const client = new TraceMemClient({
apiKey: process.env.TRACEMEM_API_KEY!,
});
// Open a decision from an action
const decision = await client.open('refactor', {
automationMode: 'propose',
});
// Add context
await decision.note({
kind: 'info',
message: 'Starting refactoring work',
});
// Close the decision
await decision.close({
outcome: 'commit',
reason: 'Refactoring completed successfully',
});Installation
npm install @tracemem/ts-sdkConfiguration
The SDK requires only an API key to get started:
const client = new TraceMemClient({
apiKey: 'your-api-key-here',
});Optional Configuration
const client = new TraceMemClient({
apiKey: 'your-api-key-here',
mcpUrl: 'https://mcp.tracemem.com', // Default
timeoutMs: 30000, // Default: 30 seconds
sanitize: true, // Default: true (redacts secrets, truncates large data)
defaultActor: 'my-agent', // Default: 'tracemem-ts'
defaultAutomationMode: 'propose', // Default: 'propose'
actionIntentMap: { // Extend default action->intent mapping
'custom_action': 'custom.intent.execute',
},
});Decision Lifecycle
Opening a Decision
Use open() to create a decision from a common action (automatically maps to intent):
const decision = await client.open('edit_files', {
automationMode: 'propose',
actor: 'my-agent',
metadata: {
project: 'my-project',
branch: 'main',
},
});Creating a Decision with Explicit Intent
Use createDecision() for explicit intent control:
const decision = await client.createDecision('code.change.apply', {
automationMode: 'execute',
actor: 'my-agent',
instance: 'instance-123',
version: '1.0.0',
metadata: {
custom: 'data',
},
});Adding Context/Notes
await decision.note({
kind: 'info',
message: 'Starting work',
data: {
files: ['file1.ts', 'file2.ts'],
},
});Reading from Data Products
const result = await decision.read('pg_customers_v1', 'order_validation', {
query: {
customer_id: '12345',
},
resultMode: 'single', // or 'multiple'
});Evaluating Policies
const evaluation = await decision.evaluate('discount_cap_v1', {
inputs: {
proposed_discount: 0.15,
customer_tier: 'premium',
},
});Requesting Approval
await decision.requestApproval({
kind: 'discount_approval',
message: 'Customer requesting 25% discount, exceeds policy limit',
});Writing to Data Products
await decision.write('pg_orders_v1', 'order_creation', {
operation: 'insert',
records: [
{
order_id: 'ord_123',
customer_id: 'cust_456',
amount: 99.99,
},
],
}, {
idempotencyKey: 'order_123_unique',
});Getting Trace and Receipt
// Get full trace of decision activities
const trace = await decision.trace();
// Get receipt (summary)
const receipt = await decision.receipt();Closing a Decision
await decision.close({
outcome: 'commit', // or 'abort'
reason: 'Order successfully processed',
});Approvals Example
const decision = await client.open('secrets', {
automationMode: 'propose',
});
// Evaluate policy
const evaluation = await decision.evaluate('secrets_change_policy', {
inputs: {
secret_name: 'DATABASE_PASSWORD',
change_type: 'update',
},
});
// Request approval if needed
if (evaluation.requiresApproval) {
await decision.requestApproval({
kind: 'secrets_change',
message: 'Updating production database password',
});
// Wait for approval (poll or webhook)
// ... approval logic ...
}
// Proceed with change
await decision.write('secrets_v1', 'secret_update', {
operation: 'update',
name: 'DATABASE_PASSWORD',
value: 'new-secure-password',
});
await decision.close({
outcome: 'commit',
reason: 'Secret updated after approval',
});Product Discovery
// List all products
const productsText = await client.products.list();
// Parse JSON if needed
const products = JSON.parse(productsText);
// Get specific product
const productText = await client.products.get('pg_customers_v1');
const product = JSON.parse(productText);Using Client Methods Directly
You can also use client methods directly (useful when working with multiple decisions):
const decisionId = 'dec_abc123';
await client.note(decisionId, {
kind: 'info',
message: 'Note',
});
const result = await client.read(decisionId, {
product: 'pg_customers_v1',
purpose: 'order_validation',
query: { customer_id: '123' },
});Security and Data Sanitization
By default, the SDK automatically sanitizes data before sending to TraceMem:
- Secret Redaction: Keys matching patterns like
password,api_key,token,secret, etc. are redacted - String Truncation: Strings longer than 1000 characters are truncated
- Array Truncation: Arrays longer than 100 items are truncated
- Object Key Limits: Objects with more than 100 keys are truncated
- Depth Limits: Nested structures deeper than 10 levels are truncated
To disable sanitization:
const client = new TraceMemClient({
apiKey: 'your-key',
sanitize: false, // Disable sanitization
});Note: Disabling sanitization may expose sensitive data. Use with caution.
Error Handling
The SDK provides typed error classes:
import {
TraceMemError,
TraceMemNetworkError,
TraceMemValidationError,
TraceMemTimeoutError,
} from '@tracemem/ts-sdk';
try {
await client.createDecision('code.change.apply');
} catch (error) {
if (error instanceof TraceMemNetworkError) {
// Handle network error
console.error('Network error:', error.message);
} else if (error instanceof TraceMemValidationError) {
// Handle validation error
console.error('Validation error:', error.message);
} else if (error instanceof TraceMemTimeoutError) {
// Handle timeout
console.error('Request timed out:', error.message);
} else if (error instanceof TraceMemError) {
// Handle other TraceMem errors
console.error('TraceMem error:', error.code, error.message);
}
}Action to Intent Mapping
The SDK automatically maps common actions to intents:
| Action | Intent |
|--------|--------|
| edit_files | code.change.apply |
| refactor | code.refactor.execute |
| run_command | ops.command.execute |
| deploy | deploy.release.execute |
| secrets | secrets.change.propose |
| db_change | data.change.apply |
| review | code.review.assist |
Unknown actions are used as-is (no mapping).
TypeScript Support
The SDK is written in TypeScript and includes full type definitions. All methods and interfaces are fully typed.
Requirements
- Node.js >= 18.0.0
- TypeScript >= 5.0 (for TypeScript projects)
License
Apache-2.0
