@outputai/cli 0.9.1-dev.000c5f3.0 → 0.9.1-dev.667788.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 (36) hide show
  1. package/dist/assets/docker/docker-compose-dev.yml +1 -1
  2. package/dist/generated/framework_version.json +1 -1
  3. package/dist/views/dev/dev_app.js +3 -17
  4. package/dist/views/dev/modals/steps_modal.js +1 -1
  5. package/dist/views/dev/panels/runs_panel.js +2 -7
  6. package/dist/views/dev/panels/workflows_panel.js +1 -1
  7. package/dist/views/dev/state/ui_state.d.ts +0 -8
  8. package/dist/views/dev/state/ui_state.js +1 -5
  9. package/oclif.manifest.json +1 -81
  10. package/package.json +4 -4
  11. package/dist/commands/workflow/history.d.ts +0 -19
  12. package/dist/commands/workflow/history.js +0 -99
  13. package/dist/commands/workflow/history.spec.d.ts +0 -1
  14. package/dist/commands/workflow/history.spec.js +0 -26
  15. package/dist/services/workflow_history/correlator.d.ts +0 -26
  16. package/dist/services/workflow_history/correlator.js +0 -261
  17. package/dist/services/workflow_history/correlator.spec.d.ts +0 -1
  18. package/dist/services/workflow_history/correlator.spec.js +0 -116
  19. package/dist/services/workflow_history.d.ts +0 -23
  20. package/dist/services/workflow_history.js +0 -79
  21. package/dist/services/workflow_history.spec.d.ts +0 -1
  22. package/dist/services/workflow_history.spec.js +0 -87
  23. package/dist/utils/span_labels.d.ts +0 -11
  24. package/dist/utils/span_labels.js +0 -22
  25. package/dist/utils/span_labels.spec.d.ts +0 -1
  26. package/dist/utils/span_labels.spec.js +0 -36
  27. package/dist/utils/waterfall.d.ts +0 -31
  28. package/dist/utils/waterfall.js +0 -192
  29. package/dist/utils/waterfall.spec.d.ts +0 -1
  30. package/dist/utils/waterfall.spec.js +0 -100
  31. package/dist/views/dev/hooks/use_step_graph.d.ts +0 -22
  32. package/dist/views/dev/hooks/use_step_graph.js +0 -76
  33. package/dist/views/dev/modals/step_graph_modal.d.ts +0 -6
  34. package/dist/views/dev/modals/step_graph_modal.js +0 -148
  35. /package/dist/views/dev/utils/{ui_constants.d.ts → constants.d.ts} +0 -0
  36. /package/dist/views/dev/utils/{ui_constants.js → constants.js} +0 -0
@@ -80,7 +80,7 @@ services:
80
80
  condition: service_healthy
81
81
  worker:
82
82
  condition: service_healthy
83
- image: outputai/api:${OUTPUT_API_VERSION:-0.9.1-dev.000c5f3.0}
83
+ image: outputai/api:${OUTPUT_API_VERSION:-0.9.1-dev.667788.0}
84
84
  init: true
85
85
  networks:
86
86
  - main
@@ -1,3 +1,3 @@
1
1
  {
2
- "framework": "0.9.1-dev.000c5f3.0"
2
+ "framework": "0.9.1-dev.667788.0"
3
3
  }
@@ -18,8 +18,7 @@ import { HELP_HINTS, HELP_SECTION_COUNT, HelpPanel } from '#views/dev/panels/hel
18
18
  import { RunModal } from '#views/dev/modals/run_modal.js';
19
19
  import { ExpandedJsonModal } from '#views/dev/modals/expanded_json_modal.js';
20
20
  import { StepsModal } from '#views/dev/modals/steps_modal.js';
21
- import { StepGraphModal } from '#views/dev/modals/step_graph_modal.js';
22
- import { MIN_TERMINAL_COLUMNS, MIN_TERMINAL_ROWS } from '#views/dev/utils/ui_constants.js';
21
+ import { MIN_TERMINAL_COLUMNS, MIN_TERMINAL_ROWS } from '#views/dev/utils/constants.js';
23
22
  const TAB_NUMBER_KEYS = {
24
23
  1: 'workflows',
25
24
  2: 'runs',
@@ -66,7 +65,7 @@ const useGlobalInput = (opts) => {
66
65
  .catch(err => exit(err instanceof Error ? err : new Error(String(err))));
67
66
  return;
68
67
  }
69
- if (ui.search.open || ui.runModal.open || ui.expandedJson.open || ui.stepGraph.open || opts.runDetailOpen) {
68
+ if (ui.search.open || ui.runModal.open || ui.expandedJson.open || opts.runDetailOpen) {
70
69
  return;
71
70
  }
72
71
  // Esc on a list view drops an active filter. Skip when we're on
@@ -134,14 +133,9 @@ const footerFor = (opts) => {
134
133
  return { hints: HELP_HINTS, itemCount: HELP_SECTION_COUNT, itemLabel: 'sections' };
135
134
  };
136
135
  const overlayFor = (opts) => {
137
- // expandedJson sits on top of everything — it's popped from another overlay
138
- // (e.g. the step graph's `e`), so it must win when both are open.
139
136
  if (opts.ui.expandedJson.open) {
140
137
  return _jsx(ExpandedJsonModal, {});
141
138
  }
142
- if (opts.ui.stepGraph.open && opts.stepGraphRun) {
143
- return _jsx(StepGraphModal, { run: opts.stepGraphRun, height: opts.rows });
144
- }
145
139
  if (opts.ui.runModal.open) {
146
140
  return _jsx(RunModal, { workflowName: opts.ui.runModal.workflowName, workflowPath: opts.ui.runModal.workflowPath });
147
141
  }
@@ -183,14 +177,6 @@ const Shell = ({ dockerComposePath, onCleanup }) => {
183
177
  runs.find(r => r.runId === ui.selection.runId && r.workflowId === ui.selection.workflowId) :
184
178
  undefined;
185
179
  const runDetailOpen = ui.runsView === 'detail' && detailRun !== undefined;
186
- // Re-resolve the step-graph run from the polled list each render so its
187
- // status/duration stay live; fall back to the snapshot captured at open.
188
- const stepGraphRun = useMemo(() => {
189
- const captured = ui.stepGraph.open ? ui.stepGraph.run : null;
190
- return captured ?
191
- (runs.find(r => r.runId === captured.runId && r.workflowId === captured.workflowId) ?? captured) :
192
- undefined;
193
- }, [ui.stepGraph.open, ui.stepGraph.run, runs]);
194
180
  useGlobalInput({ onCleanup, runDetailOpen });
195
181
  const failingServices = useMemo(() => services.filter(isServiceFailed).length, [services]);
196
182
  const serviceBadge = useMemo(() => {
@@ -224,7 +210,7 @@ const Shell = ({ dockerComposePath, onCleanup }) => {
224
210
  serviceCount: services.length,
225
211
  phase
226
212
  });
227
- const overlay = overlayFor({ ui, detailRun, stepGraphRun, runDetailOpen, rows });
213
+ const overlay = overlayFor({ ui, detailRun, runDetailOpen, rows });
228
214
  if (terminalTooSmall) {
229
215
  return _jsx(TerminalTooSmall, { rows: rows, cols: cols });
230
216
  }
@@ -9,7 +9,7 @@ import { useUiState } from '#views/dev/state/ui_state.js';
9
9
  import { useRunDetail } from '#views/dev/hooks/use_run_detail.js';
10
10
  import { JsonView } from '#views/dev/utils/json_render.js';
11
11
  import { cycleValue, formatContentTitle, truncate, useListSelection } from '#views/dev/utils/panel_helpers.js';
12
- import { RUN_DETAIL_VISIBLE_STEPS } from '#views/dev/utils/ui_constants.js';
12
+ import { RUN_DETAIL_VISIBLE_STEPS } from '#views/dev/utils/constants.js';
13
13
  import { ContentTitle, getHeight as getContentTitleHeight } from '#views/dev/components/content_title.js';
14
14
  import { MasterDetailPanel } from '#views/dev/components/master_detail_panel.js';
15
15
  import { ModalFrame, getHeight as getModalFrameHeight } from '#views/dev/modals/modal_frame.js';
@@ -14,7 +14,7 @@ import { JsonView } from '#views/dev/utils/json_render.js';
14
14
  import { RunInfoSidebar } from '#views/dev/components/run_info_sidebar.js';
15
15
  import { MasterDetailPanel } from '#views/dev/components/master_detail_panel.js';
16
16
  import { capitalize, cycleValue, formatContentTitle, formatStartedShort, hasJsonValue, truncate, useListSelection } from '#views/dev/utils/panel_helpers.js';
17
- import { CATALOG_WORKFLOW_NAME, RUNS_VISIBLE_ROWS } from '#views/dev/utils/ui_constants.js';
17
+ import { CATALOG_WORKFLOW_NAME, RUNS_VISIBLE_ROWS } from '#views/dev/utils/constants.js';
18
18
  const TEMPORAL_UI_BASE = 'http://localhost:8080';
19
19
  const STATUS_ORDER = {
20
20
  running: 0,
@@ -121,7 +121,6 @@ const DetailPane = ({ run, pane, rows }) => {
121
121
  export const RUNS_HINTS = [
122
122
  { key: '↑/↓', label: 'navigate' },
123
123
  { key: 'enter', label: 'open' },
124
- { key: 'g', label: 'graph' },
125
124
  { key: '←/→', label: 'switch pane' },
126
125
  { key: 'e', label: 'expand' },
127
126
  { key: 'o', label: 'temporal' }
@@ -174,10 +173,6 @@ export const RunsPanel = ({ runs, height }) => {
174
173
  ui.setRunsView('detail');
175
174
  return;
176
175
  }
177
- if (input === 'g' && selectedRun?.workflowId) {
178
- ui.openStepGraph(selectedRun);
179
- return;
180
- }
181
176
  if (key.leftArrow || key.rightArrow) {
182
177
  ui.setRunListPaneTab(cycleValue(RUN_INFO_TAB_ORDER, ui.runListPaneTab, key.rightArrow ? 1 : -1));
183
178
  return;
@@ -188,7 +183,7 @@ export const RunsPanel = ({ runs, height }) => {
188
183
  const title = formatContentTitle(['Recent Runs', `Workflow "${selectedRun?.workflowType ?? ''}"`, capitalize(activePane)]);
189
184
  ui.openExpandedJson(content, title);
190
185
  }
191
- }, { isActive: ui.tab === 'runs' && ui.runsView === 'list' && !ui.search.open && !ui.stepGraph.open });
186
+ }, { isActive: ui.tab === 'runs' && ui.runsView === 'list' && !ui.search.open });
192
187
  if (runs.length === 0) {
193
188
  return (_jsx(Box, { flexDirection: "column", children: _jsx(Text, { dimColor: true, children: "No runs yet. Trigger one from the Workflows tab or with `output workflow run \u2026`." }) }));
194
189
  }
@@ -8,7 +8,7 @@ import { SelectionIndicator } from '#views/dev/chrome/selection_indicator.js';
8
8
  import { useUiState } from '#views/dev/state/ui_state.js';
9
9
  import { MasterDetailPanel } from '#views/dev/components/master_detail_panel.js';
10
10
  import { formatStartedShort, useListSelection } from '#views/dev/utils/panel_helpers.js';
11
- import { WORKFLOWS_VISIBLE_ROWS, WORKFLOWS_RECENT_RUNS_LIMIT } from '#views/dev/utils/ui_constants.js';
11
+ import { WORKFLOWS_VISIBLE_ROWS, WORKFLOWS_RECENT_RUNS_LIMIT } from '#views/dev/utils/constants.js';
12
12
  const COL = {
13
13
  indicator: 3,
14
14
  name: 30
@@ -1,5 +1,4 @@
1
1
  import React from 'react';
2
- import type { WorkflowRun } from '#services/workflow_runs.js';
3
2
  export type Tab = 'workflows' | 'runs' | 'services' | 'help';
4
3
  export declare const TAB_ORDER: Tab[];
5
4
  export declare const TAB_LABELS: Record<Tab, string>;
@@ -26,10 +25,6 @@ export interface ExpandedJsonState {
26
25
  value: unknown;
27
26
  title: string;
28
27
  }
29
- export interface StepGraphState {
30
- open: boolean;
31
- run: WorkflowRun | null;
32
- }
33
28
  export interface Toast {
34
29
  id: number;
35
30
  message: string;
@@ -45,7 +40,6 @@ export interface UiState {
45
40
  runsView: RunsView;
46
41
  runModal: RunModalState;
47
42
  expandedJson: ExpandedJsonState;
48
- stepGraph: StepGraphState;
49
43
  toasts: Toast[];
50
44
  setTab: (tab: Tab) => void;
51
45
  nextTab: () => void;
@@ -62,8 +56,6 @@ export interface UiState {
62
56
  closeRunModal: () => void;
63
57
  openExpandedJson: (value: unknown, title: string) => void;
64
58
  closeExpandedJson: () => void;
65
- openStepGraph: (run: WorkflowRun) => void;
66
- closeStepGraph: () => void;
67
59
  pushToast: (message: string, tone?: Toast['tone']) => void;
68
60
  dismissToast: (id: number) => void;
69
61
  }
@@ -18,7 +18,6 @@ export const UiStateProvider = ({ children }) => {
18
18
  const [runsView, setRunsView] = useState('list');
19
19
  const [runModal, setRunModal] = useState({ open: false, workflowName: '' });
20
20
  const [expandedJson, setExpandedJson] = useState({ open: false, value: null, title: '' });
21
- const [stepGraph, setStepGraph] = useState({ open: false, run: null });
22
21
  const [toasts, setToasts] = useState([]);
23
22
  const toastIdRef = useRef(0);
24
23
  const value = useMemo(() => ({
@@ -30,7 +29,6 @@ export const UiStateProvider = ({ children }) => {
30
29
  runsView,
31
30
  runModal,
32
31
  expandedJson,
33
- stepGraph,
34
32
  toasts,
35
33
  setTab: next => {
36
34
  setTab(current => {
@@ -66,14 +64,12 @@ export const UiStateProvider = ({ children }) => {
66
64
  closeRunModal: () => setRunModal({ open: false, workflowName: '' }),
67
65
  openExpandedJson: (value, title) => setExpandedJson({ open: true, value, title }),
68
66
  closeExpandedJson: () => setExpandedJson({ open: false, value: null, title: '' }),
69
- openStepGraph: (run) => setStepGraph({ open: true, run }),
70
- closeStepGraph: () => setStepGraph({ open: false, run: null }),
71
67
  pushToast: (message, tone = 'info') => {
72
68
  const id = ++toastIdRef.current;
73
69
  setToasts(prev => [...prev, { id, message, tone }].slice(-MAX_VISIBLE_TOASTS));
74
70
  },
75
71
  dismissToast: (id) => setToasts(prev => prev.filter(t => t.id !== id))
76
- }), [tab, search, selection, runListPaneTab, runStepPaneTab, runsView, runModal, expandedJson, stepGraph, toasts]);
72
+ }), [tab, search, selection, runListPaneTab, runStepPaneTab, runsView, runModal, expandedJson, toasts]);
77
73
  return _jsx(UiStateContext.Provider, { value: value, children: children });
78
74
  };
79
75
  export const useUiState = () => {
@@ -682,86 +682,6 @@
682
682
  "generate.js"
683
683
  ]
684
684
  },
685
- "workflow:history": {
686
- "aliases": [],
687
- "args": {
688
- "workflowId": {
689
- "description": "The workflow ID to show history for",
690
- "name": "workflowId",
691
- "required": true
692
- }
693
- },
694
- "description": "Show a workflow run's step timeline as a waterfall (durations and start times)",
695
- "examples": [
696
- "<%= config.bin %> <%= command.id %> wf-12345",
697
- "<%= config.bin %> <%= command.id %> wf-12345 --run-id 2fe0b36b-...",
698
- "<%= config.bin %> <%= command.id %> wf-12345 --format json",
699
- "<%= config.bin %> <%= command.id %> wf-12345 --raw --include-payloads"
700
- ],
701
- "flags": {
702
- "run-id": {
703
- "char": "r",
704
- "description": "Show a specific run (defaults to the latest run)",
705
- "name": "run-id",
706
- "hasDynamicHelp": false,
707
- "multiple": false,
708
- "type": "option"
709
- },
710
- "format": {
711
- "char": "f",
712
- "description": "Output format",
713
- "name": "format",
714
- "default": "text",
715
- "hasDynamicHelp": false,
716
- "multiple": false,
717
- "options": [
718
- "text",
719
- "json"
720
- ],
721
- "type": "option"
722
- },
723
- "raw": {
724
- "description": "Print the history endpoint's raw response (workflow + events)",
725
- "name": "raw",
726
- "allowNo": false,
727
- "type": "boolean"
728
- },
729
- "include-payloads": {
730
- "description": "Include decoded step input/output payloads",
731
- "name": "include-payloads",
732
- "allowNo": false,
733
- "type": "boolean"
734
- },
735
- "width": {
736
- "description": "Override the detected terminal width",
737
- "name": "width",
738
- "hasDynamicHelp": false,
739
- "multiple": false,
740
- "type": "option"
741
- },
742
- "color": {
743
- "description": "Colorize the waterfall (use --no-color to disable)",
744
- "name": "color",
745
- "allowNo": true,
746
- "type": "boolean"
747
- }
748
- },
749
- "hasDynamicHelp": false,
750
- "hiddenAliases": [],
751
- "id": "workflow:history",
752
- "pluginAlias": "@outputai/cli",
753
- "pluginName": "@outputai/cli",
754
- "pluginType": "core",
755
- "strict": true,
756
- "enableJsonFlag": false,
757
- "isESM": true,
758
- "relativePath": [
759
- "dist",
760
- "commands",
761
- "workflow",
762
- "history.js"
763
- ]
764
- },
765
685
  "workflow:list": {
766
686
  "aliases": [],
767
687
  "args": {},
@@ -1534,5 +1454,5 @@
1534
1454
  ]
1535
1455
  }
1536
1456
  },
1537
- "version": "0.9.1-dev.000c5f3.0"
1457
+ "version": "0.9.1-dev.667788.0"
1538
1458
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outputai/cli",
3
- "version": "0.9.1-dev.000c5f3.0",
3
+ "version": "0.9.1-dev.667788.0",
4
4
  "description": "CLI for Output.ai workflow generation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -36,9 +36,9 @@
36
36
  "semver": "7.7.4",
37
37
  "undici": "8.5.0",
38
38
  "yaml": "^2.8.3",
39
- "@outputai/evals": "0.9.1-dev.000c5f3.0",
40
- "@outputai/llm": "0.9.1-dev.000c5f3.0",
41
- "@outputai/credentials": "0.9.1-dev.000c5f3.0"
39
+ "@outputai/credentials": "0.9.1-dev.667788.0",
40
+ "@outputai/evals": "0.9.1-dev.667788.0",
41
+ "@outputai/llm": "0.9.1-dev.667788.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/cli-progress": "3.11.6",
@@ -1,19 +0,0 @@
1
- import { Command } from '@oclif/core';
2
- export default class WorkflowHistory extends Command {
3
- static description: string;
4
- static examples: string[];
5
- static args: {
6
- workflowId: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
7
- };
8
- static flags: {
9
- 'run-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
- format: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
- raw: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
- 'include-payloads': import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
- width: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
- color: import("@oclif/core/interfaces").BooleanFlag<boolean>;
15
- };
16
- run(): Promise<void>;
17
- private buildHeader;
18
- catch(error: Error): Promise<void>;
19
- }
@@ -1,99 +0,0 @@
1
- import { Args, Command, Flags } from '@oclif/core';
2
- import { fetchWorkflowHistory } from '#services/workflow_history.js';
3
- import buildSpanLabels from '#utils/span_labels.js';
4
- import renderWaterfall, { formatDurationLabel } from '#utils/waterfall.js';
5
- import { handleApiError } from '#utils/error_handler.js';
6
- const DEFAULT_WIDTH = 80;
7
- const OUTPUT_FORMAT = { JSON: 'json', TEXT: 'text' };
8
- export default class WorkflowHistory extends Command {
9
- static description = 'Show a workflow run\'s step timeline as a waterfall (durations and start times)';
10
- static examples = [
11
- '<%= config.bin %> <%= command.id %> wf-12345',
12
- '<%= config.bin %> <%= command.id %> wf-12345 --run-id 2fe0b36b-...',
13
- '<%= config.bin %> <%= command.id %> wf-12345 --format json',
14
- '<%= config.bin %> <%= command.id %> wf-12345 --raw --include-payloads'
15
- ];
16
- static args = {
17
- workflowId: Args.string({
18
- description: 'The workflow ID to show history for',
19
- required: true
20
- })
21
- };
22
- static flags = {
23
- 'run-id': Flags.string({
24
- char: 'r',
25
- description: 'Show a specific run (defaults to the latest run)'
26
- }),
27
- format: Flags.string({
28
- char: 'f',
29
- description: 'Output format',
30
- options: [OUTPUT_FORMAT.TEXT, OUTPUT_FORMAT.JSON],
31
- default: OUTPUT_FORMAT.TEXT
32
- }),
33
- raw: Flags.boolean({
34
- description: 'Print the history endpoint\'s raw response (workflow + events)',
35
- default: false
36
- }),
37
- 'include-payloads': Flags.boolean({
38
- description: 'Include decoded step input/output payloads',
39
- default: false
40
- }),
41
- width: Flags.integer({
42
- description: 'Override the detected terminal width'
43
- }),
44
- color: Flags.boolean({
45
- description: 'Colorize the waterfall (use --no-color to disable)',
46
- default: true,
47
- allowNo: true
48
- })
49
- };
50
- async run() {
51
- const { args, flags } = await this.parse(WorkflowHistory);
52
- const result = await fetchWorkflowHistory({
53
- workflowId: args.workflowId,
54
- runId: flags['run-id'],
55
- includePayloads: flags['include-payloads']
56
- });
57
- if (flags.raw) {
58
- this.log(JSON.stringify({
59
- workflow: result.workflow,
60
- runId: result.runId,
61
- events: result.events
62
- }, null, 2));
63
- return;
64
- }
65
- if (flags.format === OUTPUT_FORMAT.JSON) {
66
- this.log(JSON.stringify({
67
- workflow: result.workflow,
68
- runId: result.runId,
69
- totalDurationMs: result.totalDurationMs,
70
- spans: result.spans
71
- }, null, 2));
72
- return;
73
- }
74
- const labels = buildSpanLabels(result.spans);
75
- const width = flags.width ?? process.stdout.columns ?? DEFAULT_WIDTH;
76
- const color = flags.color && !process.env.NO_COLOR &&
77
- (!!process.env.FORCE_COLOR || process.stdout.isTTY === true);
78
- this.log(renderWaterfall(result.spans, result.totalDurationMs, {
79
- width,
80
- color,
81
- labels,
82
- header: this.buildHeader(args.workflowId, result.runId, result.workflow?.status, result.totalDurationMs)
83
- }));
84
- // Failure reasons live in the payloads the server strips by default, so a
85
- // failed run shows red bars but no messages until payloads are requested.
86
- if (!flags['include-payloads'] && result.spans.some(span => span.status === 'failed')) {
87
- this.log('\nSome steps failed — re-run with --include-payloads to see their error messages.');
88
- }
89
- }
90
- buildHeader(workflowId, runId, status, totalDurationMs) {
91
- const shortRun = runId ? runId.slice(0, 8) : 'unknown';
92
- return `${workflowId} · run ${shortRun} · ${status ?? 'unknown'} · ${formatDurationLabel(totalDurationMs)}`;
93
- }
94
- async catch(error) {
95
- return handleApiError(error, (...args) => this.error(...args), {
96
- 404: 'Workflow not found. Check the workflow ID.'
97
- });
98
- }
99
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,26 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- // Isolate the command module from the API/service layer at import time.
3
- vi.mock('../../services/workflow_history.js', () => ({
4
- fetchWorkflowHistory: vi.fn()
5
- }));
6
- describe('workflow history command', () => {
7
- it('exports a valid OCLIF command with a workflowId arg', async () => {
8
- const WorkflowHistory = (await import('./history.js')).default;
9
- expect(WorkflowHistory).toBeDefined();
10
- expect(WorkflowHistory.description).toContain('waterfall');
11
- expect(WorkflowHistory.args).toHaveProperty('workflowId');
12
- expect(WorkflowHistory.args.workflowId.required).toBe(true);
13
- });
14
- it('declares the expected flags and defaults', async () => {
15
- const WorkflowHistory = (await import('./history.js')).default;
16
- const flags = WorkflowHistory.flags;
17
- expect(flags).toHaveProperty('run-id');
18
- expect(flags).toHaveProperty('raw');
19
- expect(flags).toHaveProperty('include-payloads');
20
- expect(flags).toHaveProperty('color');
21
- expect(flags).toHaveProperty('width');
22
- expect(flags.format.options).toEqual(['text', 'json']);
23
- expect(flags.format.default).toBe('text');
24
- expect(flags.raw.default).toBe(false);
25
- });
26
- });
@@ -1,26 +0,0 @@
1
- export type SpanStatus = 'pending' | 'running' | 'completed' | 'failed';
2
- export type SpanKind = 'activity' | 'child_workflow';
3
- export interface Span {
4
- id: string;
5
- name: string;
6
- technicalName: string;
7
- description: string | null;
8
- status: SpanStatus;
9
- kind: SpanKind;
10
- attempt: number;
11
- startedAt: string | null;
12
- scheduledAt: string | null;
13
- completedAt: string | null;
14
- startOffsetMs: number;
15
- endOffsetMs: number;
16
- durationMs: number;
17
- failureMessage: string | null;
18
- input?: unknown;
19
- output?: unknown;
20
- }
21
- export type HistoryEvent = Record<string, unknown>;
22
- /**
23
- * @param events - flat Temporal history events, in chronological order
24
- * @param workflowStartTimeMs - epoch ms used as the timeline origin (0 offset)
25
- */
26
- export declare function correlate(events: HistoryEvent[], workflowStartTimeMs: number | null): Span[];