elasticdash-test 0.1.26 → 0.1.27

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 (85) hide show
  1. package/README.md +100 -0
  2. package/dist/cli.js +175 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/index.cjs +62 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/tool-registry.d.ts +31 -0
  10. package/dist/tool-registry.d.ts.map +1 -0
  11. package/dist/tool-registry.js +73 -0
  12. package/dist/tool-registry.js.map +1 -0
  13. package/dist/tool-runner-worker.js +19 -2
  14. package/dist/tool-runner-worker.js.map +1 -1
  15. package/dist/utils/debug.d.ts +1 -1
  16. package/dist/utils/debug.d.ts.map +1 -1
  17. package/dist/utils/debug.js +2 -2
  18. package/dist/utils/debug.js.map +1 -1
  19. package/docs/observability_contract.md +192 -0
  20. package/package.json +2 -2
  21. package/src/cli.ts +184 -0
  22. package/src/index.ts +4 -0
  23. package/src/tool-registry.ts +94 -0
  24. package/src/tool-runner-worker.ts +17 -2
  25. package/src/utils/debug.ts +2 -2
  26. package/dist/cloud-client.d.ts +0 -34
  27. package/dist/cloud-client.d.ts.map +0 -1
  28. package/dist/cloud-client.js +0 -103
  29. package/dist/cloud-client.js.map +0 -1
  30. package/dist/evaluators/determinism.d.ts +0 -3
  31. package/dist/evaluators/determinism.d.ts.map +0 -1
  32. package/dist/evaluators/determinism.js +0 -116
  33. package/dist/evaluators/determinism.js.map +0 -1
  34. package/dist/evaluators/index.d.ts +0 -4
  35. package/dist/evaluators/index.d.ts.map +0 -1
  36. package/dist/evaluators/index.js +0 -61
  37. package/dist/evaluators/index.js.map +0 -1
  38. package/dist/evaluators/latency-budget.d.ts +0 -3
  39. package/dist/evaluators/latency-budget.d.ts.map +0 -1
  40. package/dist/evaluators/latency-budget.js +0 -45
  41. package/dist/evaluators/latency-budget.js.map +0 -1
  42. package/dist/evaluators/llm-judge.d.ts +0 -3
  43. package/dist/evaluators/llm-judge.d.ts.map +0 -1
  44. package/dist/evaluators/llm-judge.js +0 -125
  45. package/dist/evaluators/llm-judge.js.map +0 -1
  46. package/dist/evaluators/output-contains.d.ts +0 -3
  47. package/dist/evaluators/output-contains.d.ts.map +0 -1
  48. package/dist/evaluators/output-contains.js +0 -52
  49. package/dist/evaluators/output-contains.js.map +0 -1
  50. package/dist/evaluators/output-schema.d.ts +0 -3
  51. package/dist/evaluators/output-schema.d.ts.map +0 -1
  52. package/dist/evaluators/output-schema.js +0 -58
  53. package/dist/evaluators/output-schema.js.map +0 -1
  54. package/dist/evaluators/token-budget.d.ts +0 -3
  55. package/dist/evaluators/token-budget.d.ts.map +0 -1
  56. package/dist/evaluators/token-budget.js +0 -45
  57. package/dist/evaluators/token-budget.js.map +0 -1
  58. package/dist/evaluators/types.d.ts +0 -104
  59. package/dist/evaluators/types.d.ts.map +0 -1
  60. package/dist/evaluators/types.js +0 -6
  61. package/dist/evaluators/types.js.map +0 -1
  62. package/dist/test-group/cli.d.ts +0 -8
  63. package/dist/test-group/cli.d.ts.map +0 -1
  64. package/dist/test-group/cli.js +0 -162
  65. package/dist/test-group/cli.js.map +0 -1
  66. package/dist/test-group/git-context.d.ts +0 -3
  67. package/dist/test-group/git-context.d.ts.map +0 -1
  68. package/dist/test-group/git-context.js +0 -59
  69. package/dist/test-group/git-context.js.map +0 -1
  70. package/dist/test-group/reporter.d.ts +0 -4
  71. package/dist/test-group/reporter.d.ts.map +0 -1
  72. package/dist/test-group/reporter.js +0 -54
  73. package/dist/test-group/reporter.js.map +0 -1
  74. package/dist/test-group/runner.d.ts +0 -18
  75. package/dist/test-group/runner.d.ts.map +0 -1
  76. package/dist/test-group/runner.js +0 -234
  77. package/dist/test-group/runner.js.map +0 -1
  78. package/dist/tracing-universal.d.ts +0 -13
  79. package/dist/tracing-universal.d.ts.map +0 -1
  80. package/dist/tracing-universal.js +0 -33
  81. package/dist/tracing-universal.js.map +0 -1
  82. package/docs/backend_rerun_alignment.md +0 -291
  83. package/docs/backend_traceid_update.md +0 -141
  84. package/docs/observability_backend_contract.md +0 -577
  85. package/docs/observability_rerun_backend_plan.md +0 -596
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Global registry for tools defined via edTool().
3
+ *
4
+ * Tools registered here are discoverable for reruns regardless of which
5
+ * module they live in. The helper also applies wrapTool() so telemetry
6
+ * fires automatically — symmetric with the Python @ed_tool decorator.
7
+ */
8
+ import { wrapTool } from './interceptors/tool.js';
9
+ const _registry = new Map();
10
+ export function getRegisteredTools() {
11
+ return Array.from(_registry.values());
12
+ }
13
+ export function getRegisteredTool(name) {
14
+ return _registry.get(name);
15
+ }
16
+ export function clearToolRegistry() {
17
+ _registry.clear();
18
+ }
19
+ function inferCallerLocation() {
20
+ const stack = new Error().stack;
21
+ if (!stack)
22
+ return { file: null, line: null };
23
+ const lines = stack.split('\n');
24
+ for (let i = 2; i < lines.length; i++) {
25
+ const m = lines[i].match(/\((.*?):(\d+):\d+\)|at\s+(.*?):(\d+):\d+/);
26
+ if (!m)
27
+ continue;
28
+ const file = m[1] ?? m[3];
29
+ const line = parseInt(m[2] ?? m[4], 10);
30
+ if (file && !file.includes('tool-registry')) {
31
+ return { file: file.replace(/^file:\/\//, ''), line: isNaN(line) ? null : line };
32
+ }
33
+ }
34
+ return { file: null, line: null };
35
+ }
36
+ function inferSignature(fn) {
37
+ const src = fn.toString();
38
+ const m = src.match(/^[^(]*\(([^)]*)\)/);
39
+ if (!m)
40
+ return '()';
41
+ const params = m[1]
42
+ .split(',')
43
+ .map(p => p.trim().split(/[\s=:]/)[0])
44
+ .filter(Boolean);
45
+ return `(${params.join(', ')})`;
46
+ }
47
+ /**
48
+ * Register a function as a rerunnable tool.
49
+ *
50
+ * export const myTool = edTool('my_tool', async (query: string) => { ... })
51
+ *
52
+ * The returned function is the telemetry-wrapped version, so calling it from
53
+ * normal code paths still produces traces. The CLI `run-tool` command and the
54
+ * ElasticDash MCP `run_tool` tool will resolve the original by name.
55
+ */
56
+ export function edTool(name, fn) {
57
+ const isAsync = fn.constructor.name === 'AsyncFunction';
58
+ const signature = inferSignature(fn);
59
+ const { file, line } = inferCallerLocation();
60
+ const wrapped = wrapTool(name, fn);
61
+ _registry.set(name, {
62
+ name,
63
+ fn: fn,
64
+ wrapped: wrapped,
65
+ isAsync,
66
+ signature,
67
+ sourceFile: file,
68
+ lineNumber: line,
69
+ });
70
+ return wrapped;
71
+ }
72
+ export const defineTool = edTool;
73
+ //# sourceMappingURL=tool-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"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"}
@@ -172,9 +172,26 @@ async function main() {
172
172
  originalExit(1);
173
173
  return;
174
174
  }
175
- const fn = mod[toolName];
175
+ // Registry first: covers tools defined via edTool() anywhere in the project,
176
+ // as long as their containing module is reachable from toolsModulePath's
177
+ // import graph. Falls back to ed_tools-style module export lookup.
178
+ let fn;
179
+ try {
180
+ const reg = await import('./tool-registry.js');
181
+ const registered = reg.getRegisteredTool(toolName);
182
+ if (registered)
183
+ fn = registered.wrapped;
184
+ }
185
+ catch {
186
+ // Registry module not available (older SDK build); fall through to export lookup.
187
+ }
188
+ if (!fn) {
189
+ const exported = mod[toolName];
190
+ if (typeof exported === 'function')
191
+ fn = exported;
192
+ }
176
193
  if (typeof fn !== 'function') {
177
- await writeResult({ ok: false, error: `"${toolName}" is not an exported function in the module.` });
194
+ await writeResult({ ok: false, error: `"${toolName}" not found via edTool() registry or as an exported function in the module.` });
178
195
  originalExit(1);
179
196
  return;
180
197
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tool-runner-worker.js","sourceRoot":"","sources":["../src/tool-runner-worker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool-runner-worker.js","sourceRoot":"","sources":["../src/tool-runner-worker.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- /** Log only when ELASTICDASH_DEBUG=1 is set. Drop-in replacement for console.log in interceptors. */
1
+ /** Log only when ELASTICDASH_DEBUG=1 is set. Writes to stderr so callers parsing stdout (e.g. `elasticdash run-tool`) get a clean JSON channel. */
2
2
  export declare function debugLog(...args: unknown[]): void;
3
3
  //# sourceMappingURL=debug.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAEA,qGAAqG;AACrG,wBAAgB,QAAQ,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAIjD"}
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAEA,mJAAmJ;AACnJ,wBAAgB,QAAQ,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAIjD"}
@@ -1,8 +1,8 @@
1
1
  const DEBUG_KEY = 'ELASTICDASH_DEBUG';
2
- /** Log only when ELASTICDASH_DEBUG=1 is set. Drop-in replacement for console.log in interceptors. */
2
+ /** Log only when ELASTICDASH_DEBUG=1 is set. Writes to stderr so callers parsing stdout (e.g. `elasticdash run-tool`) get a clean JSON channel. */
3
3
  export function debugLog(...args) {
4
4
  if (typeof process !== 'undefined' && process.env?.[DEBUG_KEY] === '1') {
5
- console.log(...args);
5
+ console.error(...args);
6
6
  }
7
7
  }
8
8
  //# sourceMappingURL=debug.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,mBAAmB,CAAA;AAErC,qGAAqG;AACrG,MAAM,UAAU,QAAQ,CAAC,GAAG,IAAe;IACzC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAA;IACtB,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/utils/debug.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,mBAAmB,CAAA;AAErC,mJAAmJ;AACnJ,MAAM,UAAU,QAAQ,CAAC,GAAG,IAAe;IACzC,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAA;IACxB,CAAC;AACH,CAAC"}
@@ -0,0 +1,192 @@
1
+ # Observability SDK Contract
2
+
3
+ This document describes the event types the SDK sends and the portal (remote rerun queue) contract between the SDK and the backend.
4
+
5
+ ---
6
+
7
+ ## SDK Event Types
8
+
9
+ ### Events the SDK Sends
10
+
11
+ | `type` | `name` | When | Key fields |
12
+ |--------|--------|------|------------|
13
+ | `ai` | Model name (e.g. `gpt-4o`) | Every `wrapAI` call | `input`, `output`, `usage`, `durationMs`, `streamed` |
14
+ | `tool` | Tool name (e.g. `searchDB`) | Every `wrapTool` call | `input`, `output`, `durationMs`, `streamed` |
15
+ | `side_effect` | `__heartbeat__` | Every 30s (configurable) | `input.sessionId`, `output.uptime` |
16
+ | `side_effect` | `__session_end__` | On `shutdownObservability()` | `input.sessionId`, `output.uptime` |
17
+
18
+ ### Special Events (do not display in trace UI)
19
+
20
+ - `__heartbeat__` — update session liveness, do not store as event
21
+ - `__session_end__` — mark session as ended, do not store as event
22
+
23
+ ### Streamed Events
24
+
25
+ When `streamed === true`:
26
+ - `output` is `null`
27
+ - `streamRaw` contains the full buffered text of the stream
28
+ - Display `streamRaw` as the output in the UI
29
+
30
+ ### Error Events
31
+
32
+ When a tool or AI call throws:
33
+ - `output` is `{ "error": "Error message string" }`
34
+ - `durationMs` reflects time until failure
35
+ - Display with error styling in the UI
36
+
37
+ ---
38
+
39
+ ## Portal (Remote Rerun Queue) Contract
40
+
41
+ The SDK's `elasticdash portal` command starts an HTTP server that the backend can push rerun tasks to. The backend also needs endpoints to receive results.
42
+
43
+ ### SDK Portal Endpoints (hosted on user's machine, default port 4574)
44
+
45
+ These endpoints are served by the SDK. The backend calls them.
46
+
47
+ #### `POST /api/portal/tasks` — Push a single rerun task
48
+
49
+ **Request:**
50
+ ```json
51
+ {
52
+ "taskId": "task-uuid-from-backend",
53
+ "type": "tool",
54
+ "name": "searchDB",
55
+ "input": { "query": "pikachu" },
56
+ "metadata": { "testGroupId": 42, "expectationIds": [1, 2, 3] }
57
+ }
58
+ ```
59
+
60
+ For AI tasks:
61
+ ```json
62
+ {
63
+ "taskId": "task-uuid-from-backend",
64
+ "type": "ai",
65
+ "name": "gpt-4o",
66
+ "input": { "messages": [{ "role": "user", "content": "Hello" }] },
67
+ "model": "gpt-4o",
68
+ "provider": "openai",
69
+ "modelParameters": { "temperature": 0.7, "max_tokens": 512 },
70
+ "metadata": { "testGroupId": 42 }
71
+ }
72
+ ```
73
+
74
+ **Response:** `202 Accepted`
75
+ ```json
76
+ { "ok": true, "taskId": "task-uuid-from-backend", "position": 3 }
77
+ ```
78
+
79
+ **Auth:** `Authorization: Bearer <api_key>` (validated if portal was started with `--api-key`)
80
+
81
+ #### `POST /api/portal/tasks/batch` — Push multiple tasks
82
+
83
+ **Request:**
84
+ ```json
85
+ { "tasks": [ /* PortalTask[] */ ] }
86
+ ```
87
+
88
+ **Response:** `202 Accepted`
89
+ ```json
90
+ { "ok": true, "tasks": [{ "taskId": "...", "position": 1 }, { "taskId": "...", "position": 2 }] }
91
+ ```
92
+
93
+ #### `GET /api/portal/status` — Health check
94
+
95
+ **Response:**
96
+ ```json
97
+ {
98
+ "ok": true,
99
+ "queueLength": 5,
100
+ "processing": "task-uuid-123",
101
+ "completed": 12,
102
+ "failed": 1
103
+ }
104
+ ```
105
+
106
+ #### `DELETE /api/portal/tasks/:taskId` — Cancel a pending task
107
+
108
+ **Response:** `200` if removed, `404` if not found or already processing.
109
+
110
+ ---
111
+
112
+ ### Backend Endpoints (needed for portal to work)
113
+
114
+ These endpoints must be implemented on the backend. The SDK calls them.
115
+
116
+ #### `POST /api/portal/register` — Portal registration
117
+
118
+ Called by the SDK when `elasticdash portal` starts.
119
+
120
+ **Request:**
121
+ ```json
122
+ {
123
+ "portalUrl": "http://localhost:4574"
124
+ }
125
+ ```
126
+
127
+ **Auth:** `Authorization: Bearer <api_key>`
128
+
129
+ **Response:** `200 OK`
130
+ ```json
131
+ { "ok": true }
132
+ ```
133
+
134
+ The backend should store this portal URL and use it to push tasks. The registration should be scoped to the project resolved from the API key.
135
+
136
+ #### `POST /api/portal/results/:taskId` — Receive task result
137
+
138
+ Called by the SDK after each task completes (success or failure).
139
+
140
+ **Request:**
141
+ ```json
142
+ {
143
+ "taskId": "task-uuid-from-backend",
144
+ "ok": true,
145
+ "output": "The search returned 3 results for pikachu...",
146
+ "durationMs": 245,
147
+ "usage": {
148
+ "inputTokens": 150,
149
+ "outputTokens": 45,
150
+ "totalTokens": 195
151
+ },
152
+ "metadata": { "testGroupId": 42, "expectationIds": [1, 2, 3] }
153
+ }
154
+ ```
155
+
156
+ For failed tasks:
157
+ ```json
158
+ {
159
+ "taskId": "task-uuid-from-backend",
160
+ "ok": false,
161
+ "output": null,
162
+ "error": "Tool not found: \"searchDB\". Available tools: fetchData, sendEmail",
163
+ "durationMs": 0,
164
+ "metadata": { "testGroupId": 42 }
165
+ }
166
+ ```
167
+
168
+ **Auth:** `Authorization: Bearer <api_key>`
169
+
170
+ **Response:** `200 OK`
171
+ ```json
172
+ { "ok": true }
173
+ ```
174
+
175
+ ---
176
+
177
+ ### Error Results Reference
178
+
179
+ The SDK sends these error patterns:
180
+
181
+ | Error pattern | Meaning |
182
+ |--------------|---------|
183
+ | `Tool not found: "<name>". Available tools: ...` | Tool doesn't exist in `ed_tools.ts` |
184
+ | `Cannot find ed_tools.ts/js in workspace root.` | No tools module in the project |
185
+ | `Unsupported AI provider: "<name>"` | Unknown provider string |
186
+ | `Missing API key for provider "<name>". Expected environment variable: <VAR>` | LLM API key not configured |
187
+ | `AI task input is empty; cannot execute.` | No prompt could be extracted from input |
188
+ | `AI execution failed: <message>` | LLM API call failed (rate limit, network, invalid model) |
189
+ | `Tool subprocess produced no output.` | Subprocess exited without result |
190
+ | `Failed to spawn tool subprocess: <message>` | Could not start subprocess |
191
+ | `Missing tool name on task.` | Task had no `name` field |
192
+ | `Unknown task type: <type>` | Task type was neither `tool` nor `ai` |
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elasticdash-test",
3
- "version": "0.1.26",
4
- "description": "AI-native test runner for ElasticDash workflow testing",
3
+ "version": "0.1.27",
4
+ "description": "AI-native SDK for ElasticDash workflow testing, tracing, and observability",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "elasticdash": "./dist/cli.js",
package/src/cli.ts CHANGED
@@ -14,6 +14,20 @@ import { startBrowserUiServer, type UiEvent } from './browser-ui.js'
14
14
  import { startDashboardServer } from './dashboard-server.js'
15
15
  import { initObservability, shutdownObservability } from './observability.js'
16
16
  import { startPortalServer } from './portal-server.js'
17
+ import { resolveRuntimeModule, scanTools, buildToolArgs, runToolInSubprocess } from './execution/tool-runner.js'
18
+
19
+ /** Brief, single-line preview of any value for trace event tables. */
20
+ function previewify(value: unknown, maxLen = 200): string {
21
+ if (value === null || value === undefined) return ''
22
+ let str: string
23
+ try {
24
+ str = typeof value === 'string' ? value : JSON.stringify(value)
25
+ } catch {
26
+ str = String(value)
27
+ }
28
+ str = str.replace(/\n/g, ' ').trim()
29
+ return str.length > maxLen ? str.slice(0, maxLen) + '...' : str
30
+ }
17
31
 
18
32
  function stripAnsi(input?: string): string | undefined {
19
33
  if (!input) return input
@@ -57,6 +71,8 @@ function validateRepoDirectory(cwd: string): boolean {
57
71
  'elasticdash.config.js',
58
72
  'ed_workflows.ts',
59
73
  'ed_workflows.js',
74
+ 'ed_tools.ts',
75
+ 'ed_tools.js',
60
76
  ]
61
77
  return validFiles.some(file => existsSync(path.join(cwd, file)))
62
78
  }
@@ -566,6 +582,174 @@ async function bootstrap(): Promise<void> {
566
582
  process.once('SIGTERM', cleanup)
567
583
  })
568
584
 
585
+ // elasticdash run-tool <name>
586
+ program
587
+ .command('run-tool <name>')
588
+ .description('Run a single tool by name with given input. Used for rerun validation (e.g. ElasticDash MCP).')
589
+ .option('--input <json>', 'JSON input to pass to the tool')
590
+ .option('--input-file <path>', 'Path to JSON file with input')
591
+ .action(async (name: string, options: { input?: string; inputFile?: string }) => {
592
+ const toolsModulePath = resolveRuntimeModule(cwd, 'ed_tools')
593
+ if (!toolsModulePath) {
594
+ console.error(`[elasticdash] Error: Could not find ed_tools.ts or ed_tools.js in ${cwd}`)
595
+ process.exit(1)
596
+ }
597
+
598
+ let toolInput: unknown = undefined
599
+ try {
600
+ if (options.inputFile) {
601
+ toolInput = JSON.parse(readFileSync(path.resolve(cwd, options.inputFile), 'utf-8'))
602
+ } else if (options.input) {
603
+ toolInput = JSON.parse(options.input)
604
+ }
605
+ } catch (err) {
606
+ console.error(`[elasticdash] Error: Failed to parse input JSON: ${err instanceof Error ? err.message : String(err)}`)
607
+ process.exit(1)
608
+ }
609
+
610
+ // File-scan is used to compute a positional-arg signature when present,
611
+ // but a missing scan hit is not fatal: tools defined via edTool() live
612
+ // in the runtime registry and only resolve once the worker imports the
613
+ // module. The worker handles "not found" with a clear error.
614
+ const tools = scanTools(cwd)
615
+ const tool = tools.find(t => t.name === name)
616
+
617
+ const args = buildToolArgs(toolInput, tool)
618
+ const result = await runToolInSubprocess(toolsModulePath, name, args)
619
+
620
+ if (!result.ok) {
621
+ console.error(`[elasticdash] ${result.error ?? 'Tool execution failed'}`)
622
+ process.exit(1)
623
+ }
624
+
625
+ const payload = {
626
+ tool: name,
627
+ output: result.currentOutput,
628
+ duration_ms: result.currentDurationMs,
629
+ }
630
+ process.stdout.write(JSON.stringify(payload, null, 2) + '\n')
631
+ // Sentinel line so machine consumers (e.g. ElasticDash MCP) can extract the
632
+ // result envelope even when project code prints to stdout before us.
633
+ process.stdout.write('__ED_RUN_TOOL_RESULT__:' + JSON.stringify(payload) + '\n')
634
+ process.exit(0)
635
+ })
636
+
637
+ // elasticdash run-workflow <name>
638
+ program
639
+ .command('run-workflow <name>')
640
+ .description('Run a single workflow by name with given input. Used for trace-less rerun (e.g. ElasticDash MCP).')
641
+ .option('--input <json>', 'JSON input to pass to the workflow')
642
+ .option('--input-file <path>', 'Path to JSON file with input')
643
+ .option('--timeout-seconds <n>', 'Hard cap on a single run in seconds', (v) => Number(v), 300)
644
+ .action(async (name: string, options: { input?: string; inputFile?: string; timeoutSeconds: number }) => {
645
+ const workflowsModulePath = resolveRuntimeModule(cwd, 'ed_workflows')
646
+ if (!workflowsModulePath) {
647
+ console.error(`[elasticdash] Error: Could not find ed_workflows.ts or ed_workflows.js in ${cwd}`)
648
+ process.exit(1)
649
+ }
650
+
651
+ // tsx's in-process `register('tsx/esm', ...)` produces a data:text/javascript URL
652
+ // that newer Node versions reject as unresolvable. To load TS reliably, re-spawn
653
+ // ourselves once with `--import tsx` in NODE_OPTIONS so tsx is installed at
654
+ // process startup (the same approach `runToolInSubprocess` uses for ed_tools.ts).
655
+ const isTs = workflowsModulePath.endsWith('.ts') || workflowsModulePath.endsWith('.tsx')
656
+ const nodeOptions = process.env.NODE_OPTIONS ?? ''
657
+ const tsxAlreadyLoaded = nodeOptions.includes('tsx') || nodeOptions.includes('--import')
658
+ if (isTs && !tsxAlreadyLoaded) {
659
+ const { spawn } = await import('node:child_process')
660
+ const child = spawn(process.execPath, process.argv.slice(1), {
661
+ env: { ...process.env, NODE_OPTIONS: `${nodeOptions} --import tsx`.trim() },
662
+ cwd,
663
+ stdio: 'inherit',
664
+ })
665
+ const exitCode: number = await new Promise(resolve => {
666
+ child.on('exit', code => resolve(code ?? 0))
667
+ child.on('error', () => resolve(1))
668
+ })
669
+ process.exit(exitCode)
670
+ }
671
+
672
+ let workflowInput: unknown = undefined
673
+ try {
674
+ if (options.inputFile) {
675
+ workflowInput = JSON.parse(readFileSync(path.resolve(cwd, options.inputFile), 'utf-8'))
676
+ } else if (options.input) {
677
+ workflowInput = JSON.parse(options.input)
678
+ }
679
+ } catch (err) {
680
+ console.error(`[elasticdash] Error: Failed to parse input JSON: ${err instanceof Error ? err.message : String(err)}`)
681
+ process.exit(1)
682
+ }
683
+
684
+ let mod: Record<string, unknown>
685
+ try {
686
+ mod = await import(pathToFileURL(workflowsModulePath).href) as Record<string, unknown>
687
+ } catch (err) {
688
+ console.error(`[elasticdash] Error: Failed to import ${workflowsModulePath}: ${err instanceof Error ? err.message : String(err)}`)
689
+ process.exit(1)
690
+ }
691
+
692
+ const workflowFn = mod[name] as ((input?: unknown) => unknown) | undefined
693
+ if (typeof workflowFn !== 'function') {
694
+ console.error(`[elasticdash] Error: Workflow '${name}' not found or not a function in ${workflowsModulePath}`)
695
+ process.exit(1)
696
+ }
697
+
698
+ const { runWorkflow } = await import('./workflow-runner.js')
699
+
700
+ const startedAt = Date.now()
701
+ let runError: string | undefined
702
+ let timedOut = false
703
+ let traceId: string | null = null
704
+ let output: unknown = null
705
+ let events: Array<Record<string, unknown>> = []
706
+
707
+ try {
708
+ const runPromise = runWorkflow(async () => workflowFn(workflowInput))
709
+ const timeoutPromise = new Promise((_, reject) => {
710
+ setTimeout(() => {
711
+ timedOut = true
712
+ reject(new Error(`workflow '${name}' timed out after ${options.timeoutSeconds}s`))
713
+ }, options.timeoutSeconds * 1000)
714
+ })
715
+ const runResult = await Promise.race([runPromise, timeoutPromise]) as { result: unknown; trace: { traceId: string; events: Array<{ id: number; type: string; name: string; input: unknown; output: unknown; durationMs: number }> } }
716
+ output = runResult.result
717
+ traceId = runResult.trace?.traceId ?? null
718
+ events = (runResult.trace?.events ?? []).map((e) => {
719
+ const out = e.output as Record<string, unknown> | null | undefined
720
+ const hasError = out !== null && typeof out === 'object' && out !== null && 'error' in out
721
+ return {
722
+ id: e.id,
723
+ type: e.type,
724
+ name: e.name,
725
+ duration_ms: e.durationMs,
726
+ has_error: hasError,
727
+ input_preview: previewify(e.input),
728
+ output_preview: previewify(e.output),
729
+ }
730
+ })
731
+ } catch (err) {
732
+ runError = err instanceof Error ? err.message : String(err)
733
+ }
734
+ const endedAt = Date.now()
735
+
736
+ const envelope = {
737
+ workflow: name,
738
+ trace_id: traceId,
739
+ output,
740
+ duration_ms: endedAt - startedAt,
741
+ started_at: startedAt,
742
+ ended_at: endedAt,
743
+ events,
744
+ status: runError ? (timedOut ? 'timed_out' : 'failed') : 'completed',
745
+ ...(runError ? { error: runError } : {}),
746
+ }
747
+
748
+ process.stdout.write(JSON.stringify(envelope, null, 2) + '\n')
749
+ process.stdout.write('__ED_RUN_WORKFLOW_RESULT__:' + JSON.stringify(envelope) + '\n')
750
+ process.exit(runError ? 1 : 0)
751
+ })
752
+
569
753
  // elasticdash init-guide
570
754
  program
571
755
  .command('init-guide')
package/src/index.ts CHANGED
@@ -22,6 +22,10 @@ export type { CaptureContext } from './capture/recorder.js'
22
22
  export { wrapTool } from './interceptors/tool.js'
23
23
  export { wrapAI } from './interceptors/workflow-ai.js'
24
24
 
25
+ // Tool registry (rerunnable tools defined anywhere in the project)
26
+ export { edTool, defineTool, getRegisteredTool, getRegisteredTools, clearToolRegistry } from './tool-registry.js'
27
+ export type { RegisteredTool } from './tool-registry.js'
28
+
25
29
  // HTTP run context (ALS + global fallback for streaming frameworks)
26
30
  export {
27
31
  setHttpRunContext,