@output.ai/cli 0.3.0-dev.pr156.c8e7f40 → 0.3.0-dev.pr156.f70e0a1

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.
@@ -32,20 +32,10 @@ export interface Workflow {
32
32
  inputSchema?: JSONSchema;
33
33
  outputSchema?: JSONSchema;
34
34
  }
35
- export type PostWorkflowRunBody = {
36
- /** The name of the workflow to execute */
37
- workflowName: string;
38
- /** The payload to send to the workflow */
39
- input: unknown;
40
- /** (Optional) The workflowId to use. Must be unique */
41
- workflowId?: string;
42
- /** The name of the task queue to send the workflow to */
43
- taskQueue?: string;
44
- };
45
35
  /**
46
36
  * File destinations for trace data
47
37
  */
48
- export type PostWorkflowRun200TraceDestinations = {
38
+ export type TraceInfoDestinations = {
49
39
  /**
50
40
  * Absolute path to local trace file, or null if not saved locally
51
41
  * @nullable
@@ -60,17 +50,26 @@ export type PostWorkflowRun200TraceDestinations = {
60
50
  /**
61
51
  * An object with information about the trace generated by the execution
62
52
  */
63
- export type PostWorkflowRun200Trace = {
53
+ export interface TraceInfo {
64
54
  /** File destinations for trace data */
65
- destinations?: PostWorkflowRun200TraceDestinations;
55
+ destinations?: TraceInfoDestinations;
56
+ }
57
+ export type PostWorkflowRunBody = {
58
+ /** The name of the workflow to execute */
59
+ workflowName: string;
60
+ /** The payload to send to the workflow */
61
+ input: unknown;
62
+ /** (Optional) The workflowId to use. Must be unique */
63
+ workflowId?: string;
64
+ /** The name of the task queue to send the workflow to */
65
+ taskQueue?: string;
66
66
  };
67
67
  export type PostWorkflowRun200 = {
68
68
  /** The workflow execution id */
69
69
  workflowId?: string;
70
70
  /** The output of the workflow */
71
71
  output?: unknown;
72
- /** An object with information about the trace generated by the execution */
73
- trace?: PostWorkflowRun200Trace;
72
+ trace?: TraceInfo;
74
73
  };
75
74
  export type PostWorkflowStartBody = {
76
75
  /** The name of the workflow to execute */
@@ -110,35 +109,12 @@ export type GetWorkflowIdStatus200 = {
110
109
  /** An epoch timestamp representing when the workflow ended */
111
110
  completedAt?: number;
112
111
  };
113
- /**
114
- * File destinations for trace data
115
- */
116
- export type GetWorkflowIdOutput200TraceDestinations = {
117
- /**
118
- * Absolute path to local trace file, or null if not saved locally
119
- * @nullable
120
- */
121
- local: string | null;
122
- /**
123
- * Remote trace location (e.g., S3 URI), or null if not saved remotely
124
- * @nullable
125
- */
126
- remote: string | null;
127
- };
128
- /**
129
- * An object with information about the trace generated by the execution
130
- */
131
- export type GetWorkflowIdOutput200Trace = {
132
- /** File destinations for trace data */
133
- destinations?: GetWorkflowIdOutput200TraceDestinations;
134
- };
135
112
  export type GetWorkflowIdOutput200 = {
136
113
  /** The workflow execution id */
137
114
  workflowId?: string;
138
115
  /** The output of workflow */
139
116
  output?: unknown;
140
- /** An object with information about the trace generated by the execution */
141
- trace?: GetWorkflowIdOutput200Trace;
117
+ trace?: TraceInfo;
142
118
  };
143
119
  export type GetWorkflowCatalogId200 = {
144
120
  /** Each workflow available in this catalog */
@@ -9,7 +9,6 @@ export default class WorkflowDebug extends Command {
9
9
  format: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
10
  };
11
11
  run(): Promise<void>;
12
- private getTrace;
13
12
  private outputJson;
14
13
  private displayTextTrace;
15
14
  }
@@ -1,7 +1,7 @@
1
1
  import { Args, Command, Flags } from '@oclif/core';
2
2
  import { OUTPUT_FORMAT } from '#utils/constants.js';
3
- import { traceFormatter } from '#utils/trace_formatter.js';
4
- import { findTraceFile, readTraceFile } from '#services/trace_reader.js';
3
+ import { displayDebugTree } from '#utils/trace_formatter.js';
4
+ import { getTrace } from '#services/trace_reader.js';
5
5
  export default class WorkflowDebug extends Command {
6
6
  static description = 'Get and display workflow execution trace for debugging';
7
7
  static examples = [
@@ -29,7 +29,7 @@ export default class WorkflowDebug extends Command {
29
29
  if (!isJsonFormat) {
30
30
  this.log(`Fetching debug information for workflow: ${args.workflowId}...`);
31
31
  }
32
- const traceData = await this.getTrace(args.workflowId);
32
+ const traceData = await getTrace(args.workflowId);
33
33
  // Output based on format
34
34
  if (isJsonFormat) {
35
35
  this.outputJson(traceData);
@@ -38,17 +38,13 @@ export default class WorkflowDebug extends Command {
38
38
  // Display text format
39
39
  this.displayTextTrace(traceData);
40
40
  }
41
- async getTrace(workflowId) {
42
- const tracePath = await findTraceFile(workflowId);
43
- return readTraceFile(tracePath);
44
- }
45
41
  outputJson(data) {
46
42
  this.log(JSON.stringify(data, null, 2));
47
43
  }
48
44
  displayTextTrace(traceData) {
49
45
  this.log('\nTrace Log:');
50
46
  this.log('─'.repeat(80));
51
- this.log(traceFormatter.displayDebugTree(traceData));
47
+ this.log(displayDebugTree(traceData));
52
48
  this.log('\n' + '─'.repeat(80));
53
49
  this.log('Tip: Use --format json for complete verbose output');
54
50
  }
@@ -1,16 +1,13 @@
1
1
  import { describe, it, expect, vi, beforeEach } from 'vitest';
2
2
  // Mock the TraceReader service
3
3
  vi.mock('../../services/trace_reader.js', () => ({
4
- TraceReader: vi.fn().mockImplementation(() => ({
5
- findTraceFile: vi.fn(),
6
- readTraceFile: vi.fn()
7
- }))
4
+ findTraceFile: vi.fn(),
5
+ readTraceFile: vi.fn(),
6
+ getTrace: vi.fn()
8
7
  }));
9
8
  // Mock the utilities
10
9
  vi.mock('../../utils/trace_formatter.js', () => ({
11
- traceFormatter: {
12
- displayDebugTree: vi.fn()
13
- }
10
+ displayDebugTree: vi.fn()
14
11
  }));
15
12
  describe('workflow debug command', () => {
16
13
  beforeEach(() => {
@@ -1,3 +1,32 @@
1
+ export interface TraceData {
2
+ root: {
3
+ workflowName: string;
4
+ workflowId: string;
5
+ startTime: number;
6
+ endTime?: number;
7
+ duration?: number;
8
+ status?: string;
9
+ error?: unknown;
10
+ };
11
+ events?: Array<{
12
+ name: string;
13
+ phase: string;
14
+ timestamp: number;
15
+ details?: unknown;
16
+ }>;
17
+ children?: TraceNode[];
18
+ }
19
+ interface TraceNode {
20
+ name: string;
21
+ type?: string;
22
+ startTime?: number;
23
+ endTime?: number;
24
+ duration?: number;
25
+ status?: string;
26
+ details?: unknown;
27
+ error?: unknown;
28
+ children?: TraceNode[];
29
+ }
1
30
  /**
2
31
  * Find trace file from workflow metadata
3
32
  */
@@ -5,4 +34,9 @@ export declare function findTraceFile(workflowId: string): Promise<string>;
5
34
  /**
6
35
  * Read and parse trace file
7
36
  */
8
- export declare function readTraceFile(path: string): Promise<any>;
37
+ export declare function readTraceFile(path: string): Promise<TraceData>;
38
+ /**
39
+ * Get trace data from workflow ID
40
+ */
41
+ export declare function getTrace(workflowId: string): Promise<TraceData>;
42
+ export {};
@@ -33,7 +33,6 @@ export async function findTraceFile(workflowId) {
33
33
  /**
34
34
  * Read and parse trace file
35
35
  */
36
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
36
  export async function readTraceFile(path) {
38
37
  try {
39
38
  const content = await readFile(path, 'utf-8');
@@ -49,3 +48,10 @@ export async function readTraceFile(path) {
49
48
  throw error;
50
49
  }
51
50
  }
51
+ /**
52
+ * Get trace data from workflow ID
53
+ */
54
+ export async function getTrace(workflowId) {
55
+ const tracePath = await findTraceFile(workflowId);
56
+ return readTraceFile(tracePath);
57
+ }
@@ -1,3 +1,23 @@
1
+ type ErrorLike = string | {
2
+ message: string;
3
+ } | Error | unknown;
4
+ interface DebugNode {
5
+ kind?: string;
6
+ type?: string;
7
+ name?: string;
8
+ workflowName?: string;
9
+ stepName?: string;
10
+ activityName?: string;
11
+ phase?: string;
12
+ status?: string;
13
+ startTime?: number;
14
+ endTime?: number;
15
+ duration?: number;
16
+ details?: Record<string, unknown>;
17
+ error?: ErrorLike;
18
+ children?: DebugNode[];
19
+ [key: string]: unknown;
20
+ }
1
21
  /**
2
22
  * Format duration in human-readable format
3
23
  */
@@ -19,9 +39,5 @@ export declare function getSummary(traceData: string | object): {
19
39
  /**
20
40
  * Display trace tree with debug command formatting style
21
41
  */
22
- export declare function displayDebugTree(node: any): string;
23
- export declare const traceFormatter: {
24
- format: typeof format;
25
- getSummary: typeof getSummary;
26
- displayDebugTree: typeof displayDebugTree;
27
- };
42
+ export declare function displayDebugTree(node: DebugNode | unknown): string;
43
+ export {};
@@ -17,20 +17,18 @@ export function formatDuration(ms) {
17
17
  /**
18
18
  * Format error for display
19
19
  */
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
20
  function formatError(error) {
22
21
  if (typeof error === 'string') {
23
22
  return error;
24
23
  }
25
- if (error.message) {
26
- return error.message;
24
+ if (error && typeof error === 'object' && 'message' in error) {
25
+ return String(error.message);
27
26
  }
28
27
  return JSON.stringify(error);
29
28
  }
30
29
  /**
31
30
  * Truncate long values for display
32
31
  */
33
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
32
  function truncateValue(value, maxLength = 50) {
35
33
  const str = typeof value === 'string' ? value : JSON.stringify(value);
36
34
  if (str.length <= maxLength) {
@@ -71,7 +69,6 @@ function formatPhase(phase) {
71
69
  /**
72
70
  * Format details for table display
73
71
  */
74
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
72
  function formatDetails(details) {
76
73
  if (!details) {
77
74
  return '-';
@@ -98,7 +95,6 @@ function formatDetails(details) {
98
95
  /**
99
96
  * Format details for tree display
100
97
  */
101
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
102
98
  function formatTreeDetails(details, depth) {
103
99
  const lines = [];
104
100
  const indent = ' '.repeat(depth);
@@ -117,17 +113,26 @@ function formatTreeDetails(details, depth) {
117
113
  function formatHeader(root) {
118
114
  const lines = [];
119
115
  lines.push('═'.repeat(60));
120
- lines.push(`Workflow: ${root.workflowName}`);
121
- lines.push(`Workflow ID: ${root.workflowId}`);
122
- lines.push(`Start Time: ${new Date(root.timestamp).toISOString()}`);
116
+ // Handle both TraceEvent and DebugNode types
117
+ const workflowName = 'workflowName' in root ? root.workflowName : (root.name || 'Unknown');
118
+ const workflowId = 'workflowId' in root ? root.workflowId : 'N/A';
119
+ const timestamp = 'timestamp' in root ? root.timestamp : root.startTime;
120
+ lines.push(`Workflow: ${workflowName}`);
121
+ lines.push(`Workflow ID: ${workflowId}`);
122
+ if (timestamp && (typeof timestamp === 'number' || typeof timestamp === 'string')) {
123
+ lines.push(`Start Time: ${new Date(timestamp).toISOString()}`);
124
+ }
123
125
  if (root.duration) {
124
126
  lines.push(`Duration: ${formatDuration(root.duration)}`);
125
127
  }
126
- if (root.phase === 'error' && root.error) {
128
+ // Handle status based on available properties
129
+ const phase = 'phase' in root ? root.phase : undefined;
130
+ const status = 'status' in root ? root.status : undefined;
131
+ if ((phase === 'error' || status === 'failed') && root.error) {
127
132
  lines.push('Status: Failed');
128
133
  lines.push(`Error: ${formatError(root.error)}`);
129
134
  }
130
- else if (root.phase === 'end') {
135
+ else if (phase === 'end' || status === 'completed') {
131
136
  lines.push('Status: Completed');
132
137
  }
133
138
  else {
@@ -158,6 +163,57 @@ function formatEventsTable(events) {
158
163
  }
159
164
  return table.toString();
160
165
  }
166
+ /**
167
+ * Get debug node display information
168
+ */
169
+ function getDebugNodeInfo(node) {
170
+ if (typeof node === 'string') {
171
+ return node;
172
+ }
173
+ if (typeof node !== 'object' || node === null) {
174
+ return String(node);
175
+ }
176
+ const debugNode = node;
177
+ const parts = [];
178
+ // Look for common identifying properties
179
+ if (debugNode.kind) {
180
+ parts.push(`[${debugNode.kind}]`);
181
+ }
182
+ else if (debugNode.type) {
183
+ parts.push(`[${debugNode.type}]`);
184
+ }
185
+ if (debugNode.name) {
186
+ parts.push(debugNode.name);
187
+ }
188
+ else if (debugNode.workflowName) {
189
+ parts.push(debugNode.workflowName);
190
+ }
191
+ else if (debugNode.stepName) {
192
+ parts.push(debugNode.stepName);
193
+ }
194
+ else if (debugNode.activityName) {
195
+ parts.push(debugNode.activityName);
196
+ }
197
+ // Add phase/status indicators
198
+ if (debugNode.phase === 'error' || debugNode.status === 'failed') {
199
+ parts.push('[FAILED]');
200
+ }
201
+ else if (debugNode.phase === 'end' || debugNode.status === 'completed') {
202
+ parts.push('[COMPLETED]');
203
+ }
204
+ else if (debugNode.status === 'running') {
205
+ parts.push('[RUNNING]');
206
+ }
207
+ // If we have no meaningful parts, show a summary of the object
208
+ if (parts.length === 0) {
209
+ const keys = Object.keys(debugNode).filter(k => k !== 'children' && k !== 'parent');
210
+ if (keys.length > 0) {
211
+ return `Node {${keys.slice(0, 3).join(', ')}${keys.length > 3 ? ', ...' : ''}}`;
212
+ }
213
+ return 'Node';
214
+ }
215
+ return parts.join(' ');
216
+ }
161
217
  /**
162
218
  * Format trace as a tree structure
163
219
  */
@@ -165,11 +221,28 @@ function formatTree(node, depth) {
165
221
  const lines = [];
166
222
  const indent = ' '.repeat(depth);
167
223
  const marker = depth === 0 ? '' : '├─';
168
- // Format current node
169
- const nodeName = getEventName(node);
170
- const phase = formatPhase(node.phase);
171
- const duration = node.duration ? ` (${formatDuration(node.duration)})` : '';
172
- lines.push(`${indent}${marker} ${nodeName} ${phase}${duration}`);
224
+ // Format current node - handle both types
225
+ const nodeInfo = (() => {
226
+ if ('workflowId' in node && 'timestamp' in node) {
227
+ // It's a TraceEvent
228
+ const traceNode = node;
229
+ return {
230
+ nodeName: getEventName(traceNode),
231
+ phase: formatPhase(traceNode.phase),
232
+ duration: traceNode.duration ? ` (${formatDuration(traceNode.duration)})` : ''
233
+ };
234
+ }
235
+ else {
236
+ // It's a DebugNode
237
+ const debugNode = node;
238
+ return {
239
+ nodeName: getDebugNodeInfo(node),
240
+ phase: debugNode.phase ? formatPhase(debugNode.phase) : '',
241
+ duration: debugNode.duration ? ` (${formatDuration(debugNode.duration)})` : ''
242
+ };
243
+ }
244
+ })();
245
+ lines.push(`${indent}${marker} ${nodeInfo.nodeName} ${nodeInfo.phase}${nodeInfo.duration}`);
173
246
  // Add error details if present
174
247
  if (node.error) {
175
248
  lines.push(`${indent} └─ ERROR: ${formatError(node.error)}`);
@@ -192,7 +265,6 @@ function formatTree(node, depth) {
192
265
  /**
193
266
  * Format trace as human-readable text with tree structure
194
267
  */
195
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
196
268
  function formatAsText(trace) {
197
269
  const output = [];
198
270
  // Add header with workflow info
@@ -261,7 +333,6 @@ function getConnector(isLast) {
261
333
  /**
262
334
  * Format value for debug detail display
263
335
  */
264
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
265
336
  function formatDebugDetailValue(value) {
266
337
  if (value === null) {
267
338
  return 'null';
@@ -290,14 +361,15 @@ function formatDebugDetailValue(value) {
290
361
  return `[Array with ${value.length} items]`;
291
362
  }
292
363
  if (typeof value === 'object') {
293
- const keys = Object.keys(value);
364
+ const obj = value;
365
+ const keys = Object.keys(obj);
294
366
  if (keys.length === 0) {
295
367
  return '{}';
296
368
  }
297
369
  // For simple objects with few keys, show inline
298
370
  if (keys.length <= 2) {
299
371
  const pairs = keys.map(k => {
300
- const v = value[k];
372
+ const v = obj[k];
301
373
  if (typeof v === 'string' && v.length > 30) {
302
374
  return `${k}: "${v.substring(0, 30)}..."`;
303
375
  }
@@ -313,82 +385,30 @@ function formatDebugDetailValue(value) {
313
385
  }
314
386
  return String(value);
315
387
  }
316
- /**
317
- * Get debug node display information
318
- */
319
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
320
- function getDebugNodeInfo(node) {
321
- if (typeof node === 'string') {
322
- return node;
323
- }
324
- if (typeof node !== 'object') {
325
- return String(node);
326
- }
327
- const parts = [];
328
- // Look for common identifying properties
329
- if (node.kind) {
330
- parts.push(`[${node.kind}]`);
331
- }
332
- else if (node.type) {
333
- parts.push(`[${node.type}]`);
334
- }
335
- if (node.name) {
336
- parts.push(node.name);
337
- }
338
- else if (node.workflowName) {
339
- parts.push(node.workflowName);
340
- }
341
- else if (node.stepName) {
342
- parts.push(node.stepName);
343
- }
344
- else if (node.activityName) {
345
- parts.push(node.activityName);
346
- }
347
- // Add phase/status indicators
348
- if (node.phase === 'error' || node.status === 'failed') {
349
- parts.push('[FAILED]');
350
- }
351
- else if (node.phase === 'end' || node.status === 'completed') {
352
- parts.push('[COMPLETED]');
353
- }
354
- else if (node.status === 'running') {
355
- parts.push('[RUNNING]');
356
- }
357
- // If we have no meaningful parts, show a summary of the object
358
- if (parts.length === 0) {
359
- const keys = Object.keys(node).filter(k => k !== 'children' && k !== 'parent');
360
- if (keys.length > 0) {
361
- return `Node {${keys.slice(0, 3).join(', ')}${keys.length > 3 ? ', ...' : ''}}`;
362
- }
363
- return 'Node';
364
- }
365
- return parts.join(' ');
366
- }
367
388
  /**
368
389
  * Add debug node details to lines array
369
390
  */
370
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
371
391
  function addDebugNodeDetails(node, prefix, lines) {
372
392
  if (typeof node !== 'object' || node === null) {
373
393
  return;
374
394
  }
375
395
  const details = [];
376
396
  // Add timing information
377
- if (node.startedAt || node.timestamp) {
378
- const startTime = node.startedAt || node.timestamp;
379
- const startDate = new Date(startTime);
397
+ const startedAt = node.startedAt || node.timestamp;
398
+ if (startedAt && (typeof startedAt === 'number' || typeof startedAt === 'string')) {
399
+ const startDate = new Date(startedAt);
380
400
  if (!isNaN(startDate.getTime())) {
381
401
  details.push(`${prefix}Started: ${startDate.toISOString()}`);
382
402
  }
383
403
  }
384
- if (node.endedAt) {
404
+ if (node.endedAt && (typeof node.endedAt === 'number' || typeof node.endedAt === 'string')) {
385
405
  const endDate = new Date(node.endedAt);
386
406
  if (!isNaN(endDate.getTime())) {
387
407
  details.push(`${prefix}Ended: ${endDate.toISOString()}`);
388
408
  }
389
409
  }
390
410
  // Calculate and show duration
391
- if (node.startedAt && node.endedAt) {
411
+ if (node.startedAt && node.endedAt && typeof node.startedAt === 'number' && typeof node.endedAt === 'number') {
392
412
  const duration = node.endedAt - node.startedAt;
393
413
  details.push(`${prefix}Duration: ${formatDuration(duration)}`);
394
414
  }
@@ -407,7 +427,17 @@ function addDebugNodeDetails(node, prefix, lines) {
407
427
  }
408
428
  // Show error if present
409
429
  if (node.error) {
410
- const errorMsg = typeof node.error === 'string' ? node.error : (node.error.message || JSON.stringify(node.error));
430
+ const errorMsg = (() => {
431
+ if (typeof node.error === 'string') {
432
+ return node.error;
433
+ }
434
+ else if (node.error && typeof node.error === 'object' && 'message' in node.error) {
435
+ return String(node.error.message);
436
+ }
437
+ else {
438
+ return JSON.stringify(node.error);
439
+ }
440
+ })();
411
441
  details.push(`${prefix}Error: ${errorMsg}`);
412
442
  }
413
443
  // Add all details to lines
@@ -422,7 +452,6 @@ function addDebugNodeDetails(node, prefix, lines) {
422
452
  /**
423
453
  * Build debug tree lines recursively
424
454
  */
425
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
426
455
  function buildDebugTreeLines(node, depth, isLast, prefix, lines) {
427
456
  if (node === null || node === undefined) {
428
457
  return;
@@ -436,30 +465,28 @@ function buildDebugTreeLines(node, depth, isLast, prefix, lines) {
436
465
  lines.push(indent + nodeInfo);
437
466
  // Display additional details with proper indentation
438
467
  const detailPrefix = isRoot ? ' ' : prefix + (isLast ? ' ' : '│ ');
439
- addDebugNodeDetails(node, detailPrefix, lines);
468
+ if (typeof node === 'object' && node !== null) {
469
+ addDebugNodeDetails(node, detailPrefix, lines);
470
+ }
440
471
  // Update prefix for children
441
472
  const childPrefix = isRoot ? '' : prefix + (isLast ? ' ' : '│ ');
442
473
  // Process children if they exist
443
- if (node.children && Array.isArray(node.children)) {
444
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
445
- node.children.forEach((child, i) => {
446
- const isLastChild = i === node.children.length - 1;
447
- buildDebugTreeLines(child, depth + 1, isLastChild, childPrefix, lines);
448
- });
474
+ if (typeof node === 'object' && node !== null) {
475
+ const debugNode = node;
476
+ if (debugNode.children && Array.isArray(debugNode.children)) {
477
+ const children = debugNode.children;
478
+ children.forEach((child, i) => {
479
+ const isLastChild = i === children.length - 1;
480
+ buildDebugTreeLines(child, depth + 1, isLastChild, childPrefix, lines);
481
+ });
482
+ }
449
483
  }
450
484
  }
451
485
  /**
452
486
  * Display trace tree with debug command formatting style
453
487
  */
454
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
455
488
  export function displayDebugTree(node) {
456
489
  const lines = [];
457
490
  buildDebugTreeLines(node, 0, false, '', lines);
458
491
  return lines.join('\n');
459
492
  }
460
- // For backward compatibility, export an object with the main functions
461
- export const traceFormatter = {
462
- format,
463
- getSummary,
464
- displayDebugTree
465
- };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@output.ai/cli",
3
- "version": "0.3.0-dev.pr156.c8e7f40",
3
+ "version": "0.3.0-dev.pr156.f70e0a1",
4
4
  "description": "CLI for Output.ai workflow generation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",