monora-ai 1.0.1 → 1.3.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 (65) hide show
  1. package/README.md +13 -0
  2. package/dist/ai_act_report.d.ts +66 -0
  3. package/dist/ai_act_report.d.ts.map +1 -0
  4. package/dist/ai_act_report.js +294 -0
  5. package/dist/api.d.ts +102 -0
  6. package/dist/api.d.ts.map +1 -0
  7. package/dist/api.js +125 -0
  8. package/dist/attestation.d.ts +26 -1
  9. package/dist/attestation.d.ts.map +1 -1
  10. package/dist/attestation.js +97 -12
  11. package/dist/cli.js +74 -0
  12. package/dist/config.d.ts +44 -0
  13. package/dist/config.d.ts.map +1 -1
  14. package/dist/config.js +43 -3
  15. package/dist/context.d.ts +50 -0
  16. package/dist/context.d.ts.map +1 -1
  17. package/dist/context.js +122 -2
  18. package/dist/events.d.ts +5 -0
  19. package/dist/events.d.ts.map +1 -1
  20. package/dist/events.js +17 -2
  21. package/dist/index.d.ts +10 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +55 -2
  24. package/dist/instrumentation.d.ts +7 -2
  25. package/dist/instrumentation.d.ts.map +1 -1
  26. package/dist/instrumentation.js +200 -14
  27. package/dist/lineage.d.ts +178 -0
  28. package/dist/lineage.d.ts.map +1 -0
  29. package/dist/lineage.js +313 -0
  30. package/dist/middleware/express.d.ts +61 -0
  31. package/dist/middleware/express.d.ts.map +1 -0
  32. package/dist/middleware/express.js +112 -0
  33. package/dist/propagation.d.ts +103 -0
  34. package/dist/propagation.d.ts.map +1 -0
  35. package/dist/propagation.js +214 -0
  36. package/dist/registry.d.ts +9 -0
  37. package/dist/registry.d.ts.map +1 -1
  38. package/dist/registry.js +33 -1
  39. package/dist/report.d.ts.map +1 -1
  40. package/dist/report.js +88 -25
  41. package/dist/reporting.d.ts +30 -0
  42. package/dist/reporting.d.ts.map +1 -0
  43. package/dist/reporting.js +519 -0
  44. package/dist/runtime.d.ts +78 -0
  45. package/dist/runtime.d.ts.map +1 -1
  46. package/dist/runtime.js +315 -6
  47. package/dist/signing.d.ts +106 -0
  48. package/dist/signing.d.ts.map +1 -0
  49. package/dist/signing.js +424 -0
  50. package/dist/timers.d.ts +86 -0
  51. package/dist/timers.d.ts.map +1 -0
  52. package/dist/timers.js +100 -0
  53. package/dist/traced_emitter.d.ts +97 -0
  54. package/dist/traced_emitter.d.ts.map +1 -0
  55. package/dist/traced_emitter.js +184 -0
  56. package/dist/trust_package.d.ts +22 -0
  57. package/dist/trust_package.d.ts.map +1 -0
  58. package/dist/trust_package.js +147 -0
  59. package/dist/verify.d.ts +47 -0
  60. package/dist/verify.d.ts.map +1 -1
  61. package/dist/verify.js +90 -0
  62. package/dist/wal.d.ts +91 -0
  63. package/dist/wal.d.ts.map +1 -0
  64. package/dist/wal.js +344 -0
  65. package/package.json +1 -1
@@ -41,6 +41,7 @@ exports.serializeReport = serializeReport;
41
41
  exports.computeSha256 = computeSha256;
42
42
  exports.signReportGpg = signReportGpg;
43
43
  exports.buildAttestationBundle = buildAttestationBundle;
44
+ exports.extractComplianceSummary = extractComplianceSummary;
44
45
  const crypto = __importStar(require("crypto"));
45
46
  const fs = __importStar(require("fs"));
46
47
  const os = __importStar(require("os"));
@@ -114,19 +115,103 @@ function signReportGpg(reportBytes, options) {
114
115
  }
115
116
  }
116
117
  }
117
- function buildAttestationBundle(report, reportBytes, signature) {
118
- return {
119
- bundle_version: '1.0.0',
118
+ /**
119
+ * Build attestation bundle with optional chain proof (v2.0.0 format).
120
+ *
121
+ * @param report - Compliance report
122
+ * @param reportBytes - Serialized report
123
+ * @param signature - Optional GPG signature
124
+ * @param options - Optional v2.0.0 fields (chainProof, eventsDigest, traceInfo, events)
125
+ * @returns Trust proof bundle (v2.0.0 format if chainProof provided, v1.0.0 otherwise)
126
+ */
127
+ function buildAttestationBundle(report, reportBytes, signature, options) {
128
+ const isTrustProof = options?.chainProof != null;
129
+ const bundleVersion = isTrustProof ? '2.0.0' : '1.0.0';
130
+ const bundleType = isTrustProof ? 'trust_proof' : 'compliance_report';
131
+ const bundle = {
132
+ bundle_version: bundleVersion,
133
+ bundle_type: bundleType,
120
134
  generated_at: new Date().toISOString(),
121
- report_sha256: computeSha256(reportBytes),
122
- report_json: reportBytes.toString('utf-8'),
123
- signature: {
124
- type: signature.signature_type,
125
- value: signature.signature,
126
- key_id: signature.key_id,
127
- fingerprint: signature.fingerprint,
128
- signed_at: new Date().toISOString(),
129
- },
135
+ };
136
+ // Add trace info (v2.0.0 only)
137
+ if (options?.traceInfo) {
138
+ bundle.trace_info = options.traceInfo;
139
+ }
140
+ // Add chain proof (v2.0.0 only)
141
+ if (options?.chainProof) {
142
+ bundle.chain_proof = options.chainProof;
143
+ }
144
+ // Add events digest (v2.0.0 only)
145
+ if (options?.eventsDigest) {
146
+ bundle.events_digest = options.eventsDigest;
147
+ }
148
+ // Embed raw events if provided (v2.0.0 only)
149
+ if (options?.events) {
150
+ bundle.events = options.events;
151
+ }
152
+ // Add compliance summary (v2.0.0 only)
153
+ if (isTrustProof) {
154
+ bundle.compliance_summary = extractComplianceSummary(report);
155
+ }
156
+ // Add report artifacts (v2.0.0 only)
157
+ if (isTrustProof) {
158
+ bundle.report_artifacts = report.artifacts || [];
159
+ }
160
+ // v1.0.0 format (backward compatibility)
161
+ if (!isTrustProof) {
162
+ bundle.report_sha256 = computeSha256(reportBytes);
163
+ bundle.report_json = reportBytes.toString('utf-8');
164
+ }
165
+ // Add signature if provided
166
+ if (signature) {
167
+ if (isTrustProof) {
168
+ // For v2.0.0, compute signature over entire bundle (excluding signature itself)
169
+ const payload = {};
170
+ for (const [key, value] of Object.entries(bundle)) {
171
+ if (key !== 'signature') {
172
+ payload[key] = value;
173
+ }
174
+ }
175
+ const payloadBytes = serializeReport(payload);
176
+ const payloadSha = computeSha256(payloadBytes);
177
+ bundle.signature = {
178
+ type: signature.signature_type,
179
+ value: signature.signature,
180
+ key_id: signature.key_id,
181
+ fingerprint: signature.fingerprint,
182
+ signed_at: new Date().toISOString(),
183
+ signed_payload_sha256: payloadSha,
184
+ };
185
+ }
186
+ else {
187
+ // v1.0.0 format
188
+ bundle.signature = {
189
+ type: signature.signature_type,
190
+ value: signature.signature,
191
+ key_id: signature.key_id,
192
+ fingerprint: signature.fingerprint,
193
+ signed_at: new Date().toISOString(),
194
+ };
195
+ }
196
+ }
197
+ return bundle;
198
+ }
199
+ /**
200
+ * Extract key compliance metrics for bundle.
201
+ *
202
+ * @param report - Full compliance report
203
+ * @returns Compact compliance summary
204
+ */
205
+ function extractComplianceSummary(report) {
206
+ const modelCompliance = report.model_compliance || {};
207
+ const violations = report.violations || [];
208
+ const tokenUsage = report.token_usage || {};
209
+ return {
210
+ policy_violations: Array.isArray(violations) ? violations.length : 0,
211
+ data_handling_issues: 0, // TODO: Extract from data handling events
212
+ unknown_models: modelCompliance.unknown_models_used || [],
213
+ forbidden_models_blocked: (modelCompliance.forbidden_models_blocked || []).length,
214
+ total_tokens: tokenUsage.total_tokens || 0,
130
215
  };
131
216
  }
132
217
  function findGpg() {
package/dist/cli.js CHANGED
@@ -43,8 +43,10 @@ const readline = __importStar(require("readline"));
43
43
  const yaml = __importStar(require("js-yaml"));
44
44
  const config_1 = require("./config");
45
45
  const report_1 = require("./report");
46
+ const ai_act_report_1 = require("./ai_act_report");
46
47
  const security_report_1 = require("./security_report");
47
48
  const attestation_1 = require("./attestation");
49
+ const trust_package_1 = require("./trust_package");
48
50
  const diagnostics_1 = require("./cli/diagnostics");
49
51
  function usage() {
50
52
  console.log('Usage:');
@@ -53,6 +55,8 @@ function usage() {
53
55
  console.log(' monora doctor [--config monora.yml] [--json] [--no-network]');
54
56
  console.log(' monora report --input <events.jsonl> --output <report.json> [--format json|markdown] [--config monora.yml]');
55
57
  console.log(' monora security-review --input <events.jsonl> --output <security.json> [--config monora.yml] [--sign gpg --gpg-key <id> --bundle <bundle.json>]');
58
+ console.log(' monora trust-package --input <events.jsonl> --trace-id <trace_id> --output <trust.json> [--config monora.yml] [--sign gpg --gpg-key <id>]');
59
+ console.log(' monora ai-act-report --input <events.jsonl> --output <report.json> [--format json|markdown] [--config monora.yml]');
56
60
  }
57
61
  function parseArgs(argv) {
58
62
  const args = argv.slice(2);
@@ -319,6 +323,29 @@ function parseSecurityReviewOptions(args) {
319
323
  bundle: getFlagValue(args, '--bundle'),
320
324
  };
321
325
  }
326
+ function parseTrustPackageOptions(args) {
327
+ return {
328
+ input: getFlagValue(args, '--input'),
329
+ traceId: getFlagValue(args, '--trace-id'),
330
+ output: getFlagValue(args, '--output'),
331
+ config: getFlagValue(args, '--config'),
332
+ sign: getFlagValue(args, '--sign') || undefined,
333
+ gpgKey: getFlagValue(args, '--gpg-key'),
334
+ gpgHome: getFlagValue(args, '--gpg-home'),
335
+ };
336
+ }
337
+ function parseAIActReportOptions(args) {
338
+ const input = getFlagValue(args, '--input');
339
+ const output = getFlagValue(args, '--output');
340
+ const format = getFlagValue(args, '--format') || 'json';
341
+ const config = getFlagValue(args, '--config');
342
+ return {
343
+ input,
344
+ output,
345
+ format: format === 'markdown' ? 'markdown' : 'json',
346
+ config,
347
+ };
348
+ }
322
349
  async function runReport(options) {
323
350
  if (!options.input || !options.output) {
324
351
  usage();
@@ -335,6 +362,17 @@ async function runReport(options) {
335
362
  }
336
363
  console.log(`Report generated: ${options.output}`);
337
364
  }
365
+ async function runAIActReport(options) {
366
+ if (!options.input || !options.output) {
367
+ usage();
368
+ process.exit(1);
369
+ }
370
+ const events = (0, report_1.loadJsonl)(options.input);
371
+ const config = options.config ? (0, config_1.loadConfig)({ configPath: options.config }) : (0, config_1.loadConfig)();
372
+ const report = (0, ai_act_report_1.buildAIActReport)(events, config);
373
+ (0, ai_act_report_1.writeAIActReport)(report, options.output, options.format);
374
+ console.log(`AI Act transparency report generated: ${options.output}`);
375
+ }
338
376
  async function runSecurityReview(options) {
339
377
  if (!options.input || !options.output) {
340
378
  usage();
@@ -369,6 +407,34 @@ async function runSecurityReview(options) {
369
407
  }
370
408
  console.log(`Security review report generated: ${options.output}`);
371
409
  }
410
+ async function runTrustPackage(options) {
411
+ if (!options.input || !options.output || !options.traceId) {
412
+ usage();
413
+ process.exit(1);
414
+ }
415
+ const events = (0, report_1.loadJsonl)(options.input);
416
+ const config = options.config ? (0, config_1.loadConfig)({ configPath: options.config }) : (0, config_1.loadConfig)();
417
+ let trustPackage = (0, trust_package_1.buildTrustPackage)(options.traceId, events, config);
418
+ if (options.sign) {
419
+ if (options.sign !== 'gpg') {
420
+ console.error(`Unsupported signing type: ${options.sign}`);
421
+ process.exit(1);
422
+ }
423
+ try {
424
+ trustPackage = (0, trust_package_1.applyGpgSignature)(trustPackage, {
425
+ gpgKey: options.gpgKey,
426
+ gpgHome: options.gpgHome,
427
+ });
428
+ }
429
+ catch (error) {
430
+ const message = error instanceof attestation_1.AttestationError ? error.message : String(error);
431
+ console.error(`Signing failed: ${message}`);
432
+ process.exit(1);
433
+ }
434
+ }
435
+ (0, trust_package_1.writeTrustPackage)(options.output, trustPackage);
436
+ console.log(`Trust package generated: ${options.output}`);
437
+ }
372
438
  async function runValidate(args) {
373
439
  const configPath = getFlagValue(args, '--config') || 'monora.yml';
374
440
  const asJson = hasFlag(args, '--json');
@@ -434,6 +500,14 @@ async function main() {
434
500
  await runSecurityReview(parseSecurityReviewOptions(parsed.args));
435
501
  return;
436
502
  }
503
+ if (parsed.command === 'trust-package') {
504
+ await runTrustPackage(parseTrustPackageOptions(parsed.args));
505
+ return;
506
+ }
507
+ if (parsed.command === 'ai-act-report') {
508
+ await runAIActReport(parseAIActReportOptions(parsed.args));
509
+ return;
510
+ }
437
511
  usage();
438
512
  }
439
513
  main().catch((err) => {
package/dist/config.d.ts CHANGED
@@ -17,6 +17,17 @@ export interface MonoraConfig {
17
17
  enabled?: boolean;
18
18
  scope?: 'per_trace' | 'global';
19
19
  hash_algorithm?: string;
20
+ verify_on_emit?: boolean;
21
+ verify_on_shutdown?: boolean;
22
+ persist_chain?: boolean;
23
+ };
24
+ attestation?: {
25
+ enabled?: boolean;
26
+ gpg?: {
27
+ enabled?: boolean;
28
+ key_id?: string;
29
+ gpg_home?: string;
30
+ };
20
31
  };
21
32
  registry?: any;
22
33
  instrumentation?: {
@@ -26,6 +37,16 @@ export interface MonoraConfig {
26
37
  data_classification?: string;
27
38
  reason?: string;
28
39
  fail_fast?: boolean;
40
+ log_report?: boolean;
41
+ };
42
+ reporting?: {
43
+ enabled?: boolean;
44
+ emit_trust_summary?: boolean;
45
+ output_dir?: string;
46
+ formats?: string[];
47
+ include_security_report?: boolean;
48
+ max_events_per_trace?: number;
49
+ redact_host?: boolean;
29
50
  };
30
51
  data_handling?: {
31
52
  enabled?: boolean;
@@ -59,6 +80,29 @@ export interface MonoraConfig {
59
80
  flush_interval_sec?: number;
60
81
  queue_full_timeout_sec?: number | null;
61
82
  };
83
+ wal?: {
84
+ enabled?: boolean;
85
+ path?: string;
86
+ sync_mode?: 'fsync' | 'async' | 'none';
87
+ max_file_size_mb?: number;
88
+ retention_hours?: number;
89
+ recovery_on_startup?: boolean;
90
+ };
91
+ signing?: {
92
+ enabled?: boolean;
93
+ algorithm?: 'ed25519' | 'hmac-sha256';
94
+ key_id?: string | null;
95
+ key_file?: string | null;
96
+ key_env?: string;
97
+ };
98
+ ai_act?: {
99
+ enabled?: boolean;
100
+ organization_name?: string | null;
101
+ contact_email?: string | null;
102
+ default_risk_category?: 'minimal' | 'limited' | 'high' | 'unacceptable';
103
+ generate_transparency_report?: boolean;
104
+ transparency_report_formats?: string[];
105
+ };
62
106
  }
63
107
  export declare function loadConfig(options?: {
64
108
  configPath?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE;QACT,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC,CAAC;IACH,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;QAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,eAAe,CAAC,EAAE;QAChB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;QAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,aAAa,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;KACf,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;QAC1B,yBAAyB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChD,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,cAAc,CAAC,EAAE;QACf,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;QAChD,mBAAmB,CAAC,EAAE,OAAO,CAAC;QAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;QAC7C,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxC,CAAC;CACH;AA4ED,wBAAgB,UAAU,CAAC,OAAO,CAAC,EAAE;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,YAAY,CA0Bf"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -71,6 +71,15 @@ const DEFAULT_CONFIG = {
71
71
  reason: undefined,
72
72
  fail_fast: false,
73
73
  },
74
+ reporting: {
75
+ enabled: true,
76
+ emit_trust_summary: true,
77
+ output_dir: './monora_reports',
78
+ formats: ['json'],
79
+ include_security_report: false,
80
+ max_events_per_trace: 10000,
81
+ redact_host: true,
82
+ },
74
83
  data_handling: {
75
84
  enabled: false,
76
85
  mode: 'redact',
@@ -111,6 +120,29 @@ const DEFAULT_CONFIG = {
111
120
  flush_interval_sec: 1.0,
112
121
  queue_full_timeout_sec: null,
113
122
  },
123
+ wal: {
124
+ enabled: false,
125
+ path: './monora_wal',
126
+ sync_mode: 'fsync',
127
+ max_file_size_mb: 100,
128
+ retention_hours: 24,
129
+ recovery_on_startup: true,
130
+ },
131
+ signing: {
132
+ enabled: false,
133
+ algorithm: 'ed25519',
134
+ key_id: null,
135
+ key_file: null,
136
+ key_env: 'MONORA_SIGNING_KEY',
137
+ },
138
+ ai_act: {
139
+ enabled: false,
140
+ organization_name: null,
141
+ contact_email: null,
142
+ default_risk_category: 'limited',
143
+ generate_transparency_report: true,
144
+ transparency_report_formats: ['json'],
145
+ },
114
146
  };
115
147
  function loadConfig(options) {
116
148
  const { configPath, configDict, envPrefix = 'MONORA_' } = options || {};
@@ -171,9 +203,17 @@ function envKeyToPath(key) {
171
203
  if (parts.length >= 2 && parts[0] === 'ERROR' && parts[1] === 'HANDLING') {
172
204
  return ['error_handling', ...parts.slice(2).map((p) => p.toLowerCase())];
173
205
  }
174
- const root = parts[0].toLowerCase();
175
- const rest = parts.slice(1);
176
- const path = [root];
206
+ const upperKey = key.toUpperCase();
207
+ let rest = parts.slice(1);
208
+ const path = [];
209
+ if (upperKey.startsWith('AI_ACT') ||
210
+ (parts.length >= 2 && parts[0] === 'AI' && parts[1] === 'ACT')) {
211
+ path.push('ai_act');
212
+ rest = parts.slice(2);
213
+ }
214
+ else {
215
+ path.push(parts[0].toLowerCase());
216
+ }
177
217
  const buffer = [];
178
218
  for (const part of rest) {
179
219
  if (/^\d+$/.test(part)) {
package/dist/context.d.ts CHANGED
@@ -14,6 +14,8 @@ export interface TraceContext {
14
14
  stepCounter: number;
15
15
  eventCounter: number;
16
16
  }
17
+ type TraceCompletionHandler = (span: Span) => void | Promise<void>;
18
+ export declare function registerTraceCompletionHandler(handler: TraceCompletionHandler): () => void;
17
19
  export declare function getCurrentContext(): TraceContext | undefined;
18
20
  export declare function getCurrentSpan(): Span | null;
19
21
  export declare function pushSpan(span: Span): void;
@@ -29,4 +31,52 @@ export declare function traceAsync<T>(name: string, fn: (span: Span) => Promise<
29
31
  export declare function startSpan(name: string, metadata?: Record<string, any>): Span;
30
32
  export declare function nextStepNumber(): number;
31
33
  export declare function nextEventSequence(): number | null;
34
+ /**
35
+ * Capture the current trace context for later use.
36
+ *
37
+ * This is useful for preserving context across async boundaries like
38
+ * setTimeout, setInterval, EventEmitter callbacks, or worker threads.
39
+ *
40
+ * @returns The current trace context, or undefined if no trace is active.
41
+ */
42
+ export declare function captureContext(): TraceContext | undefined;
43
+ /**
44
+ * Run a function within a specific trace context.
45
+ *
46
+ * This allows executing code as if it were inside a particular trace,
47
+ * even when called from outside that trace's async chain.
48
+ *
49
+ * @param ctx The trace context to run within (or undefined for no context).
50
+ * @param fn The function to execute.
51
+ * @returns The result of the function.
52
+ */
53
+ export declare function runInContext<T>(ctx: TraceContext | undefined, fn: () => T): T;
54
+ /**
55
+ * Bind a function to the current trace context.
56
+ *
57
+ * The returned function, when called, will execute within the captured
58
+ * trace context regardless of where it's called from. This is essential
59
+ * for preserving trace context through:
60
+ * - setTimeout/setInterval callbacks
61
+ * - EventEmitter handlers
62
+ * - process.nextTick/setImmediate callbacks
63
+ * - Any other async scheduling mechanism
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * trace('my-workflow', async (span) => {
68
+ * const boundCallback = bindContext(() => {
69
+ * // getCurrentSpan() will return the correct span here
70
+ * logEvent('delayed_action', { data: 'test' });
71
+ * });
72
+ *
73
+ * setTimeout(boundCallback, 1000);
74
+ * });
75
+ * ```
76
+ *
77
+ * @param fn The function to bind to the current context.
78
+ * @returns A wrapped function that will execute in the captured context.
79
+ */
80
+ export declare function bindContext<T extends (...args: any[]) => any>(fn: T): T;
81
+ export {};
32
82
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,wBAAgB,iBAAiB,IAAI,YAAY,GAAG,SAAS,CAE5D;AAED,wBAAgB,cAAc,IAAI,IAAI,GAAG,IAAI,CAG5C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAYzC;AAED,wBAAgB,OAAO,IAAI,IAAI,GAAG,IAAI,CAiBrC;AAED,wBAAgB,KAAK,CAAC,CAAC,EACrB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,EACrB,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAC7D,CAAC,CAkBH;AAED,wBAAsB,UAAU,CAAC,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAC7D,OAAO,CAAC,CAAC,CAAC,CAkBZ;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAe5E;AAED,wBAAgB,cAAc,IAAI,MAAM,CAOvC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAOjD"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,IAAI,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAKD,KAAK,sBAAsB,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAGnE,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,sBAAsB,GAC9B,MAAM,IAAI,CAGZ;AAED,wBAAgB,iBAAiB,IAAI,YAAY,GAAG,SAAS,CAE5D;AAED,wBAAgB,cAAc,IAAI,IAAI,GAAG,IAAI,CAG5C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAYzC;AAED,wBAAgB,OAAO,IAAI,IAAI,GAAG,IAAI,CAiBrC;AAED,wBAAgB,KAAK,CAAC,CAAC,EACrB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,CAAC,EACrB,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAC7D,CAAC,CA+BH;AAED,wBAAsB,UAAU,CAAC,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAC7D,OAAO,CAAC,CAAC,CAAC,CAwBZ;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAe5E;AAED,wBAAgB,cAAc,IAAI,MAAM,CAOvC;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAOjD;AA+BD;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,YAAY,GAAG,SAAS,CAEzD;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,YAAY,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAK7E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,CAQvE"}
package/dist/context.js CHANGED
@@ -3,6 +3,7 @@
3
3
  * Trace context propagation using AsyncLocalStorage.
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerTraceCompletionHandler = registerTraceCompletionHandler;
6
7
  exports.getCurrentContext = getCurrentContext;
7
8
  exports.getCurrentSpan = getCurrentSpan;
8
9
  exports.pushSpan = pushSpan;
@@ -12,10 +13,18 @@ exports.traceAsync = traceAsync;
12
13
  exports.startSpan = startSpan;
13
14
  exports.nextStepNumber = nextStepNumber;
14
15
  exports.nextEventSequence = nextEventSequence;
16
+ exports.captureContext = captureContext;
17
+ exports.runInContext = runInContext;
18
+ exports.bindContext = bindContext;
15
19
  const async_hooks_1 = require("async_hooks");
16
20
  const ids_1 = require("./ids");
17
21
  // AsyncLocalStorage for Node.js context propagation
18
22
  const asyncLocalStorage = new async_hooks_1.AsyncLocalStorage();
23
+ const traceCompletionHandlers = new Set();
24
+ function registerTraceCompletionHandler(handler) {
25
+ traceCompletionHandlers.add(handler);
26
+ return () => traceCompletionHandlers.delete(handler);
27
+ }
19
28
  function getCurrentContext() {
20
29
  return asyncLocalStorage.getStore();
21
30
  }
@@ -62,7 +71,21 @@ function trace(name, fn, options) {
62
71
  stepCounter: 0,
63
72
  eventCounter: 0,
64
73
  };
65
- return asyncLocalStorage.run(ctx, () => fn(span));
74
+ return asyncLocalStorage.run(ctx, () => {
75
+ let result;
76
+ try {
77
+ result = fn(span);
78
+ }
79
+ catch (error) {
80
+ runTraceCompletionHandlersSync(span);
81
+ throw error;
82
+ }
83
+ if (isPromise(result)) {
84
+ return result.finally(() => runTraceCompletionHandlers(span));
85
+ }
86
+ runTraceCompletionHandlersSync(span);
87
+ return result;
88
+ });
66
89
  }
67
90
  async function traceAsync(name, fn, options) {
68
91
  const rootTraceId = options?.traceId || (0, ids_1.generateUlid)('trc');
@@ -79,7 +102,14 @@ async function traceAsync(name, fn, options) {
79
102
  stepCounter: 0,
80
103
  eventCounter: 0,
81
104
  };
82
- return asyncLocalStorage.run(ctx, () => fn(span));
105
+ return asyncLocalStorage.run(ctx, async () => {
106
+ try {
107
+ return await fn(span);
108
+ }
109
+ finally {
110
+ await runTraceCompletionHandlers(span);
111
+ }
112
+ });
83
113
  }
84
114
  function startSpan(name, metadata) {
85
115
  const current = getCurrentSpan();
@@ -111,3 +141,93 @@ function nextEventSequence() {
111
141
  ctx.eventCounter += 1;
112
142
  return ctx.eventCounter;
113
143
  }
144
+ function runTraceCompletionHandlersSync(span) {
145
+ for (const handler of traceCompletionHandlers) {
146
+ try {
147
+ const result = handler(span);
148
+ if (result && typeof result.then === 'function') {
149
+ result.catch((error) => {
150
+ console.error(`Monora: trace completion handler failed: ${error}`);
151
+ });
152
+ }
153
+ }
154
+ catch (error) {
155
+ console.error(`Monora: trace completion handler failed: ${error}`);
156
+ }
157
+ }
158
+ }
159
+ async function runTraceCompletionHandlers(span) {
160
+ for (const handler of traceCompletionHandlers) {
161
+ try {
162
+ await handler(span);
163
+ }
164
+ catch (error) {
165
+ console.error(`Monora: trace completion handler failed: ${error}`);
166
+ }
167
+ }
168
+ }
169
+ function isPromise(value) {
170
+ return value && typeof value.then === 'function';
171
+ }
172
+ /**
173
+ * Capture the current trace context for later use.
174
+ *
175
+ * This is useful for preserving context across async boundaries like
176
+ * setTimeout, setInterval, EventEmitter callbacks, or worker threads.
177
+ *
178
+ * @returns The current trace context, or undefined if no trace is active.
179
+ */
180
+ function captureContext() {
181
+ return asyncLocalStorage.getStore();
182
+ }
183
+ /**
184
+ * Run a function within a specific trace context.
185
+ *
186
+ * This allows executing code as if it were inside a particular trace,
187
+ * even when called from outside that trace's async chain.
188
+ *
189
+ * @param ctx The trace context to run within (or undefined for no context).
190
+ * @param fn The function to execute.
191
+ * @returns The result of the function.
192
+ */
193
+ function runInContext(ctx, fn) {
194
+ if (!ctx) {
195
+ return fn();
196
+ }
197
+ return asyncLocalStorage.run(ctx, fn);
198
+ }
199
+ /**
200
+ * Bind a function to the current trace context.
201
+ *
202
+ * The returned function, when called, will execute within the captured
203
+ * trace context regardless of where it's called from. This is essential
204
+ * for preserving trace context through:
205
+ * - setTimeout/setInterval callbacks
206
+ * - EventEmitter handlers
207
+ * - process.nextTick/setImmediate callbacks
208
+ * - Any other async scheduling mechanism
209
+ *
210
+ * @example
211
+ * ```typescript
212
+ * trace('my-workflow', async (span) => {
213
+ * const boundCallback = bindContext(() => {
214
+ * // getCurrentSpan() will return the correct span here
215
+ * logEvent('delayed_action', { data: 'test' });
216
+ * });
217
+ *
218
+ * setTimeout(boundCallback, 1000);
219
+ * });
220
+ * ```
221
+ *
222
+ * @param fn The function to bind to the current context.
223
+ * @returns A wrapped function that will execute in the captured context.
224
+ */
225
+ function bindContext(fn) {
226
+ const captured = captureContext();
227
+ if (!captured) {
228
+ return fn;
229
+ }
230
+ return ((...args) => {
231
+ return runInContext(captured, () => fn(...args));
232
+ });
233
+ }
package/dist/events.d.ts CHANGED
@@ -10,6 +10,11 @@ export declare class EventBuilder {
10
10
  dataClassification?: string;
11
11
  purpose?: string;
12
12
  reason?: string;
13
+ parentEventId?: string;
14
+ inputEventIds?: string[];
15
+ promptId?: string;
16
+ templateId?: string;
17
+ dataSourceIds?: string[];
13
18
  }): Record<string, any>;
14
19
  }
15
20
  //# sourceMappingURL=events.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA6ExC,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,SAAS,CAAa;gBAElB,MAAM,EAAE,YAAY;IAWhC,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,OAAO,CAAC,EAAE;QACR,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GACA,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CA4BvB"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAqFxC,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,SAAS,CAAa;gBAElB,MAAM,EAAE,YAAY;IAWhC,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,OAAO,CAAC,EAAE;QACR,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1B,GACA,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;CA4CvB"}
package/dist/events.js CHANGED
@@ -40,6 +40,7 @@ exports.EventBuilder = void 0;
40
40
  const os = __importStar(require("os"));
41
41
  const context_1 = require("./context");
42
42
  const ids_1 = require("./ids");
43
+ const lineage_1 = require("./lineage");
43
44
  class TimestampEnricher {
44
45
  enrich(event) {
45
46
  event.timestamp = new Date().toISOString();
@@ -107,13 +108,25 @@ class EventBuilder {
107
108
  }
108
109
  build(eventType, body, options) {
109
110
  const span = (0, context_1.getCurrentSpan)();
111
+ // Auto-capture lineage from context if not explicitly provided
112
+ const effectiveParentEventId = options?.parentEventId ?? (0, lineage_1.getParentEventId)();
113
+ const effectiveInputEventIds = options?.inputEventIds ?? (0, lineage_1.getInputEvents)();
114
+ const effectivePromptId = options?.promptId ?? (0, lineage_1.getPromptId)();
115
+ const effectiveTemplateId = options?.templateId ?? (0, lineage_1.getTemplateId)();
116
+ const effectiveDataSourceIds = options?.dataSourceIds ?? (0, lineage_1.getDataSources)();
117
+ const eventId = (0, ids_1.generateUlid)('evt');
110
118
  const event = {
111
- schema_version: '1.0.0',
112
- event_id: (0, ids_1.generateUlid)('evt'),
119
+ schema_version: '1.1.0',
120
+ event_id: eventId,
113
121
  event_type: eventType,
114
122
  trace_id: span ? span.traceId : (0, ids_1.generateUlid)('trc'),
115
123
  span_id: span ? span.spanId : (0, ids_1.generateUlid)('spn'),
116
124
  parent_span_id: span ? span.parentSpanId : null,
125
+ parent_event_id: effectiveParentEventId,
126
+ input_event_ids: effectiveInputEventIds.length > 0 ? effectiveInputEventIds : [],
127
+ prompt_id: effectivePromptId,
128
+ template_id: effectiveTemplateId,
129
+ data_source_ids: effectiveDataSourceIds.length > 0 ? effectiveDataSourceIds : [],
117
130
  data_classification: options?.dataClassification || this.defaults?.data_classification || 'internal',
118
131
  purpose: options?.purpose || this.defaults?.purpose || 'general',
119
132
  reason: options?.reason || null,
@@ -126,6 +139,8 @@ class EventBuilder {
126
139
  for (const enricher of this.enrichers) {
127
140
  enricher.enrich(event);
128
141
  }
142
+ // Update current event for next event's parent_event_id
143
+ (0, lineage_1.setCurrentEvent)(eventId);
129
144
  return event;
130
145
  }
131
146
  }