Skip to content

Conversation

@karthikscale3
Copy link
Contributor

@karthikscale3 karthikscale3 commented Nov 28, 2025

Note: This PR is related to #455

Adds a new "Workflows" tab to the observability dashboard that displays workflow definitions with interactive graph visualization.

Changes

  • @workflow/web-shared: Add fetchWorkflowsManifest server action to read the workflows.json manifest generated by the build process
  • @workflow/web: Add useWorkflowGraphManifest hook for fetching workflow graph data
  • @workflow/web: Add "Workflows" tab to the main page displaying all registered workflows
  • @workflow/web: Add WorkflowsList component with table view and slide-out graph viewer

Features

  • Lists all workflows with their file paths and step counts
  • Click on a workflow to view its control flow graph in a side panel
  • Shows step nodes, edges, and control flow structure (loops, conditionals, parallel execution)

@changeset-bot
Copy link

changeset-bot bot commented Nov 28, 2025

🦋 Changeset detected

Latest commit: 6c51f45

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 6 packages
Name Type
@workflow/web-shared Patch
@workflow/web Patch
@workflow/cli Patch
workflow Patch
@workflow/world-testing Patch
@workflow/ai Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Contributor

vercel bot commented Nov 28, 2025

@karthikscale3 is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@socket-security
Copy link

socket-security bot commented Nov 28, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​@​radix-ui/​react-dropdown-menu@​2.1.6991007499100

View full report

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes here are mostly around standardizing with

  • shadcn
  • tailwind

className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<LayoutClient>{children}</LayoutClient>
<NuqsAdapter>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added support for https://nuqs.dev/ so it's easier to make every url stateful without maintaining any custom code

selectedHookId={selectedHookId}
/>
</ErrorBoundary>
<div className="max-w-7xl mx-auto px-4">
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redesigned the UI to have tabs view so it scales better and also provides visual focus

return <SettingsSidebar open={open} onOpenChange={onOpenChange} />;
}

export function SettingsDropdown() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a dedicated settings dropdown for theme switching and linking to docs. Moved the link to docs from the workflows logo on the top left as it's normally used for navigating to the home.

@@ -0,0 +1,36 @@
import { cva, type VariantProps } from 'class-variance-authority';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standard shadcn component

import type * as React from 'react';

import { cn } from '@/lib/utils';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standard shadcn component

@@ -0,0 +1,200 @@
'use client';

import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standard shadcn component

@@ -0,0 +1,44 @@
'use client';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standard shadcn component

@@ -0,0 +1,139 @@
'use client';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standard shadcn component

@@ -0,0 +1,66 @@
'use client';

import * as TabsPrimitive from '@radix-ui/react-tabs';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standard shadcn component

@karthikscale3 karthikscale3 changed the title Add workflow graph visualization to observability UI Add workflow CFG visualization to observability UI Nov 28, 2025
* Hook to fetch the workflow graph manifest from the workflow data directory
* The manifest contains static structure information about all workflows
*/
export function useWorkflowGraphManifest(config: WorldConfig) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utility hook for fetching the workflow graph from the workflows.json file

Comment on lines +94 to +107
<div className="space-y-6">
{graphError && (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Error Loading Workflows</AlertTitle>
<AlertDescription>{graphError.message}</AlertDescription>
</Alert>
)}
<WorkflowsList
workflows={workflows}
onWorkflowSelect={() => {}}
loading={graphLoading}
/>
</div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<div className="space-y-6">
{graphError && (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Error Loading Workflows</AlertTitle>
<AlertDescription>{graphError.message}</AlertDescription>
</Alert>
)}
<WorkflowsList
workflows={workflows}
onWorkflowSelect={() => {}}
loading={graphLoading}
/>
</div>
{graphError ? (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertTitle>Error Loading Workflows</AlertTitle>
<AlertDescription>{graphError.message}</AlertDescription>
</Alert>
) : (
<WorkflowsList
workflows={workflows}
onWorkflowSelect={() => {}}
loading={graphLoading}
/>
)}

The Workflows tab displays both an error alert and a "No Workflows Found" message when the manifest load fails, which conflates the error state with an empty data state and misleads users about the actual issue.

View Details

Analysis

Workflows tab displays both error alert and "No Workflows Found" message when manifest load fails

What fails: The Workflows tab in packages/web/src/app/page.tsx renders both an error alert AND a "No Workflows Found" message simultaneously when the workflow manifest fails to load, conflating the error state with an empty data state.

How to reproduce:

  1. Simulate a manifest load failure in useWorkflowGraphManifest by causing the fetchWorkflowsManifest call to reject
  2. Navigate to the Workflows tab
  3. Observe both messages appearing together on screen

What happens: When useWorkflowGraphManifest fails:

  • graphError becomes truthy (error object)
  • graphManifest becomes null
  • workflows becomes [] (empty array from line 59)
  • graphLoading becomes false

The page then renders:

  • Error alert (lines 95-101) showing the error message ✓
  • WorkflowsList component with workflows=[] and loading=false (lines 102-106)

Inside WorkflowsList, the condition if (workflows.length === 0) evaluates to true (since loading=false), so it renders "No Workflows Found" message.

Result: Users see both "Error Loading Workflows" alert with the actual error AND "No Workflows Found" message, which misleads them about the actual issue (failed to load vs successfully loaded but empty).

Expected behavior: When there's an error loading the manifest, ONLY the error alert should display. The empty state message should only show when workflows were successfully loaded but the list is empty.

Fix: Changed the Workflows tab rendering from showing both error alert and WorkflowsList unconditionally to using mutually exclusive ternary logic (matching the pattern in run-detail-view.tsx lines 428-461):

  • If error: show error alert only
  • Else: show WorkflowsList (which handles loading and empty states)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant