truthguard-ai 0.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 (199) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +363 -0
  3. package/dist/Advisor/index.d.ts +78 -0
  4. package/dist/Advisor/index.d.ts.map +1 -0
  5. package/dist/Advisor/index.js +539 -0
  6. package/dist/Advisor/index.js.map +1 -0
  7. package/dist/Alerting/index.d.ts +35 -0
  8. package/dist/Alerting/index.d.ts.map +1 -0
  9. package/dist/Alerting/index.js +76 -0
  10. package/dist/Alerting/index.js.map +1 -0
  11. package/dist/Auth/index.d.ts +82 -0
  12. package/dist/Auth/index.d.ts.map +1 -0
  13. package/dist/Auth/index.js +242 -0
  14. package/dist/Auth/index.js.map +1 -0
  15. package/dist/Baseline/index.d.ts +43 -0
  16. package/dist/Baseline/index.d.ts.map +1 -0
  17. package/dist/Baseline/index.js +195 -0
  18. package/dist/Baseline/index.js.map +1 -0
  19. package/dist/Claims/index.d.ts +73 -0
  20. package/dist/Claims/index.d.ts.map +1 -0
  21. package/dist/Claims/index.js +1669 -0
  22. package/dist/Claims/index.js.map +1 -0
  23. package/dist/Client/index.d.ts +90 -0
  24. package/dist/Client/index.d.ts.map +1 -0
  25. package/dist/Client/index.js +186 -0
  26. package/dist/Client/index.js.map +1 -0
  27. package/dist/Config/index.d.ts +41 -0
  28. package/dist/Config/index.d.ts.map +1 -0
  29. package/dist/Config/index.js +129 -0
  30. package/dist/Config/index.js.map +1 -0
  31. package/dist/Coverage/index.d.ts +28 -0
  32. package/dist/Coverage/index.d.ts.map +1 -0
  33. package/dist/Coverage/index.js +134 -0
  34. package/dist/Coverage/index.js.map +1 -0
  35. package/dist/Demo/index.d.ts +16 -0
  36. package/dist/Demo/index.d.ts.map +1 -0
  37. package/dist/Demo/index.js +189 -0
  38. package/dist/Demo/index.js.map +1 -0
  39. package/dist/Gate/index.d.ts +39 -0
  40. package/dist/Gate/index.d.ts.map +1 -0
  41. package/dist/Gate/index.js +207 -0
  42. package/dist/Gate/index.js.map +1 -0
  43. package/dist/Grounding/index.d.ts +40 -0
  44. package/dist/Grounding/index.d.ts.map +1 -0
  45. package/dist/Grounding/index.js +1433 -0
  46. package/dist/Grounding/index.js.map +1 -0
  47. package/dist/L2/index.d.ts +93 -0
  48. package/dist/L2/index.d.ts.map +1 -0
  49. package/dist/L2/index.js +1773 -0
  50. package/dist/L2/index.js.map +1 -0
  51. package/dist/MCP/index.d.ts +139 -0
  52. package/dist/MCP/index.d.ts.map +1 -0
  53. package/dist/MCP/index.js +1250 -0
  54. package/dist/MCP/index.js.map +1 -0
  55. package/dist/Matchers/index.d.ts +101 -0
  56. package/dist/Matchers/index.d.ts.map +1 -0
  57. package/dist/Matchers/index.js +690 -0
  58. package/dist/Matchers/index.js.map +1 -0
  59. package/dist/Middleware/index.d.ts +146 -0
  60. package/dist/Middleware/index.d.ts.map +1 -0
  61. package/dist/Middleware/index.js +239 -0
  62. package/dist/Middleware/index.js.map +1 -0
  63. package/dist/Mode/index.d.ts +87 -0
  64. package/dist/Mode/index.d.ts.map +1 -0
  65. package/dist/Mode/index.js +117 -0
  66. package/dist/Mode/index.js.map +1 -0
  67. package/dist/Policy/index.d.ts +89 -0
  68. package/dist/Policy/index.d.ts.map +1 -0
  69. package/dist/Policy/index.js +143 -0
  70. package/dist/Policy/index.js.map +1 -0
  71. package/dist/Proxy/SessionStore.d.ts +94 -0
  72. package/dist/Proxy/SessionStore.d.ts.map +1 -0
  73. package/dist/Proxy/SessionStore.js +225 -0
  74. package/dist/Proxy/SessionStore.js.map +1 -0
  75. package/dist/Proxy/index.d.ts +166 -0
  76. package/dist/Proxy/index.d.ts.map +1 -0
  77. package/dist/Proxy/index.js +531 -0
  78. package/dist/Proxy/index.js.map +1 -0
  79. package/dist/Registry/index.d.ts +93 -0
  80. package/dist/Registry/index.d.ts.map +1 -0
  81. package/dist/Registry/index.js +818 -0
  82. package/dist/Registry/index.js.map +1 -0
  83. package/dist/Reports/index.d.ts +38 -0
  84. package/dist/Reports/index.d.ts.map +1 -0
  85. package/dist/Reports/index.js +149 -0
  86. package/dist/Reports/index.js.map +1 -0
  87. package/dist/Rules/index.d.ts +587 -0
  88. package/dist/Rules/index.d.ts.map +1 -0
  89. package/dist/Rules/index.js +6236 -0
  90. package/dist/Rules/index.js.map +1 -0
  91. package/dist/Rules/intents.d.ts +22 -0
  92. package/dist/Rules/intents.d.ts.map +1 -0
  93. package/dist/Rules/intents.js +242 -0
  94. package/dist/Rules/intents.js.map +1 -0
  95. package/dist/Runner/index.d.ts +39 -0
  96. package/dist/Runner/index.d.ts.map +1 -0
  97. package/dist/Runner/index.js +185 -0
  98. package/dist/Runner/index.js.map +1 -0
  99. package/dist/SDK/anthropic.d.ts +102 -0
  100. package/dist/SDK/anthropic.d.ts.map +1 -0
  101. package/dist/SDK/anthropic.js +425 -0
  102. package/dist/SDK/anthropic.js.map +1 -0
  103. package/dist/SDK/openai.d.ts +164 -0
  104. package/dist/SDK/openai.d.ts.map +1 -0
  105. package/dist/SDK/openai.js +557 -0
  106. package/dist/SDK/openai.js.map +1 -0
  107. package/dist/Store/index.d.ts +72 -0
  108. package/dist/Store/index.d.ts.map +1 -0
  109. package/dist/Store/index.js +136 -0
  110. package/dist/Store/index.js.map +1 -0
  111. package/dist/Telemetry/index.d.ts +84 -0
  112. package/dist/Telemetry/index.d.ts.map +1 -0
  113. package/dist/Telemetry/index.js +239 -0
  114. package/dist/Telemetry/index.js.map +1 -0
  115. package/dist/Trace/index.d.ts +219 -0
  116. package/dist/Trace/index.d.ts.map +1 -0
  117. package/dist/Trace/index.js +763 -0
  118. package/dist/Trace/index.js.map +1 -0
  119. package/dist/TraceReadiness/index.d.ts +42 -0
  120. package/dist/TraceReadiness/index.d.ts.map +1 -0
  121. package/dist/TraceReadiness/index.js +169 -0
  122. package/dist/TraceReadiness/index.js.map +1 -0
  123. package/dist/cli/index.d.ts +15 -0
  124. package/dist/cli/index.d.ts.map +1 -0
  125. package/dist/cli/index.js +807 -0
  126. package/dist/cli/index.js.map +1 -0
  127. package/dist/i18n/index.d.ts +44 -0
  128. package/dist/i18n/index.d.ts.map +1 -0
  129. package/dist/i18n/index.js +124 -0
  130. package/dist/i18n/index.js.map +1 -0
  131. package/dist/index.d.ts +55 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +218 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/thin.d.ts +39 -0
  136. package/dist/thin.d.ts.map +1 -0
  137. package/dist/thin.js +120 -0
  138. package/dist/thin.js.map +1 -0
  139. package/dist/types/index.d.ts +498 -0
  140. package/dist/types/index.d.ts.map +1 -0
  141. package/dist/types/index.js +17 -0
  142. package/dist/types/index.js.map +1 -0
  143. package/dist-npm/Alerting/index.d.ts +35 -0
  144. package/dist-npm/Alerting/index.d.ts.map +1 -0
  145. package/dist-npm/Alerting/index.js +76 -0
  146. package/dist-npm/Alerting/index.js.map +1 -0
  147. package/dist-npm/Auth/index.d.ts +82 -0
  148. package/dist-npm/Auth/index.d.ts.map +1 -0
  149. package/dist-npm/Auth/index.js +242 -0
  150. package/dist-npm/Auth/index.js.map +1 -0
  151. package/dist-npm/Client/index.d.ts +90 -0
  152. package/dist-npm/Client/index.d.ts.map +1 -0
  153. package/dist-npm/Client/index.js +186 -0
  154. package/dist-npm/Client/index.js.map +1 -0
  155. package/dist-npm/Demo/index.d.ts +16 -0
  156. package/dist-npm/Demo/index.d.ts.map +1 -0
  157. package/dist-npm/Demo/index.js +189 -0
  158. package/dist-npm/Demo/index.js.map +1 -0
  159. package/dist-npm/Middleware/index.d.ts +146 -0
  160. package/dist-npm/Middleware/index.d.ts.map +1 -0
  161. package/dist-npm/Middleware/index.js +239 -0
  162. package/dist-npm/Middleware/index.js.map +1 -0
  163. package/dist-npm/Proxy/SessionStore.d.ts +94 -0
  164. package/dist-npm/Proxy/SessionStore.d.ts.map +1 -0
  165. package/dist-npm/Proxy/SessionStore.js +225 -0
  166. package/dist-npm/Proxy/SessionStore.js.map +1 -0
  167. package/dist-npm/Proxy/index.d.ts +166 -0
  168. package/dist-npm/Proxy/index.d.ts.map +1 -0
  169. package/dist-npm/Proxy/index.js +531 -0
  170. package/dist-npm/Proxy/index.js.map +1 -0
  171. package/dist-npm/SDK/anthropic.d.ts +102 -0
  172. package/dist-npm/SDK/anthropic.d.ts.map +1 -0
  173. package/dist-npm/SDK/anthropic.js +425 -0
  174. package/dist-npm/SDK/anthropic.js.map +1 -0
  175. package/dist-npm/SDK/openai.d.ts +164 -0
  176. package/dist-npm/SDK/openai.d.ts.map +1 -0
  177. package/dist-npm/SDK/openai.js +557 -0
  178. package/dist-npm/SDK/openai.js.map +1 -0
  179. package/dist-npm/Store/index.d.ts +72 -0
  180. package/dist-npm/Store/index.d.ts.map +1 -0
  181. package/dist-npm/Store/index.js +136 -0
  182. package/dist-npm/Store/index.js.map +1 -0
  183. package/dist-npm/Telemetry/index.d.ts +84 -0
  184. package/dist-npm/Telemetry/index.d.ts.map +1 -0
  185. package/dist-npm/Telemetry/index.js +239 -0
  186. package/dist-npm/Telemetry/index.js.map +1 -0
  187. package/dist-npm/Trace/index.d.ts +219 -0
  188. package/dist-npm/Trace/index.d.ts.map +1 -0
  189. package/dist-npm/Trace/index.js +763 -0
  190. package/dist-npm/Trace/index.js.map +1 -0
  191. package/dist-npm/thin.d.ts +39 -0
  192. package/dist-npm/thin.d.ts.map +1 -0
  193. package/dist-npm/thin.js +120 -0
  194. package/dist-npm/thin.js.map +1 -0
  195. package/dist-npm/types/index.d.ts +498 -0
  196. package/dist-npm/types/index.d.ts.map +1 -0
  197. package/dist-npm/types/index.js +17 -0
  198. package/dist-npm/types/index.js.map +1 -0
  199. package/package.json +114 -0
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ /**
3
+ * Alert Dispatchers — notify when grounding scores drop.
4
+ *
5
+ * Used by warn and block modes to send notifications
6
+ * through various channels (webhook, console, custom).
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.CallbackAlertDispatcher = exports.WebhookAlertDispatcher = exports.ConsoleAlertDispatcher = void 0;
10
+ // ---------------------------------------------------------------------------
11
+ // ConsoleAlertDispatcher
12
+ // ---------------------------------------------------------------------------
13
+ /** Logs alerts to stderr with color. */
14
+ class ConsoleAlertDispatcher {
15
+ async dispatch(report, _trace) {
16
+ const score = (report.groundingScore * 100).toFixed(0);
17
+ const failures = report.detectedFailures
18
+ .map((f) => f.type)
19
+ .join(', ');
20
+ console.error(`[TruthGuard WARN] Trace ${report.traceId} scored ${score}% | ` +
21
+ `${report.claimsFailed} ungrounded claims | ` +
22
+ `Failures: ${failures || 'none'}`);
23
+ }
24
+ }
25
+ exports.ConsoleAlertDispatcher = ConsoleAlertDispatcher;
26
+ /** Posts alert payloads to a webhook URL (Slack, Discord, PagerDuty, custom). */
27
+ class WebhookAlertDispatcher {
28
+ constructor(config) {
29
+ this.config = config;
30
+ }
31
+ async dispatch(report, trace) {
32
+ const payload = {
33
+ event: 'truthguard.grounding.alert',
34
+ timestamp: new Date().toISOString(),
35
+ traceId: report.traceId,
36
+ groundingScore: report.groundingScore,
37
+ claimsTotal: report.claimsTotal,
38
+ claimsFailed: report.claimsFailed,
39
+ detectedFailures: report.detectedFailures.map((f) => ({
40
+ type: f.type,
41
+ confidence: f.confidence,
42
+ description: f.description,
43
+ })),
44
+ trace: {
45
+ traceId: trace.traceId,
46
+ stepsCount: trace.steps.length,
47
+ },
48
+ };
49
+ const res = await fetch(this.config.url, {
50
+ method: 'POST',
51
+ headers: {
52
+ 'Content-Type': 'application/json',
53
+ ...this.config.headers,
54
+ },
55
+ body: JSON.stringify(payload),
56
+ });
57
+ if (!res.ok) {
58
+ console.error(`[TruthGuard] Webhook alert failed: ${res.status} ${res.statusText}`);
59
+ }
60
+ }
61
+ }
62
+ exports.WebhookAlertDispatcher = WebhookAlertDispatcher;
63
+ // ---------------------------------------------------------------------------
64
+ // CallbackAlertDispatcher — for custom integrations
65
+ // ---------------------------------------------------------------------------
66
+ /** Calls a user-provided function. */
67
+ class CallbackAlertDispatcher {
68
+ constructor(fn) {
69
+ this.fn = fn;
70
+ }
71
+ async dispatch(report, trace) {
72
+ await this.fn(report, trace);
73
+ }
74
+ }
75
+ exports.CallbackAlertDispatcher = CallbackAlertDispatcher;
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Alerting/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAcH,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E,wCAAwC;AACxC,MAAa,sBAAsB;IACjC,KAAK,CAAC,QAAQ,CAAC,MAAuB,EAAE,MAAa;QACnD,MAAM,KAAK,GAAG,CAAC,MAAM,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB;aACrC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;aAClB,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,CAAC,KAAK,CACX,2BAA2B,MAAM,CAAC,OAAO,WAAW,KAAK,MAAM;YAC7D,GAAG,MAAM,CAAC,YAAY,uBAAuB;YAC7C,aAAa,QAAQ,IAAI,MAAM,EAAE,CACpC,CAAC;IACJ,CAAC;CACF;AAZD,wDAYC;AAaD,iFAAiF;AACjF,MAAa,sBAAsB;IAGjC,YAAY,MAAqB;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAuB,EAAE,KAAY;QAClD,MAAM,OAAO,GAAG;YACd,KAAK,EAAE,4BAA4B;YACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpD,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,WAAW,EAAE,CAAC,CAAC,WAAW;aAC3B,CAAC,CAAC;YACH,KAAK,EAAE;gBACL,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM;aAC/B;SACF,CAAC;QAEF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE;YACvC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO;aACvB;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CACX,sCAAsC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CACrE,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAzCD,wDAyCC;AAED,8EAA8E;AAC9E,oDAAoD;AACpD,8EAA8E;AAE9E,sCAAsC;AACtC,MAAa,uBAAuB;IAMlC,YACE,EAAmE;QAEnE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACf,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,MAAuB,EAAE,KAAY;QAClD,MAAM,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;CACF;AAfD,0DAeC"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Auth — API Key management and local credential storage.
3
+ *
4
+ * Stores credentials in ~/.truthguard/config.json
5
+ * Provides login flow, key validation, and session management.
6
+ */
7
+ /** Stored authentication configuration. */
8
+ export interface AuthConfig {
9
+ /** API key for the TruthGuard cloud service. */
10
+ apiKey: string;
11
+ /** API base URL. */
12
+ apiUrl: string;
13
+ /** Whether telemetry is enabled (opt-in). */
14
+ telemetryEnabled: boolean;
15
+ /** ISO-8601 timestamp when the config was created. */
16
+ createdAt: string;
17
+ /** ISO-8601 timestamp when last authenticated. */
18
+ lastAuthAt?: string;
19
+ }
20
+ /** Response from the /auth/validate endpoint. */
21
+ export interface AuthValidation {
22
+ valid: boolean;
23
+ plan?: 'free' | 'pro' | 'enterprise';
24
+ email?: string;
25
+ teamId?: string;
26
+ expiresAt?: string;
27
+ }
28
+ /** Benchmark data returned after login. */
29
+ export interface BenchmarkData {
30
+ /** User's average score (from telemetry). */
31
+ userAvgScore?: number;
32
+ /** Global average score across all users. */
33
+ globalAvgScore: number;
34
+ /** Percentile rank (0–100). */
35
+ percentile?: number;
36
+ /** Top failure types seen globally. */
37
+ topFailures: string[];
38
+ /** Personalized recommendations. */
39
+ recommendations: string[];
40
+ }
41
+ /** Load the stored auth config, or null if not logged in. */
42
+ export declare function loadAuthConfig(): AuthConfig | null;
43
+ /** Save auth config to disk. */
44
+ export declare function saveAuthConfig(config: AuthConfig): void;
45
+ /** Remove stored credentials (logout). */
46
+ export declare function clearAuthConfig(): boolean;
47
+ /** Get the API key from config or TRUTHGUARD_API_KEY env var. */
48
+ export declare function getApiKey(): string | null;
49
+ /** Get the API URL from config or TRUTHGUARD_API_URL env var. */
50
+ export declare function getApiUrl(): string;
51
+ /** Check if telemetry is enabled. */
52
+ export declare function isTelemetryEnabled(): boolean;
53
+ /**
54
+ * Validate an API key against the cloud service.
55
+ * Returns validation result or null if the service is unreachable.
56
+ */
57
+ export declare function validateApiKey(apiKey: string, apiUrl?: string): Promise<AuthValidation | null>;
58
+ /**
59
+ * Fetch benchmark data after login.
60
+ * Returns benchmark or null if unavailable.
61
+ */
62
+ export declare function fetchBenchmark(apiKey: string, apiUrl?: string): Promise<BenchmarkData | null>;
63
+ /**
64
+ * Perform the login flow:
65
+ * 1. Save API key
66
+ * 2. Validate with cloud (if reachable)
67
+ * 3. Fetch benchmark (value exchange)
68
+ *
69
+ * Returns validation + benchmark, or null if completely offline.
70
+ */
71
+ export declare function login(apiKey: string, options?: {
72
+ apiUrl?: string;
73
+ telemetry?: boolean;
74
+ }): Promise<{
75
+ validation: AuthValidation | null;
76
+ benchmark: BenchmarkData | null;
77
+ }>;
78
+ /** Logout — remove stored credentials. */
79
+ export declare function logout(): boolean;
80
+ export declare const AUTH_CONFIG_DIR: string;
81
+ export declare const AUTH_CONFIG_PATH: string;
82
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Auth/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,YAAY,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,oCAAoC;IACpC,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAYD,6DAA6D;AAC7D,wBAAgB,cAAc,IAAI,UAAU,GAAG,IAAI,CAWlD;AAED,gCAAgC;AAChC,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAMvD;AAED,0CAA0C;AAC1C,wBAAgB,eAAe,IAAI,OAAO,CAMzC;AAED,iEAAiE;AACjE,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAMzC;AAED,iEAAiE;AACjE,wBAAgB,SAAS,IAAI,MAAM,CAMlC;AAED,qCAAqC;AACrC,wBAAgB,kBAAkB,IAAI,OAAO,CAO5C;AA0DD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAkBpG;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAenG;AAED;;;;;;;GAOG;AACH,wBAAsB,KAAK,CACzB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GACjD,OAAO,CAAC;IAAE,UAAU,EAAE,cAAc,GAAG,IAAI,CAAC;IAAC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAA;CAAE,CAAC,CAoBjF;AAED,0CAA0C;AAC1C,wBAAgB,MAAM,IAAI,OAAO,CAEhC;AAMD,eAAO,MAAM,eAAe,QAAa,CAAC;AAC1C,eAAO,MAAM,gBAAgB,QAAc,CAAC"}
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ /**
3
+ * Auth — API Key management and local credential storage.
4
+ *
5
+ * Stores credentials in ~/.truthguard/config.json
6
+ * Provides login flow, key validation, and session management.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.AUTH_CONFIG_PATH = exports.AUTH_CONFIG_DIR = void 0;
43
+ exports.loadAuthConfig = loadAuthConfig;
44
+ exports.saveAuthConfig = saveAuthConfig;
45
+ exports.clearAuthConfig = clearAuthConfig;
46
+ exports.getApiKey = getApiKey;
47
+ exports.getApiUrl = getApiUrl;
48
+ exports.isTelemetryEnabled = isTelemetryEnabled;
49
+ exports.validateApiKey = validateApiKey;
50
+ exports.fetchBenchmark = fetchBenchmark;
51
+ exports.login = login;
52
+ exports.logout = logout;
53
+ const fs = __importStar(require("fs"));
54
+ const path = __importStar(require("path"));
55
+ const os = __importStar(require("os"));
56
+ const https = __importStar(require("https"));
57
+ const http = __importStar(require("http"));
58
+ // ---------------------------------------------------------------------------
59
+ // Constants
60
+ // ---------------------------------------------------------------------------
61
+ const CONFIG_DIR = path.join(os.homedir(), '.truthguard');
62
+ const CONFIG_PATH = path.join(CONFIG_DIR, 'config.json');
63
+ const DEFAULT_API_URL = 'https://api.truthguard.dev';
64
+ // ---------------------------------------------------------------------------
65
+ // Config persistence
66
+ // ---------------------------------------------------------------------------
67
+ function ensureConfigDir() {
68
+ if (!fs.existsSync(CONFIG_DIR)) {
69
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
70
+ }
71
+ }
72
+ /** Load the stored auth config, or null if not logged in. */
73
+ function loadAuthConfig() {
74
+ if (!fs.existsSync(CONFIG_PATH))
75
+ return null;
76
+ try {
77
+ const raw = fs.readFileSync(CONFIG_PATH, 'utf-8');
78
+ const parsed = JSON.parse(raw);
79
+ if (!parsed.apiKey)
80
+ return null;
81
+ return parsed;
82
+ }
83
+ catch {
84
+ return null;
85
+ }
86
+ }
87
+ /** Save auth config to disk. */
88
+ function saveAuthConfig(config) {
89
+ ensureConfigDir();
90
+ fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), {
91
+ encoding: 'utf-8',
92
+ mode: 0o600, // owner read/write only
93
+ });
94
+ }
95
+ /** Remove stored credentials (logout). */
96
+ function clearAuthConfig() {
97
+ if (fs.existsSync(CONFIG_PATH)) {
98
+ fs.unlinkSync(CONFIG_PATH);
99
+ return true;
100
+ }
101
+ return false;
102
+ }
103
+ /** Get the API key from config or TRUTHGUARD_API_KEY env var. */
104
+ function getApiKey() {
105
+ const envKey = process.env['TRUTHGUARD_API_KEY'];
106
+ if (envKey)
107
+ return envKey;
108
+ const config = loadAuthConfig();
109
+ return config?.apiKey ?? null;
110
+ }
111
+ /** Get the API URL from config or TRUTHGUARD_API_URL env var. */
112
+ function getApiUrl() {
113
+ const envUrl = process.env['TRUTHGUARD_API_URL'];
114
+ if (envUrl)
115
+ return envUrl;
116
+ const config = loadAuthConfig();
117
+ return config?.apiUrl ?? DEFAULT_API_URL;
118
+ }
119
+ /** Check if telemetry is enabled. */
120
+ function isTelemetryEnabled() {
121
+ const envFlag = process.env['TRUTHGUARD_TELEMETRY'];
122
+ if (envFlag === '0' || envFlag === 'false')
123
+ return false;
124
+ if (envFlag === '1' || envFlag === 'true')
125
+ return true;
126
+ const config = loadAuthConfig();
127
+ return config?.telemetryEnabled ?? false;
128
+ }
129
+ function request(url, options) {
130
+ return new Promise((resolve, reject) => {
131
+ const parsed = new URL(url);
132
+ const transport = parsed.protocol === 'https:' ? https : http;
133
+ const req = transport.request({
134
+ hostname: parsed.hostname,
135
+ port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),
136
+ path: parsed.pathname + parsed.search,
137
+ method: options.method,
138
+ headers: {
139
+ 'Content-Type': 'application/json',
140
+ 'User-Agent': 'truthguard-cli/0.1.0',
141
+ ...options.headers,
142
+ },
143
+ timeout: 10000,
144
+ }, (res) => {
145
+ let data = '';
146
+ res.on('data', (chunk) => (data += chunk.toString()));
147
+ res.on('end', () => {
148
+ resolve({ statusCode: res.statusCode ?? 0, body: data });
149
+ });
150
+ });
151
+ req.on('error', reject);
152
+ req.on('timeout', () => {
153
+ req.destroy();
154
+ reject(new Error('Request timeout'));
155
+ });
156
+ if (options.body) {
157
+ req.write(options.body);
158
+ }
159
+ req.end();
160
+ });
161
+ }
162
+ // ---------------------------------------------------------------------------
163
+ // Auth API calls
164
+ // ---------------------------------------------------------------------------
165
+ /**
166
+ * Validate an API key against the cloud service.
167
+ * Returns validation result or null if the service is unreachable.
168
+ */
169
+ async function validateApiKey(apiKey, apiUrl) {
170
+ const baseUrl = apiUrl ?? getApiUrl();
171
+ try {
172
+ const resp = await request(`${baseUrl}/v1/auth/validate`, {
173
+ method: 'POST',
174
+ headers: { Authorization: `Bearer ${apiKey}` },
175
+ body: JSON.stringify({ key: apiKey }),
176
+ });
177
+ if (resp.statusCode === 200) {
178
+ return JSON.parse(resp.body);
179
+ }
180
+ return { valid: false };
181
+ }
182
+ catch {
183
+ // Service unreachable — allow offline usage
184
+ return null;
185
+ }
186
+ }
187
+ /**
188
+ * Fetch benchmark data after login.
189
+ * Returns benchmark or null if unavailable.
190
+ */
191
+ async function fetchBenchmark(apiKey, apiUrl) {
192
+ const baseUrl = apiUrl ?? getApiUrl();
193
+ try {
194
+ const resp = await request(`${baseUrl}/v1/benchmark`, {
195
+ method: 'GET',
196
+ headers: { Authorization: `Bearer ${apiKey}` },
197
+ });
198
+ if (resp.statusCode === 200) {
199
+ return JSON.parse(resp.body);
200
+ }
201
+ return null;
202
+ }
203
+ catch {
204
+ return null;
205
+ }
206
+ }
207
+ /**
208
+ * Perform the login flow:
209
+ * 1. Save API key
210
+ * 2. Validate with cloud (if reachable)
211
+ * 3. Fetch benchmark (value exchange)
212
+ *
213
+ * Returns validation + benchmark, or null if completely offline.
214
+ */
215
+ async function login(apiKey, options) {
216
+ const apiUrl = options?.apiUrl ?? DEFAULT_API_URL;
217
+ const telemetryEnabled = options?.telemetry ?? true;
218
+ // Save config immediately (works offline)
219
+ saveAuthConfig({
220
+ apiKey,
221
+ apiUrl,
222
+ telemetryEnabled,
223
+ createdAt: new Date().toISOString(),
224
+ lastAuthAt: new Date().toISOString(),
225
+ });
226
+ // Validate + fetch benchmark in parallel
227
+ const [validation, benchmark] = await Promise.all([
228
+ validateApiKey(apiKey, apiUrl),
229
+ fetchBenchmark(apiKey, apiUrl),
230
+ ]);
231
+ return { validation, benchmark };
232
+ }
233
+ /** Logout — remove stored credentials. */
234
+ function logout() {
235
+ return clearAuthConfig();
236
+ }
237
+ // ---------------------------------------------------------------------------
238
+ // Config directory path (for tests)
239
+ // ---------------------------------------------------------------------------
240
+ exports.AUTH_CONFIG_DIR = CONFIG_DIR;
241
+ exports.AUTH_CONFIG_PATH = CONFIG_PATH;
242
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Auth/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Baseline Comparison
3
+ *
4
+ * Save dataset run results as a baseline snapshot, then compare future runs
5
+ * against it to detect regressions.
6
+ *
7
+ * Usage:
8
+ * ```ts
9
+ * // Save baseline after a known-good run
10
+ * const snapshot = createSnapshot(runResult, 'main');
11
+ * saveBaseline('.ai-rcp-baseline.json', snapshot);
12
+ *
13
+ * // Later, compare a new run against the baseline
14
+ * const comparison = compareToBaseline(newRunResult, snapshot, 0.02);
15
+ * if (!comparison.withinTolerance) { /* fail CI * / }
16
+ * ```
17
+ */
18
+ import type { BaselineComparison, BaselineSnapshot, DatasetRunResult } from '../types';
19
+ /**
20
+ * Create a baseline snapshot from a dataset run result.
21
+ */
22
+ export declare function createSnapshot(runResult: DatasetRunResult, label: string): BaselineSnapshot;
23
+ /**
24
+ * Save a baseline snapshot to a JSON file.
25
+ */
26
+ export declare function saveBaseline(filePath: string, snapshot: BaselineSnapshot): void;
27
+ /**
28
+ * Load a baseline snapshot from a JSON file.
29
+ */
30
+ export declare function loadBaseline(filePath: string): BaselineSnapshot;
31
+ /**
32
+ * Compare a current dataset run against a baseline snapshot.
33
+ *
34
+ * @param runResult - The current run to evaluate.
35
+ * @param baseline - The baseline snapshot to compare against.
36
+ * @param tolerance - Maximum allowed score drop (e.g. 0.02 = 2%). Default: 0.02.
37
+ */
38
+ export declare function compareToBaseline(runResult: DatasetRunResult, baseline: BaselineSnapshot, tolerance?: number): BaselineComparison;
39
+ /**
40
+ * Format a baseline comparison as a human-readable text block.
41
+ */
42
+ export declare function formatBaselineReport(comparison: BaselineComparison): string;
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Baseline/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAMlB;;GAEG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,MAAM,GACZ,gBAAgB,CAmBlB;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAE/E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAS/D;AAMD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,GAAE,MAAa,GACvB,kBAAkB,CA0DpB;AAMD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,CA0C3E"}
@@ -0,0 +1,195 @@
1
+ "use strict";
2
+ /**
3
+ * Baseline Comparison
4
+ *
5
+ * Save dataset run results as a baseline snapshot, then compare future runs
6
+ * against it to detect regressions.
7
+ *
8
+ * Usage:
9
+ * ```ts
10
+ * // Save baseline after a known-good run
11
+ * const snapshot = createSnapshot(runResult, 'main');
12
+ * saveBaseline('.ai-rcp-baseline.json', snapshot);
13
+ *
14
+ * // Later, compare a new run against the baseline
15
+ * const comparison = compareToBaseline(newRunResult, snapshot, 0.02);
16
+ * if (!comparison.withinTolerance) { /* fail CI * / }
17
+ * ```
18
+ */
19
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ var desc = Object.getOwnPropertyDescriptor(m, k);
22
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
23
+ desc = { enumerable: true, get: function() { return m[k]; } };
24
+ }
25
+ Object.defineProperty(o, k2, desc);
26
+ }) : (function(o, m, k, k2) {
27
+ if (k2 === undefined) k2 = k;
28
+ o[k2] = m[k];
29
+ }));
30
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
31
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
32
+ }) : function(o, v) {
33
+ o["default"] = v;
34
+ });
35
+ var __importStar = (this && this.__importStar) || (function () {
36
+ var ownKeys = function(o) {
37
+ ownKeys = Object.getOwnPropertyNames || function (o) {
38
+ var ar = [];
39
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
40
+ return ar;
41
+ };
42
+ return ownKeys(o);
43
+ };
44
+ return function (mod) {
45
+ if (mod && mod.__esModule) return mod;
46
+ var result = {};
47
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
48
+ __setModuleDefault(result, mod);
49
+ return result;
50
+ };
51
+ })();
52
+ Object.defineProperty(exports, "__esModule", { value: true });
53
+ exports.createSnapshot = createSnapshot;
54
+ exports.saveBaseline = saveBaseline;
55
+ exports.loadBaseline = loadBaseline;
56
+ exports.compareToBaseline = compareToBaseline;
57
+ exports.formatBaselineReport = formatBaselineReport;
58
+ const fs = __importStar(require("fs"));
59
+ // ---------------------------------------------------------------------------
60
+ // Snapshot creation
61
+ // ---------------------------------------------------------------------------
62
+ /**
63
+ * Create a baseline snapshot from a dataset run result.
64
+ */
65
+ function createSnapshot(runResult, label) {
66
+ return {
67
+ createdAt: new Date().toISOString(),
68
+ label,
69
+ averageScore: runResult.averageScore,
70
+ totalFailures: runResult.entries.reduce((sum, e) => sum + e.report.detectedFailures.length, 0),
71
+ passRate: runResult.totalEntries > 0
72
+ ? runResult.passedEntries / runResult.totalEntries
73
+ : 1.0,
74
+ entryScores: runResult.entries.map((e) => ({
75
+ name: e.name,
76
+ score: e.report.groundingScore,
77
+ failureCount: e.report.detectedFailures.length,
78
+ })),
79
+ };
80
+ }
81
+ // ---------------------------------------------------------------------------
82
+ // Persistence
83
+ // ---------------------------------------------------------------------------
84
+ /**
85
+ * Save a baseline snapshot to a JSON file.
86
+ */
87
+ function saveBaseline(filePath, snapshot) {
88
+ fs.writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');
89
+ }
90
+ /**
91
+ * Load a baseline snapshot from a JSON file.
92
+ */
93
+ function loadBaseline(filePath) {
94
+ const content = fs.readFileSync(filePath, 'utf-8');
95
+ const parsed = JSON.parse(content);
96
+ if (!parsed.label || typeof parsed.averageScore !== 'number') {
97
+ throw new Error('Invalid baseline file: missing required fields');
98
+ }
99
+ return parsed;
100
+ }
101
+ // ---------------------------------------------------------------------------
102
+ // Comparison
103
+ // ---------------------------------------------------------------------------
104
+ /**
105
+ * Compare a current dataset run against a baseline snapshot.
106
+ *
107
+ * @param runResult - The current run to evaluate.
108
+ * @param baseline - The baseline snapshot to compare against.
109
+ * @param tolerance - Maximum allowed score drop (e.g. 0.02 = 2%). Default: 0.02.
110
+ */
111
+ function compareToBaseline(runResult, baseline, tolerance = 0.02) {
112
+ const currentScore = runResult.averageScore;
113
+ const currentFailures = runResult.entries.reduce((sum, e) => sum + e.report.detectedFailures.length, 0);
114
+ const currentPassRate = runResult.totalEntries > 0
115
+ ? runResult.passedEntries / runResult.totalEntries
116
+ : 1.0;
117
+ const scoreDelta = currentScore - baseline.averageScore;
118
+ const failureDelta = currentFailures - baseline.totalFailures;
119
+ const passRateDelta = currentPassRate - baseline.passRate;
120
+ // Within tolerance if score didn't drop more than allowed
121
+ const withinTolerance = scoreDelta >= -tolerance;
122
+ // Per-entry comparison
123
+ const baselineMap = new Map(baseline.entryScores.map((e) => [e.name, e]));
124
+ const regressions = [];
125
+ const improvements = [];
126
+ for (const entry of runResult.entries) {
127
+ const base = baselineMap.get(entry.name);
128
+ if (!base)
129
+ continue; // New entry, no comparison possible
130
+ const delta = entry.report.groundingScore - base.score;
131
+ if (delta < -0.001) {
132
+ regressions.push({
133
+ name: entry.name,
134
+ baselineScore: base.score,
135
+ currentScore: entry.report.groundingScore,
136
+ delta,
137
+ });
138
+ }
139
+ else if (delta > 0.001) {
140
+ improvements.push({
141
+ name: entry.name,
142
+ baselineScore: base.score,
143
+ currentScore: entry.report.groundingScore,
144
+ delta,
145
+ });
146
+ }
147
+ }
148
+ return {
149
+ baselineLabel: baseline.label,
150
+ scoreDelta,
151
+ failureDelta,
152
+ passRateDelta,
153
+ withinTolerance,
154
+ tolerance,
155
+ regressions,
156
+ improvements,
157
+ };
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // Text report
161
+ // ---------------------------------------------------------------------------
162
+ /**
163
+ * Format a baseline comparison as a human-readable text block.
164
+ */
165
+ function formatBaselineReport(comparison) {
166
+ const lines = [];
167
+ const sign = (n) => (n >= 0 ? '+' : '');
168
+ lines.push('── Baseline Comparison ─────────────────────────────');
169
+ lines.push(`Compared to : ${comparison.baselineLabel}`);
170
+ lines.push(`Score delta : ${sign(comparison.scoreDelta)}${(comparison.scoreDelta * 100).toFixed(2)}%` +
171
+ ` (tolerance: ±${(comparison.tolerance * 100).toFixed(1)}%)`);
172
+ lines.push(`Failure delta: ${sign(comparison.failureDelta)}${comparison.failureDelta}`);
173
+ lines.push(`Pass rate Δ : ${sign(comparison.passRateDelta)}${(comparison.passRateDelta * 100).toFixed(2)}%`);
174
+ const icon = comparison.withinTolerance ? '✅' : '❌';
175
+ const label = comparison.withinTolerance
176
+ ? 'WITHIN TOLERANCE'
177
+ : 'REGRESSION DETECTED';
178
+ lines.push(`Result : ${icon} ${label}`);
179
+ if (comparison.regressions.length > 0) {
180
+ lines.push('');
181
+ lines.push(`Regressions (${comparison.regressions.length}):`);
182
+ for (const r of comparison.regressions) {
183
+ lines.push(` ↓ ${r.name}: ${(r.baselineScore * 100).toFixed(1)}% → ${(r.currentScore * 100).toFixed(1)}% (${(r.delta * 100).toFixed(2)}%)`);
184
+ }
185
+ }
186
+ if (comparison.improvements.length > 0) {
187
+ lines.push('');
188
+ lines.push(`Improvements (${comparison.improvements.length}):`);
189
+ for (const imp of comparison.improvements) {
190
+ lines.push(` ↑ ${imp.name}: ${(imp.baselineScore * 100).toFixed(1)}% → ${(imp.currentScore * 100).toFixed(1)}% (+${(imp.delta * 100).toFixed(2)}%)`);
191
+ }
192
+ }
193
+ return lines.join('\n');
194
+ }
195
+ //# sourceMappingURL=index.js.map