@relayburn/sdk 1.5.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/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@relayburn/sdk`.
4
+
5
+ ## [Unreleased]
6
+
7
+ ## [1.5.0] - 2026-05-01
8
+
9
+ ### Added
10
+
11
+ - Initial release with embedded `Ledger.open()`, `ingest()`, `summary()`, and `hotspots()` helpers.
package/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # @relayburn/sdk
2
+
3
+ Embeddable Relayburn SDK for in-process ingestion and analysis.
4
+
5
+ ```ts
6
+ import { Ledger, ingest, summary, hotspots } from '@relayburn/sdk';
7
+
8
+ await Ledger.open({ home: '/tmp/relayburn-home' });
9
+ await ingest({ ledgerHome: '/tmp/relayburn-home' });
10
+ const stats = await summary({ session: 'session-id', ledgerHome: '/tmp/relayburn-home' });
11
+ const findings = await hotspots({ session: 'session-id', patterns: ['retry-loop'] });
12
+ ```
package/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export interface LedgerOpenOptions { home?: string }
2
+ export declare class Ledger { static open(opts?: LedgerOpenOptions): Promise<Ledger> }
3
+
4
+ export interface IngestOptions { sessionId?: string; harness?: 'claude-code'|'codex'|'opencode'; ledgerHome?: string }
5
+ export declare function ingest(opts?: IngestOptions): Promise<unknown>
6
+
7
+ export interface SummaryOptions { session?: string; project?: string; since?: string; ledgerHome?: string }
8
+ export declare function summary(opts?: SummaryOptions): Promise<{ totalTokens: number; totalCost: number; byTool: Array<{tool:string;tokens:number;cost:number;count:number}>; byModel: Array<{model:string;tokens:number;cost:number}> }>
9
+
10
+ export interface HotspotsOptions { session?: string; patterns?: string[]; ledgerHome?: string }
11
+ export declare function hotspots(opts?: HotspotsOptions): Promise<unknown>
package/index.js ADDED
@@ -0,0 +1,81 @@
1
+ import { queryAll, queryUserTurns } from '@relayburn/ledger';
2
+ import { loadPricing, costForTurn, attributeHotspots, detectPatterns, findingsFromPatterns } from '@relayburn/analyze';
3
+ import { ingestAll } from '@relayburn/cli';
4
+
5
+ function withHome(home, fn) {
6
+ const prev = process.env.RELAYBURN_HOME;
7
+ if (home) process.env.RELAYBURN_HOME = home;
8
+ return Promise.resolve(fn()).finally(() => {
9
+ if (home) {
10
+ if (prev === undefined) delete process.env.RELAYBURN_HOME;
11
+ else process.env.RELAYBURN_HOME = prev;
12
+ }
13
+ });
14
+ }
15
+
16
+ export class Ledger {
17
+ static async open(opts = {}) {
18
+ return new Ledger(opts.home);
19
+ }
20
+
21
+ constructor(home) {
22
+ this.home = home;
23
+ }
24
+ }
25
+
26
+ export async function ingest(opts = {}) {
27
+ return withHome(opts.ledgerHome, async () => ingestAll());
28
+ }
29
+
30
+ export async function summary(opts = {}) {
31
+ return withHome(opts.ledgerHome, async () => {
32
+ const q = { sessionId: opts.session, project: opts.project, since: opts.since };
33
+ const turns = await queryAll(q);
34
+ const pricing = await loadPricing();
35
+ const byTool = new Map();
36
+ const byModel = new Map();
37
+ let totalTokens = 0;
38
+ let totalCost = 0;
39
+
40
+ for (const t of turns) {
41
+ const c = costForTurn(t, pricing)?.total ?? 0;
42
+ const usage =
43
+ t.usage.input +
44
+ t.usage.output +
45
+ t.usage.reasoning +
46
+ t.usage.cacheRead +
47
+ t.usage.cacheCreate5m +
48
+ t.usage.cacheCreate1h;
49
+ totalTokens += usage;
50
+ totalCost += c;
51
+
52
+ const model = byModel.get(t.model) ?? { model: t.model, tokens: 0, cost: 0 };
53
+ model.tokens += usage;
54
+ model.cost += c;
55
+ byModel.set(t.model, model);
56
+
57
+ for (const call of t.toolCalls) {
58
+ const tool = byTool.get(call.name) ?? { tool: call.name, tokens: 0, cost: 0, count: 0 };
59
+ tool.tokens += usage;
60
+ tool.cost += c;
61
+ tool.count += 1;
62
+ byTool.set(call.name, tool);
63
+ }
64
+ }
65
+
66
+ return { totalTokens, totalCost, byTool: [...byTool.values()], byModel: [...byModel.values()] };
67
+ });
68
+ }
69
+
70
+ export async function hotspots(opts = {}) {
71
+ return withHome(opts.ledgerHome, async () => {
72
+ const turns = await queryAll({ sessionId: opts.session });
73
+ const userTurns = await queryUserTurns({ sessionId: opts.session });
74
+ const attribution = attributeHotspots({ turns, userTurns });
75
+
76
+ if (!opts.patterns || opts.patterns.length === 0) return attribution;
77
+
78
+ const detected = detectPatterns({ turns, userTurns, hotspots: attribution });
79
+ return findingsFromPatterns(detected).filter((f) => opts.patterns.includes(f.kind));
80
+ });
81
+ }
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@relayburn/sdk",
3
+ "version": "1.5.0",
4
+ "description": "Embeddable Relayburn SDK for in-process ingest, summary, and hotspots queries",
5
+ "type": "module",
6
+ "main": "./index.js",
7
+ "types": "./index.d.ts",
8
+ "files": [
9
+ "index.js",
10
+ "index.d.ts",
11
+ "README.md",
12
+ "CHANGELOG.md",
13
+ "package.json"
14
+ ],
15
+ "engines": {
16
+ "node": ">=22"
17
+ },
18
+ "dependencies": {
19
+ "@relayburn/analyze": "1.5.0",
20
+ "@relayburn/ledger": "1.5.0",
21
+ "@relayburn/cli": "1.5.0"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/AgentWorkforce/burn",
26
+ "directory": "packages/sdk"
27
+ },
28
+ "publishConfig": {
29
+ "access": "public"
30
+ },
31
+ "scripts": {
32
+ "build": "node -e \"process.exit(0)\""
33
+ }
34
+ }