elasticdash-sdk 0.2.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 (349) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +775 -0
  3. package/dist/browser-ui.d.ts +43 -0
  4. package/dist/browser-ui.d.ts.map +1 -0
  5. package/dist/browser-ui.js +246 -0
  6. package/dist/browser-ui.js.map +1 -0
  7. package/dist/capture/event.d.ts +33 -0
  8. package/dist/capture/event.d.ts.map +1 -0
  9. package/dist/capture/event.js +2 -0
  10. package/dist/capture/event.js.map +1 -0
  11. package/dist/capture/index.d.ts +4 -0
  12. package/dist/capture/index.d.ts.map +1 -0
  13. package/dist/capture/index.js +4 -0
  14. package/dist/capture/index.js.map +1 -0
  15. package/dist/capture/recorder.d.ts +24 -0
  16. package/dist/capture/recorder.d.ts.map +1 -0
  17. package/dist/capture/recorder.js +46 -0
  18. package/dist/capture/recorder.js.map +1 -0
  19. package/dist/capture/replay.d.ts +20 -0
  20. package/dist/capture/replay.d.ts.map +1 -0
  21. package/dist/capture/replay.js +47 -0
  22. package/dist/capture/replay.js.map +1 -0
  23. package/dist/ci/api-client.d.ts +38 -0
  24. package/dist/ci/api-client.d.ts.map +1 -0
  25. package/dist/ci/api-client.js +96 -0
  26. package/dist/ci/api-client.js.map +1 -0
  27. package/dist/ci/benchmark.d.ts +33 -0
  28. package/dist/ci/benchmark.d.ts.map +1 -0
  29. package/dist/ci/benchmark.js +213 -0
  30. package/dist/ci/benchmark.js.map +1 -0
  31. package/dist/ci/ed-runner.d.ts +48 -0
  32. package/dist/ci/ed-runner.d.ts.map +1 -0
  33. package/dist/ci/ed-runner.js +260 -0
  34. package/dist/ci/ed-runner.js.map +1 -0
  35. package/dist/ci/executor.d.ts +13 -0
  36. package/dist/ci/executor.d.ts.map +1 -0
  37. package/dist/ci/executor.js +542 -0
  38. package/dist/ci/executor.js.map +1 -0
  39. package/dist/ci/git-info.d.ts +17 -0
  40. package/dist/ci/git-info.d.ts.map +1 -0
  41. package/dist/ci/git-info.js +102 -0
  42. package/dist/ci/git-info.js.map +1 -0
  43. package/dist/ci/index.d.ts +6 -0
  44. package/dist/ci/index.d.ts.map +1 -0
  45. package/dist/ci/index.js +4 -0
  46. package/dist/ci/index.js.map +1 -0
  47. package/dist/ci/measurement.d.ts +9 -0
  48. package/dist/ci/measurement.d.ts.map +1 -0
  49. package/dist/ci/measurement.js +15 -0
  50. package/dist/ci/measurement.js.map +1 -0
  51. package/dist/ci/replay.d.ts +31 -0
  52. package/dist/ci/replay.d.ts.map +1 -0
  53. package/dist/ci/replay.js +96 -0
  54. package/dist/ci/replay.js.map +1 -0
  55. package/dist/ci/reporters/default.d.ts +8 -0
  56. package/dist/ci/reporters/default.d.ts.map +1 -0
  57. package/dist/ci/reporters/default.js +46 -0
  58. package/dist/ci/reporters/default.js.map +1 -0
  59. package/dist/ci/reporters/index.d.ts +8 -0
  60. package/dist/ci/reporters/index.d.ts.map +1 -0
  61. package/dist/ci/reporters/index.js +14 -0
  62. package/dist/ci/reporters/index.js.map +1 -0
  63. package/dist/ci/reporters/json.d.ts +8 -0
  64. package/dist/ci/reporters/json.d.ts.map +1 -0
  65. package/dist/ci/reporters/json.js +14 -0
  66. package/dist/ci/reporters/json.js.map +1 -0
  67. package/dist/ci/reporters/junit.d.ts +8 -0
  68. package/dist/ci/reporters/junit.d.ts.map +1 -0
  69. package/dist/ci/reporters/junit.js +48 -0
  70. package/dist/ci/reporters/junit.js.map +1 -0
  71. package/dist/ci/runner.d.ts +3 -0
  72. package/dist/ci/runner.d.ts.map +1 -0
  73. package/dist/ci/runner.js +187 -0
  74. package/dist/ci/runner.js.map +1 -0
  75. package/dist/ci/test-discovery.d.ts +5 -0
  76. package/dist/ci/test-discovery.d.ts.map +1 -0
  77. package/dist/ci/test-discovery.js +11 -0
  78. package/dist/ci/test-discovery.js.map +1 -0
  79. package/dist/ci/test-loader.d.ts +19 -0
  80. package/dist/ci/test-loader.d.ts.map +1 -0
  81. package/dist/ci/test-loader.js +149 -0
  82. package/dist/ci/test-loader.js.map +1 -0
  83. package/dist/ci/test-registry.d.ts +42 -0
  84. package/dist/ci/test-registry.d.ts.map +1 -0
  85. package/dist/ci/test-registry.js +18 -0
  86. package/dist/ci/test-registry.js.map +1 -0
  87. package/dist/ci/trace-schema.d.ts +30 -0
  88. package/dist/ci/trace-schema.d.ts.map +1 -0
  89. package/dist/ci/trace-schema.js +66 -0
  90. package/dist/ci/trace-schema.js.map +1 -0
  91. package/dist/ci/trace-writer.d.ts +16 -0
  92. package/dist/ci/trace-writer.d.ts.map +1 -0
  93. package/dist/ci/trace-writer.js +108 -0
  94. package/dist/ci/trace-writer.js.map +1 -0
  95. package/dist/ci/types.d.ts +108 -0
  96. package/dist/ci/types.d.ts.map +1 -0
  97. package/dist/ci/types.js +3 -0
  98. package/dist/ci/types.js.map +1 -0
  99. package/dist/ci/upload-client.d.ts +74 -0
  100. package/dist/ci/upload-client.d.ts.map +1 -0
  101. package/dist/ci/upload-client.js +195 -0
  102. package/dist/ci/upload-client.js.map +1 -0
  103. package/dist/cli.d.ts +3 -0
  104. package/dist/cli.d.ts.map +1 -0
  105. package/dist/cli.js +716 -0
  106. package/dist/cli.js.map +1 -0
  107. package/dist/core/agent-state.d.ts +47 -0
  108. package/dist/core/agent-state.d.ts.map +1 -0
  109. package/dist/core/agent-state.js +137 -0
  110. package/dist/core/agent-state.js.map +1 -0
  111. package/dist/core/judge-utils.d.ts +22 -0
  112. package/dist/core/judge-utils.d.ts.map +1 -0
  113. package/dist/core/judge-utils.js +211 -0
  114. package/dist/core/judge-utils.js.map +1 -0
  115. package/dist/core/registry.d.ts +28 -0
  116. package/dist/core/registry.d.ts.map +1 -0
  117. package/dist/core/registry.js +52 -0
  118. package/dist/core/registry.js.map +1 -0
  119. package/dist/dashboard-server.d.ts +65 -0
  120. package/dist/dashboard-server.d.ts.map +1 -0
  121. package/dist/dashboard-server.js +3940 -0
  122. package/dist/dashboard-server.js.map +1 -0
  123. package/dist/execution/tool-runner.d.ts +26 -0
  124. package/dist/execution/tool-runner.d.ts.map +1 -0
  125. package/dist/execution/tool-runner.js +316 -0
  126. package/dist/execution/tool-runner.js.map +1 -0
  127. package/dist/html/dashboard.html +2218 -0
  128. package/dist/http.d.ts +14 -0
  129. package/dist/http.d.ts.map +1 -0
  130. package/dist/http.js +13 -0
  131. package/dist/http.js.map +1 -0
  132. package/dist/index.cjs +8102 -0
  133. package/dist/index.d.ts +61 -0
  134. package/dist/index.d.ts.map +1 -0
  135. package/dist/index.js +67 -0
  136. package/dist/index.js.map +1 -0
  137. package/dist/interceptors/ai-interceptor.d.ts +26 -0
  138. package/dist/interceptors/ai-interceptor.d.ts.map +1 -0
  139. package/dist/interceptors/ai-interceptor.js +756 -0
  140. package/dist/interceptors/ai-interceptor.js.map +1 -0
  141. package/dist/interceptors/db-auto.d.ts +8 -0
  142. package/dist/interceptors/db-auto.d.ts.map +1 -0
  143. package/dist/interceptors/db-auto.js +217 -0
  144. package/dist/interceptors/db-auto.js.map +1 -0
  145. package/dist/interceptors/db.d.ts +23 -0
  146. package/dist/interceptors/db.d.ts.map +1 -0
  147. package/dist/interceptors/db.js +137 -0
  148. package/dist/interceptors/db.js.map +1 -0
  149. package/dist/interceptors/http.d.ts +28 -0
  150. package/dist/interceptors/http.d.ts.map +1 -0
  151. package/dist/interceptors/http.js +356 -0
  152. package/dist/interceptors/http.js.map +1 -0
  153. package/dist/interceptors/side-effects.d.ts +7 -0
  154. package/dist/interceptors/side-effects.d.ts.map +1 -0
  155. package/dist/interceptors/side-effects.js +72 -0
  156. package/dist/interceptors/side-effects.js.map +1 -0
  157. package/dist/interceptors/telemetry-push.d.ts +142 -0
  158. package/dist/interceptors/telemetry-push.d.ts.map +1 -0
  159. package/dist/interceptors/telemetry-push.js +463 -0
  160. package/dist/interceptors/telemetry-push.js.map +1 -0
  161. package/dist/interceptors/tool.d.ts +2 -0
  162. package/dist/interceptors/tool.d.ts.map +1 -0
  163. package/dist/interceptors/tool.js +274 -0
  164. package/dist/interceptors/tool.js.map +1 -0
  165. package/dist/interceptors/workflow-ai.d.ts +5 -0
  166. package/dist/interceptors/workflow-ai.d.ts.map +1 -0
  167. package/dist/interceptors/workflow-ai.js +382 -0
  168. package/dist/interceptors/workflow-ai.js.map +1 -0
  169. package/dist/internals/conditional-recorder.d.ts +21 -0
  170. package/dist/internals/conditional-recorder.d.ts.map +1 -0
  171. package/dist/internals/conditional-recorder.js +54 -0
  172. package/dist/internals/conditional-recorder.js.map +1 -0
  173. package/dist/internals/mock-resolver.d.ts +146 -0
  174. package/dist/internals/mock-resolver.d.ts.map +1 -0
  175. package/dist/internals/mock-resolver.js +427 -0
  176. package/dist/internals/mock-resolver.js.map +1 -0
  177. package/dist/matchers/index.d.ts +96 -0
  178. package/dist/matchers/index.d.ts.map +1 -0
  179. package/dist/matchers/index.js +668 -0
  180. package/dist/matchers/index.js.map +1 -0
  181. package/dist/observability.d.ts +82 -0
  182. package/dist/observability.d.ts.map +1 -0
  183. package/dist/observability.js +471 -0
  184. package/dist/observability.js.map +1 -0
  185. package/dist/portal-executor.d.ts +30 -0
  186. package/dist/portal-executor.d.ts.map +1 -0
  187. package/dist/portal-executor.js +324 -0
  188. package/dist/portal-executor.js.map +1 -0
  189. package/dist/portal-server.d.ts +3 -0
  190. package/dist/portal-server.d.ts.map +1 -0
  191. package/dist/portal-server.js +279 -0
  192. package/dist/portal-server.js.map +1 -0
  193. package/dist/proxy/llm-capture.d.ts +14 -0
  194. package/dist/proxy/llm-capture.d.ts.map +1 -0
  195. package/dist/proxy/llm-capture.js +264 -0
  196. package/dist/proxy/llm-capture.js.map +1 -0
  197. package/dist/reporter.d.ts +3 -0
  198. package/dist/reporter.d.ts.map +1 -0
  199. package/dist/reporter.js +72 -0
  200. package/dist/reporter.js.map +1 -0
  201. package/dist/runWorkflowSubprocess.d.ts +14 -0
  202. package/dist/runWorkflowSubprocess.d.ts.map +1 -0
  203. package/dist/runWorkflowSubprocess.js +66 -0
  204. package/dist/runWorkflowSubprocess.js.map +1 -0
  205. package/dist/runner.d.ts +16 -0
  206. package/dist/runner.d.ts.map +1 -0
  207. package/dist/runner.js +138 -0
  208. package/dist/runner.js.map +1 -0
  209. package/dist/socket-connector.d.ts +22 -0
  210. package/dist/socket-connector.d.ts.map +1 -0
  211. package/dist/socket-connector.js +104 -0
  212. package/dist/socket-connector.js.map +1 -0
  213. package/dist/telemetry-batcher.d.ts +56 -0
  214. package/dist/telemetry-batcher.d.ts.map +1 -0
  215. package/dist/telemetry-batcher.js +143 -0
  216. package/dist/telemetry-batcher.js.map +1 -0
  217. package/dist/test-setup.d.ts +12 -0
  218. package/dist/test-setup.d.ts.map +1 -0
  219. package/dist/test-setup.js +13 -0
  220. package/dist/test-setup.js.map +1 -0
  221. package/dist/tool-registry.d.ts +31 -0
  222. package/dist/tool-registry.d.ts.map +1 -0
  223. package/dist/tool-registry.js +73 -0
  224. package/dist/tool-registry.js.map +1 -0
  225. package/dist/tool-runner-worker.d.ts +2 -0
  226. package/dist/tool-runner-worker.d.ts.map +1 -0
  227. package/dist/tool-runner-worker.js +215 -0
  228. package/dist/tool-runner-worker.js.map +1 -0
  229. package/dist/trace-adapter/context.d.ts +72 -0
  230. package/dist/trace-adapter/context.d.ts.map +1 -0
  231. package/dist/trace-adapter/context.js +80 -0
  232. package/dist/trace-adapter/context.js.map +1 -0
  233. package/dist/tracing.d.ts +2 -0
  234. package/dist/tracing.d.ts.map +1 -0
  235. package/dist/tracing.js +59 -0
  236. package/dist/tracing.js.map +1 -0
  237. package/dist/trigger-executor.d.ts +12 -0
  238. package/dist/trigger-executor.d.ts.map +1 -0
  239. package/dist/trigger-executor.js +130 -0
  240. package/dist/trigger-executor.js.map +1 -0
  241. package/dist/types/portal.d.ts +76 -0
  242. package/dist/types/portal.d.ts.map +1 -0
  243. package/dist/types/portal.js +2 -0
  244. package/dist/types/portal.js.map +1 -0
  245. package/dist/utils/debug.d.ts +3 -0
  246. package/dist/utils/debug.d.ts.map +1 -0
  247. package/dist/utils/debug.js +8 -0
  248. package/dist/utils/debug.js.map +1 -0
  249. package/dist/utils/license-error.d.ts +23 -0
  250. package/dist/utils/license-error.d.ts.map +1 -0
  251. package/dist/utils/license-error.js +42 -0
  252. package/dist/utils/license-error.js.map +1 -0
  253. package/dist/utils/redact.d.ts +7 -0
  254. package/dist/utils/redact.d.ts.map +1 -0
  255. package/dist/utils/redact.js +26 -0
  256. package/dist/utils/redact.js.map +1 -0
  257. package/dist/workflow-runner-worker.d.ts +2 -0
  258. package/dist/workflow-runner-worker.d.ts.map +1 -0
  259. package/dist/workflow-runner-worker.js +329 -0
  260. package/dist/workflow-runner-worker.js.map +1 -0
  261. package/dist/workflow-runner.d.ts +14 -0
  262. package/dist/workflow-runner.d.ts.map +1 -0
  263. package/dist/workflow-runner.js +34 -0
  264. package/dist/workflow-runner.js.map +1 -0
  265. package/docs/agent-coding-instructions.md +138 -0
  266. package/docs/agent-integration-guide.md +564 -0
  267. package/docs/agents.md +140 -0
  268. package/docs/dashboard.md +394 -0
  269. package/docs/deno.md +69 -0
  270. package/docs/instrumentation.md +424 -0
  271. package/docs/langfuse-trace-structure.md +145 -0
  272. package/docs/matchers.md +173 -0
  273. package/docs/observability_contract.md +192 -0
  274. package/docs/observability_mode.md +195 -0
  275. package/docs/quickstart.md +621 -0
  276. package/docs/security-compliance.md +566 -0
  277. package/docs/test-writing-guidelines.md +444 -0
  278. package/docs/tools.md +165 -0
  279. package/docs/workflow-modes.md +253 -0
  280. package/package.json +76 -0
  281. package/src/browser-ui.ts +281 -0
  282. package/src/capture/event.ts +30 -0
  283. package/src/capture/index.ts +3 -0
  284. package/src/capture/recorder.ts +62 -0
  285. package/src/capture/replay.ts +55 -0
  286. package/src/ci/api-client.ts +136 -0
  287. package/src/ci/benchmark.ts +257 -0
  288. package/src/ci/ed-runner.ts +351 -0
  289. package/src/ci/executor.ts +671 -0
  290. package/src/ci/git-info.ts +127 -0
  291. package/src/ci/index.ts +5 -0
  292. package/src/ci/measurement.ts +25 -0
  293. package/src/ci/replay.ts +127 -0
  294. package/src/ci/reporters/default.ts +50 -0
  295. package/src/ci/reporters/index.ts +21 -0
  296. package/src/ci/reporters/json.ts +18 -0
  297. package/src/ci/reporters/junit.ts +61 -0
  298. package/src/ci/runner.ts +208 -0
  299. package/src/ci/test-discovery.ts +16 -0
  300. package/src/ci/test-loader.ts +187 -0
  301. package/src/ci/test-registry.ts +62 -0
  302. package/src/ci/trace-schema.ts +96 -0
  303. package/src/ci/trace-writer.ts +107 -0
  304. package/src/ci/types.ts +115 -0
  305. package/src/ci/upload-client.ts +300 -0
  306. package/src/cli.ts +811 -0
  307. package/src/core/agent-state.ts +162 -0
  308. package/src/core/judge-utils.ts +232 -0
  309. package/src/core/registry.ts +92 -0
  310. package/src/dashboard-server.ts +2047 -0
  311. package/src/execution/tool-runner.ts +352 -0
  312. package/src/html/dashboard.html +2218 -0
  313. package/src/http.ts +13 -0
  314. package/src/index.ts +138 -0
  315. package/src/interceptors/ai-interceptor.ts +798 -0
  316. package/src/interceptors/db-auto.ts +243 -0
  317. package/src/interceptors/db.ts +156 -0
  318. package/src/interceptors/http.ts +393 -0
  319. package/src/interceptors/side-effects.ts +83 -0
  320. package/src/interceptors/telemetry-push.ts +537 -0
  321. package/src/interceptors/tool.ts +287 -0
  322. package/src/interceptors/workflow-ai.ts +419 -0
  323. package/src/internals/conditional-recorder.ts +63 -0
  324. package/src/internals/mock-resolver.ts +492 -0
  325. package/src/matchers/index.ts +824 -0
  326. package/src/observability.ts +501 -0
  327. package/src/portal-executor.ts +355 -0
  328. package/src/portal-server.ts +304 -0
  329. package/src/proxy/llm-capture.ts +301 -0
  330. package/src/reporter.ts +81 -0
  331. package/src/runWorkflowSubprocess.ts +74 -0
  332. package/src/runner.ts +178 -0
  333. package/src/socket-connector.ts +117 -0
  334. package/src/telemetry-batcher.ts +191 -0
  335. package/src/test-setup.ts +16 -0
  336. package/src/tool-registry.ts +94 -0
  337. package/src/tool-runner-worker.ts +244 -0
  338. package/src/trace-adapter/context.ts +156 -0
  339. package/src/tracing.ts +62 -0
  340. package/src/trigger-executor.ts +171 -0
  341. package/src/types/agent.d.ts +63 -0
  342. package/src/types/expect.d.ts +81 -0
  343. package/src/types/modules.d.ts +2 -0
  344. package/src/types/portal.ts +69 -0
  345. package/src/utils/debug.ts +8 -0
  346. package/src/utils/license-error.ts +43 -0
  347. package/src/utils/redact.ts +25 -0
  348. package/src/workflow-runner-worker.ts +386 -0
  349. package/src/workflow-runner.ts +58 -0
@@ -0,0 +1,187 @@
1
+ import chalk from 'chalk';
2
+ import { fetchTestGroups, submitTestRun, createBatch } from './api-client.js';
3
+ import { executeTest } from './executor.js';
4
+ import { detectGitInfo } from './git-info.js';
5
+ // ─── CI Runner ───────────────────────────────────────────────
6
+ // Orchestrates the full CI/CD test flow:
7
+ // 1. Fetch test groups from backend
8
+ // 2. Execute each test
9
+ // 3. Submit results
10
+ // 4. Create batch
11
+ // 5. Print summary
12
+ export async function runCI(config) {
13
+ const { serverUrl, apiKey } = config;
14
+ const cwd = process.cwd();
15
+ // Debug: log config so CI logs show what was received
16
+ console.log(`[elasticdash ci] serverUrl: ${serverUrl || '(not set)'}`);
17
+ console.log(`[elasticdash ci] apiKey: ${apiKey ? apiKey.substring(0, 7) + '...' + apiKey.substring(apiKey.length - 4) : '(not set)'}`);
18
+ // Merge explicit git info with auto-detected CI env
19
+ const detected = detectGitInfo();
20
+ const gitBranch = config.gitBranch || detected.branch;
21
+ const gitCommit = config.gitCommit || detected.commit;
22
+ const gitCommitMessage = config.gitCommitMessage || detected.commitMessage;
23
+ const gitPrNumber = config.gitPrNumber || detected.prNumber;
24
+ const gitPrUrl = config.gitPrUrl || detected.prUrl;
25
+ const triggeredBy = config.triggeredBy || 'ci';
26
+ const overallStart = Date.now();
27
+ // Step 1: Fetch test groups
28
+ console.log(chalk.cyan('\n[elasticdash ci] Fetching test groups...'));
29
+ const testGroups = await fetchTestGroups(serverUrl, apiKey, {
30
+ workflowName: config.workflowName,
31
+ tags: config.tags,
32
+ });
33
+ if (testGroups.length === 0) {
34
+ console.log(chalk.yellow('[elasticdash ci] No active test groups found.'));
35
+ return {
36
+ total: 0, passed: 0, failed: 0, skipped: 0,
37
+ durationMs: Date.now() - overallStart,
38
+ batchId: null,
39
+ results: [],
40
+ };
41
+ }
42
+ const totalTests = testGroups.reduce((sum, g) => sum + g.tests.length, 0);
43
+ console.log(chalk.cyan(`[elasticdash ci] Found ${testGroups.length} test group(s), ${totalTests} test(s) total.\n`));
44
+ // Step 2 & 3: Execute and submit
45
+ const allResults = [];
46
+ const runIds = [];
47
+ for (const group of testGroups) {
48
+ console.log(chalk.white.bold(` ${group.name}`) + chalk.gray(` (${group.tests.length} tests)`));
49
+ for (const test of group.tests) {
50
+ const testLabel = test.name || `${test.test_type}:${test.target_step_name || 'unnamed'}`;
51
+ process.stdout.write(chalk.gray(` ${testLabel} ... `));
52
+ const testStart = Date.now();
53
+ let testResult;
54
+ try {
55
+ const execution = await executeTest(test, cwd);
56
+ // Submit result to backend
57
+ const payload = {
58
+ testGroupTestId: test.id,
59
+ triggeredBy,
60
+ passed: execution.passed,
61
+ summary: execution.passed ? 'Passed' : 'Failed',
62
+ gitBranch, gitCommit, gitCommitMessage, gitPrNumber, gitPrUrl,
63
+ singleRuns: execution.singleRuns,
64
+ expectationResults: execution.expectationResults,
65
+ startedAt: new Date(testStart).toISOString(),
66
+ completedAt: new Date().toISOString(),
67
+ };
68
+ let runId = null;
69
+ try {
70
+ const submitted = await submitTestRun(serverUrl, apiKey, group.id, payload);
71
+ runId = submitted.id;
72
+ runIds.push(runId);
73
+ }
74
+ catch (submitErr) {
75
+ // Non-fatal: log but don't fail the test
76
+ console.error(chalk.yellow(`\n [warn] Failed to submit result: ${submitErr instanceof Error ? submitErr.message : String(submitErr)}`));
77
+ }
78
+ testResult = {
79
+ testGroupId: group.id,
80
+ testGroupName: group.name,
81
+ testId: test.id,
82
+ testName: test.name,
83
+ testType: test.test_type,
84
+ passed: execution.passed,
85
+ runId,
86
+ singleRuns: execution.singleRuns,
87
+ expectationResults: execution.expectationResults,
88
+ durationMs: execution.durationMs,
89
+ };
90
+ }
91
+ catch (err) {
92
+ testResult = {
93
+ testGroupId: group.id,
94
+ testGroupName: group.name,
95
+ testId: test.id,
96
+ testName: test.name,
97
+ testType: test.test_type,
98
+ passed: false,
99
+ runId: null,
100
+ singleRuns: [],
101
+ expectationResults: [],
102
+ error: err instanceof Error ? err.message : String(err),
103
+ durationMs: Date.now() - testStart,
104
+ };
105
+ }
106
+ allResults.push(testResult);
107
+ // Print result
108
+ const durationStr = chalk.gray(`(${testResult.durationMs}ms)`);
109
+ if (testResult.passed) {
110
+ console.log(chalk.green('PASS') + ` ${durationStr}`);
111
+ }
112
+ else {
113
+ console.log(chalk.red('FAIL') + ` ${durationStr}`);
114
+ if (testResult.error) {
115
+ console.log(chalk.red(` ${testResult.error}`));
116
+ }
117
+ // Show errors from individual single runs
118
+ for (const run of testResult.singleRuns) {
119
+ if (!run.passed && run.error) {
120
+ console.log(chalk.red(` [run ${run.runIndex}] ${run.error}`));
121
+ }
122
+ }
123
+ // Show failed expectations
124
+ for (const exp of testResult.expectationResults) {
125
+ if (!exp.passed) {
126
+ console.log(chalk.red(` [${exp.type}] ${exp.detail || 'failed'}`));
127
+ }
128
+ }
129
+ }
130
+ }
131
+ console.log(); // blank line between groups
132
+ }
133
+ // Step 4: Create batch
134
+ let batchId = null;
135
+ if (runIds.length > 0) {
136
+ try {
137
+ const passedCount = allResults.filter((r) => r.passed).length;
138
+ const allPassed = passedCount === allResults.length;
139
+ const batch = await createBatch(serverUrl, apiKey, {
140
+ testGroupRunIds: runIds,
141
+ status: allPassed ? 'success' : 'failed',
142
+ passed: allPassed,
143
+ summary: `CI: ${passedCount}/${allResults.length} passed`,
144
+ gitBranch, gitCommit,
145
+ startedAt: new Date(overallStart).toISOString(),
146
+ completedAt: new Date().toISOString(),
147
+ });
148
+ batchId = batch.id;
149
+ }
150
+ catch {
151
+ // Non-fatal
152
+ }
153
+ }
154
+ // Step 5: Print summary
155
+ const passed = allResults.filter((r) => r.passed).length;
156
+ const failed = allResults.filter((r) => !r.passed).length;
157
+ const durationMs = Date.now() - overallStart;
158
+ console.log(chalk.white.bold('─'.repeat(50)));
159
+ console.log(chalk.white.bold('Summary'));
160
+ console.log(chalk.white.bold('─'.repeat(50)));
161
+ console.log(` Total: ${allResults.length}`);
162
+ console.log(` ${chalk.green(`Passed: ${passed}`)}`);
163
+ if (failed > 0) {
164
+ console.log(` ${chalk.red(`Failed: ${failed}`)}`);
165
+ }
166
+ console.log(` Duration: ${(durationMs / 1000).toFixed(1)}s`);
167
+ if (batchId) {
168
+ console.log(` Batch ID: ${batchId}`);
169
+ }
170
+ console.log(chalk.white.bold('─'.repeat(50)));
171
+ if (failed > 0) {
172
+ console.log(chalk.red(`\n[elasticdash ci] ${failed} test(s) failed.\n`));
173
+ }
174
+ else {
175
+ console.log(chalk.green(`\n[elasticdash ci] All tests passed.\n`));
176
+ }
177
+ return {
178
+ total: allResults.length,
179
+ passed,
180
+ failed,
181
+ skipped: 0,
182
+ durationMs,
183
+ batchId,
184
+ results: allResults,
185
+ };
186
+ }
187
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/ci/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface DiscoverOptions {
2
+ cwd?: string;
3
+ }
4
+ export declare function discoverTestFiles(options?: DiscoverOptions): Promise<string[]>;
5
+ //# sourceMappingURL=test-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-discovery.d.ts","sourceRoot":"","sources":["../../src/ci/test-discovery.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,wBAAsB,iBAAiB,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQpF"}
@@ -0,0 +1,11 @@
1
+ import fg from 'fast-glob';
2
+ export async function discoverTestFiles(options) {
3
+ const cwd = options?.cwd ?? process.cwd();
4
+ const files = await fg('**/ed_tests.{ts,js}', {
5
+ cwd,
6
+ absolute: true,
7
+ ignore: ['**/node_modules/**', '**/.git/**', '**/.ed_traces/**'],
8
+ });
9
+ return files.sort();
10
+ }
11
+ //# sourceMappingURL=test-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-discovery.js","sourceRoot":"","sources":["../../src/ci/test-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,WAAW,CAAA;AAO1B,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAyB;IAC/D,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IACzC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,qBAAqB,EAAE;QAC5C,GAAG;QACH,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,CAAC,oBAAoB,EAAE,YAAY,EAAE,kBAAkB,CAAC;KACjE,CAAC,CAAA;IACF,OAAO,KAAK,CAAC,IAAI,EAAE,CAAA;AACrB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { TestDefinition } from './test-registry.js';
2
+ import type { DiskTrace } from './trace-schema.js';
3
+ export interface ValidatedTest extends TestDefinition {
4
+ resolvedTracePath: string;
5
+ traceData: DiskTrace;
6
+ }
7
+ export interface ValidationError {
8
+ file: string;
9
+ testName?: string;
10
+ message: string;
11
+ }
12
+ export interface LoadTestsResult {
13
+ tests: ValidatedTest[];
14
+ errors: ValidationError[];
15
+ }
16
+ export declare function loadTests(options?: {
17
+ cwd?: string;
18
+ }): Promise<LoadTestsResult>;
19
+ //# sourceMappingURL=test-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-loader.d.ts","sourceRoot":"","sources":["../../src/ci/test-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAElD,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,iBAAiB,EAAE,MAAM,CAAA;IACzB,SAAS,EAAE,SAAS,CAAA;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,EAAE,CAAA;IACtB,MAAM,EAAE,eAAe,EAAE,CAAA;CAC1B;AAED,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,eAAe,CAAC,CAkKpF"}
@@ -0,0 +1,149 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { resolve, dirname } from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { discoverTestFiles } from './test-discovery.js';
5
+ import { getTestRegistry, clearTestRegistry } from './test-registry.js';
6
+ export async function loadTests(options) {
7
+ const cwd = options?.cwd ?? process.cwd();
8
+ const files = await discoverTestFiles({ cwd });
9
+ const allDefinitions = [];
10
+ const errors = [];
11
+ // Phase 1: import each test file and collect definitions
12
+ for (const file of files) {
13
+ clearTestRegistry();
14
+ try {
15
+ // Cache-bust so re-imports within the same process re-execute the module
16
+ const fileUrl = pathToFileURL(file).href + `?t=${Date.now()}`;
17
+ await import(fileUrl);
18
+ }
19
+ catch (err) {
20
+ errors.push({
21
+ file,
22
+ message: `Failed to import test file: ${err instanceof Error ? err.message : String(err)}`,
23
+ });
24
+ continue;
25
+ }
26
+ const defs = getTestRegistry();
27
+ for (const def of defs) {
28
+ def._sourceFile = file;
29
+ }
30
+ allDefinitions.push(...defs);
31
+ }
32
+ clearTestRegistry();
33
+ // Phase 2: validate definitions
34
+ const tests = [];
35
+ const seenNames = new Map(); // name → source file
36
+ for (const def of allDefinitions) {
37
+ const file = def._sourceFile;
38
+ // Validate name
39
+ if (!def.name || typeof def.name !== 'string' || def.name.trim().length === 0) {
40
+ errors.push({ file, testName: def.name, message: 'Test name must be a non-empty string' });
41
+ continue;
42
+ }
43
+ // Check uniqueness
44
+ if (seenNames.has(def.name)) {
45
+ errors.push({
46
+ file,
47
+ testName: def.name,
48
+ message: `Duplicate test name "${def.name}" (also defined in ${seenNames.get(def.name)})`,
49
+ });
50
+ continue;
51
+ }
52
+ seenNames.set(def.name, file);
53
+ // Resolve trace path relative to the test file's directory
54
+ const resolvedTracePath = resolve(dirname(file), def.trace);
55
+ // Read and parse trace file
56
+ let traceData;
57
+ try {
58
+ const raw = await readFile(resolvedTracePath, 'utf-8');
59
+ traceData = JSON.parse(raw);
60
+ }
61
+ catch (err) {
62
+ errors.push({
63
+ file,
64
+ testName: def.name,
65
+ message: `Cannot read/parse trace file "${def.trace}": ${err instanceof Error ? err.message : String(err)}`,
66
+ });
67
+ continue;
68
+ }
69
+ // Validate trace has steps array
70
+ if (!Array.isArray(traceData.steps)) {
71
+ errors.push({ file, testName: def.name, message: `Trace file "${def.trace}" has no steps array` });
72
+ continue;
73
+ }
74
+ // Validate target
75
+ if (!def.target || !def.target.step_id || !def.target.type) {
76
+ errors.push({ file, testName: def.name, message: 'Target must have type and step_id' });
77
+ continue;
78
+ }
79
+ const matchedStep = traceData.steps.find(s => s.step_id === def.target.step_id);
80
+ if (!matchedStep) {
81
+ errors.push({
82
+ file,
83
+ testName: def.name,
84
+ message: `step_id "${def.target.step_id}" not found in trace "${def.trace}"`,
85
+ });
86
+ continue;
87
+ }
88
+ if (matchedStep.type !== def.target.type) {
89
+ errors.push({
90
+ file,
91
+ testName: def.name,
92
+ message: `target.type "${def.target.type}" does not match step type "${matchedStep.type}" for step_id "${def.target.step_id}"`,
93
+ });
94
+ continue;
95
+ }
96
+ // Validate benchmarks
97
+ if (!def.benchmarks || typeof def.benchmarks !== 'object') {
98
+ errors.push({ file, testName: def.name, message: 'Benchmarks must be specified' });
99
+ continue;
100
+ }
101
+ const hasMaxDuration = def.benchmarks.max_duration_ms !== undefined;
102
+ const hasMaxTokens = def.benchmarks.max_tokens_total !== undefined;
103
+ const hasOutputContains = def.benchmarks.output_contains !== undefined;
104
+ const hasOutputNotContains = def.benchmarks.output_not_contains !== undefined;
105
+ const hasLLMJudge = def.benchmarks.llm_judge !== undefined;
106
+ if (!hasMaxDuration && !hasMaxTokens && !hasOutputContains && !hasOutputNotContains && !hasLLMJudge) {
107
+ errors.push({ file, testName: def.name, message: 'At least one benchmark must be specified' });
108
+ continue;
109
+ }
110
+ let valid = true;
111
+ if (hasMaxDuration) {
112
+ if (typeof def.benchmarks.max_duration_ms !== 'number' || def.benchmarks.max_duration_ms <= 0) {
113
+ errors.push({ file, testName: def.name, message: 'max_duration_ms must be a positive number' });
114
+ valid = false;
115
+ }
116
+ }
117
+ if (hasMaxTokens) {
118
+ if (typeof def.benchmarks.max_tokens_total !== 'number' || def.benchmarks.max_tokens_total <= 0) {
119
+ errors.push({ file, testName: def.name, message: 'max_tokens_total must be a positive number' });
120
+ valid = false;
121
+ }
122
+ if (def.target.type !== 'ai_call') {
123
+ errors.push({ file, testName: def.name, message: 'max_tokens_total can only be used with ai_call targets' });
124
+ valid = false;
125
+ }
126
+ }
127
+ if (!valid)
128
+ continue;
129
+ // Validate run (optional but must be a function if present)
130
+ if (def.run !== undefined && typeof def.run !== 'function') {
131
+ errors.push({ file, testName: def.name, message: 'run must be a function' });
132
+ continue;
133
+ }
134
+ // Validate timeout_ms (optional but must be a positive number if present)
135
+ if (def.timeout_ms !== undefined) {
136
+ if (typeof def.timeout_ms !== 'number' || def.timeout_ms <= 0) {
137
+ errors.push({ file, testName: def.name, message: 'timeout_ms must be a positive number' });
138
+ continue;
139
+ }
140
+ }
141
+ tests.push({
142
+ ...def,
143
+ resolvedTracePath,
144
+ traceData,
145
+ });
146
+ }
147
+ return { tests, errors };
148
+ }
149
+ //# sourceMappingURL=test-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-loader.js","sourceRoot":"","sources":["../../src/ci/test-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ export interface TestTarget {
2
+ type: 'tool_call' | 'ai_call';
3
+ step_id: string;
4
+ }
5
+ export interface LLMJudgeBenchmark {
6
+ /** The prompt sent to the LLM judge to evaluate the step's output. */
7
+ judge_prompt: string;
8
+ /** Minimum score (0-10) required to pass. Defaults to 7. */
9
+ judge_score_threshold?: number;
10
+ /** LLM provider to use for judging. Defaults to 'openai'. */
11
+ judge_provider?: 'openai' | 'claude' | 'gemini' | 'grok' | 'kimi';
12
+ /** Model override for the judge LLM. */
13
+ judge_model?: string;
14
+ }
15
+ export interface TestBenchmarks {
16
+ max_duration_ms?: number;
17
+ max_tokens_total?: number;
18
+ /** Assert that the step's output contains this substring. */
19
+ output_contains?: string;
20
+ /** Assert that the step's output does NOT contain this substring. */
21
+ output_not_contains?: string;
22
+ /** LLM-as-a-judge evaluation of the step's output quality. */
23
+ llm_judge?: LLMJudgeBenchmark;
24
+ }
25
+ export interface TestDefinition {
26
+ name: string;
27
+ trace: string;
28
+ target: TestTarget;
29
+ benchmarks: TestBenchmarks;
30
+ /** Custom input that overrides the trace's recorded input. Can be a static value or an async function for dynamic resolution (e.g. fetching from a database or API). */
31
+ input?: unknown | (() => Promise<unknown> | unknown);
32
+ /** The function that invokes the workflow under test. Receives the resolved input (custom or from trace) as its argument. Required for execution (Phase 3). */
33
+ run?: (input?: unknown) => Promise<void>;
34
+ /** Per-test timeout in milliseconds. Defaults to 60000. */
35
+ timeout_ms?: number;
36
+ /** Set internally by the loader to the absolute path of the source file */
37
+ _sourceFile?: string;
38
+ }
39
+ export declare function defineTest(def: Omit<TestDefinition, '_sourceFile'>): void;
40
+ export declare function getTestRegistry(): TestDefinition[];
41
+ export declare function clearTestRegistry(): void;
42
+ //# sourceMappingURL=test-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-registry.d.ts","sourceRoot":"","sources":["../../src/ci/test-registry.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,WAAW,GAAG,SAAS,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,YAAY,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAA;IACjE,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,qEAAqE;IACrE,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,iBAAiB,CAAA;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,UAAU,CAAA;IAClB,UAAU,EAAE,cAAc,CAAA;IAC1B,wKAAwK;IACxK,KAAK,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAA;IACpD,+JAA+J;IAC/J,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAWD,wBAAgB,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,GAAG,IAAI,CAEzE;AAED,wBAAgB,eAAe,IAAI,cAAc,EAAE,CAElD;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -0,0 +1,18 @@
1
+ // Use a globalThis-backed registry so that the CLI (global install) and the
2
+ // test file (local node_modules) share the same array even when they resolve
3
+ // to different module instances.
4
+ const g = globalThis;
5
+ const ED_TEST_REGISTRY_KEY = '__elasticdash_ed_test_registry__';
6
+ const registry = g[ED_TEST_REGISTRY_KEY] ?? [];
7
+ if (!g[ED_TEST_REGISTRY_KEY])
8
+ g[ED_TEST_REGISTRY_KEY] = registry;
9
+ export function defineTest(def) {
10
+ registry.push({ ...def });
11
+ }
12
+ export function getTestRegistry() {
13
+ return [...registry];
14
+ }
15
+ export function clearTestRegistry() {
16
+ registry.length = 0;
17
+ }
18
+ //# sourceMappingURL=test-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-registry.js","sourceRoot":"","sources":["../../src/ci/test-registry.ts"],"names":[],"mappings":"AA0CA,4EAA4E;AAC5E,6EAA6E;AAC7E,iCAAiC;AACjC,MAAM,CAAC,GAAG,UAAqC,CAAA;AAC/C,MAAM,oBAAoB,GAAG,kCAAkC,CAAA;AAC/D,MAAM,QAAQ,GACX,CAAC,CAAC,oBAAoB,CAAsB,IAAI,EAAE,CAAA;AACrD,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC;IAAE,CAAC,CAAC,oBAAoB,CAAC,GAAG,QAAQ,CAAA;AAEhE,MAAM,UAAU,UAAU,CAAC,GAAwC;IACjE,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAA;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAA;AACtB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAA;AACrB,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { WorkflowEvent } from '../capture/event.js';
2
+ export declare let SDK_VERSION: string;
3
+ export interface DiskTraceStep {
4
+ step_id: string;
5
+ type: 'tool_call' | 'ai_call';
6
+ name: string;
7
+ input: unknown;
8
+ output: unknown;
9
+ started_at: string;
10
+ ended_at: string;
11
+ duration_ms: number;
12
+ tokens?: {
13
+ input: number;
14
+ output: number;
15
+ total: number;
16
+ } | null;
17
+ }
18
+ export interface DiskTrace {
19
+ trace_id: string;
20
+ created_at: string;
21
+ sdk_version: string;
22
+ workflow: {
23
+ name: string;
24
+ input: unknown;
25
+ output: unknown;
26
+ };
27
+ steps: DiskTraceStep[];
28
+ }
29
+ export declare function workflowEventsToDiskTrace(events: WorkflowEvent[], traceId: string): DiskTrace;
30
+ //# sourceMappingURL=trace-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-schema.d.ts","sourceRoot":"","sources":["../../src/ci/trace-schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,eAAO,IAAI,WAAW,QAAY,CAAA;AAUlC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,WAAW,GAAG,SAAS,CAAA;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CACjE;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,KAAK,EAAE,OAAO,CAAA;QACd,MAAM,EAAE,OAAO,CAAA;KAChB,CAAA;IACD,KAAK,EAAE,aAAa,EAAE,CAAA;CACvB;AAQD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAkD7F"}
@@ -0,0 +1,66 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ export let SDK_VERSION = 'unknown';
5
+ try {
6
+ // Works in both ESM (import.meta.url) and CJS (__dirname) contexts
7
+ const base = typeof __dirname !== 'undefined' ? __dirname : dirname(fileURLToPath(import.meta.url));
8
+ const pkg = JSON.parse(readFileSync(join(base, '..', '..', 'package.json'), 'utf-8'));
9
+ SDK_VERSION = pkg.version;
10
+ }
11
+ catch {
12
+ // Bundled context — version not critical
13
+ }
14
+ function mapEventType(type) {
15
+ if (type === 'tool')
16
+ return 'tool_call';
17
+ if (type === 'ai')
18
+ return 'ai_call';
19
+ return null;
20
+ }
21
+ export function workflowEventsToDiskTrace(events, traceId) {
22
+ const workflowEvent = events.find(e => e.type === 'workflow');
23
+ const counters = { tool_call: 0, ai_call: 0 };
24
+ const steps = [];
25
+ for (const event of events) {
26
+ const mappedType = mapEventType(event.type);
27
+ if (!mappedType)
28
+ continue;
29
+ const index = counters[mappedType]++;
30
+ const stepId = `${mappedType}_${index}`;
31
+ const startedAt = new Date(event.timestamp).toISOString();
32
+ const endedAt = new Date(event.timestamp + event.durationMs).toISOString();
33
+ let tokens = null;
34
+ if (mappedType === 'ai_call' && event.usage) {
35
+ tokens = {
36
+ input: event.usage.inputTokens ?? 0,
37
+ output: event.usage.outputTokens ?? 0,
38
+ total: event.usage.totalTokens ?? ((event.usage.inputTokens ?? 0) + (event.usage.outputTokens ?? 0)),
39
+ };
40
+ }
41
+ steps.push({
42
+ step_id: stepId,
43
+ type: mappedType,
44
+ name: event.name,
45
+ input: event.input,
46
+ output: event.output,
47
+ started_at: startedAt,
48
+ ended_at: endedAt,
49
+ duration_ms: event.durationMs,
50
+ tokens,
51
+ });
52
+ }
53
+ const now = new Date();
54
+ return {
55
+ trace_id: traceId,
56
+ created_at: now.toISOString(),
57
+ sdk_version: SDK_VERSION,
58
+ workflow: {
59
+ name: workflowEvent?.name ?? 'unknown',
60
+ input: workflowEvent?.input ?? null,
61
+ output: workflowEvent?.output ?? null,
62
+ },
63
+ steps,
64
+ };
65
+ }
66
+ //# sourceMappingURL=trace-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-schema.js","sourceRoot":"","sources":["../../src/ci/trace-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { WorkflowEvent } from '../capture/event.js';
2
+ import type { DiskTrace } from './trace-schema.js';
3
+ export declare function isTraceCaptureEnabled(): boolean;
4
+ export declare function generateTraceFilename(): string;
5
+ export declare function scrubSecrets(obj: unknown): unknown;
6
+ export declare function writeTraceToDisk(trace: DiskTrace, cwd?: string): Promise<void>;
7
+ /**
8
+ * Synchronous write for use in process.on('exit') handlers where async is not possible.
9
+ */
10
+ export declare function writeTraceToDiskSync(trace: DiskTrace, cwd?: string): void;
11
+ export declare function maybeCaptureTrace(events: WorkflowEvent[], traceId?: string, cwd?: string): Promise<void>;
12
+ /**
13
+ * Synchronous version of maybeCaptureTrace for process exit handlers.
14
+ */
15
+ export declare function maybeCaptureTraceSync(events: WorkflowEvent[], traceId?: string, cwd?: string): void;
16
+ //# sourceMappingURL=trace-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-writer.d.ts","sourceRoot":"","sources":["../../src/ci/trace-writer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAMlD,wBAAgB,qBAAqB,IAAI,OAAO,CAW/C;AAGD,wBAAgB,qBAAqB,IAAI,MAAM,CAO9C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAelD;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAYpF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAYzE;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAS9G;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CASnG"}