Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4a1788b
Fix formatting for configuration error state
karthikscale3 Nov 22, 2025
f073014
Move hooks and runs as tabs
karthikscale3 Nov 22, 2025
82240ef
Theme updates
karthikscale3 Nov 23, 2025
ab87596
Migrate to nuqs
karthikscale3 Nov 23, 2025
1dc7df5
fix warnings
karthikscale3 Nov 23, 2025
acb109a
Minor fixes
karthikscale3 Nov 23, 2025
1bfd16d
Minor fixes
karthikscale3 Nov 23, 2025
4b4b55a
fix back button
karthikscale3 Nov 23, 2025
53dacc1
make font size small
karthikscale3 Nov 23, 2025
ef0ab99
Fix theme issue
karthikscale3 Nov 23, 2025
0af4c2d
workflow views
karthikscale3 Nov 23, 2025
e00700f
Fix graph extraction logic
karthikscale3 Nov 24, 2025
bbf3b41
Implement CFG
karthikscale3 Nov 24, 2025
e274059
Improve dashboard layout and workflow viewer
karthikscale3 Nov 24, 2025
9a583fd
Merge branch 'main' of github.com:karthikscale3/workflow into karthik…
karthikscale3 Nov 25, 2025
33237b2
refactor: move graph extraction to TypeScript post-bundle
karthikscale3 Nov 25, 2025
f5cbe81
nit: remove unneeded changes
karthikscale3 Nov 25, 2025
af497fd
Capture tools as steps
karthikscale3 Nov 25, 2025
080df95
fix
karthikscale3 Nov 25, 2025
9312eba
fix
karthikscale3 Nov 25, 2025
1aa86d8
chore: consolidate graph extraction changesets
karthikscale3 Nov 25, 2025
5b6697a
UI updates
karthikscale3 Nov 25, 2025
0e0c522
UI updates
karthikscale3 Nov 25, 2025
4972ffe
UI enhancements
karthikscale3 Nov 25, 2025
de123cd
Update graph node selectors
karthikscale3 Nov 25, 2025
1e8def6
Merge branch 'main' of github.com:karthikscale3/workflow into karthik…
karthikscale3 Nov 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/post-bundle-graph-extraction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"@workflow/builders": patch
"@workflow/next": patch
"@workflow/web": patch
---

Refactor graph extraction to post-bundle TypeScript AST traversal. This replaces the previous Rust-based per-file analysis with a more accurate approach that analyzes the bundled workflow code, enabling:

- Full CFG representation including loops, conditionals (with proper Then/Else branch metadata), and parallel execution
- Detection of step functions from imported packages
- Detection of indirect step calls through helper functions
- Step reference detection in tool configurations

Web dashboard improvements:
- Migrate to nuqs for URL state management
- Add graph execution mapper to match runtime step executions to graph nodes
- Improve workflow graph visualization with proper execution status display

52 changes: 50 additions & 2 deletions packages/builders/src/base-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const EMIT_SOURCEMAPS_FOR_DEBUGGING =
*/
export abstract class BaseBuilder {
protected config: WorkflowConfig;
protected lastWorkflowManifest?: WorkflowManifest;

constructor(config: WorkflowConfig) {
this.config = config;
Expand Down Expand Up @@ -253,6 +254,7 @@ export abstract class BaseBuilder {
* Steps have full Node.js runtime access and handle side effects, API calls, etc.
*
* @param externalizeNonSteps - If true, only bundles step entry points and externalizes other code
* @returns Build context (for watch mode) and the collected workflow manifest
*/
protected async createStepsBundle({
inputFiles,
Expand All @@ -268,7 +270,10 @@ export abstract class BaseBuilder {
outfile: string;
format?: 'cjs' | 'esm';
externalizeNonSteps?: boolean;
}): Promise<esbuild.BuildContext | undefined> {
}): Promise<{
context: esbuild.BuildContext | undefined;
manifest: WorkflowManifest;
}> {
// These need to handle watching for dev to scan for
// new entries and changes to existing ones
const { discoveredSteps: stepFiles } = await this.discoverEntries(
Expand Down Expand Up @@ -389,10 +394,14 @@ export abstract class BaseBuilder {
// Create .gitignore in .swc directory
await this.createSwcGitignore();

// Store the manifest for later use (e.g., graph generation in watch mode)
this.lastWorkflowManifest = workflowManifest;

if (this.config.watch) {
return esbuildCtx;
return { context: esbuildCtx, manifest: workflowManifest };
}
await esbuildCtx.dispose();
return { context: undefined, manifest: workflowManifest };
}

/**
Expand Down Expand Up @@ -838,4 +847,43 @@ export const OPTIONS = handler;`;
// We're intentionally silently ignoring this error - creating .gitignore isn't critical
}
}

/**
* Creates a graph manifest JSON file by extracting from the bundled workflow file.
* The manifest contains React Flow-compatible graph data for visualizing workflows.
*/
protected async createGraphManifest({
workflowBundlePath,
outfile,
}: {
workflowBundlePath: string;
outfile: string;
}): Promise<void> {
const graphBuildStart = Date.now();
console.log('Creating workflow graph manifest...');

try {
// Import the graph extractor
const { extractGraphFromBundle } = await import('./graph-extractor.js');

// Extract graph from the bundled workflow file
const graphManifest = await extractGraphFromBundle(workflowBundlePath);

// Write the graph manifest
await this.ensureDirectory(outfile);
await writeFile(outfile, JSON.stringify(graphManifest, null, 2));

console.log(
`Created graph manifest with ${
Object.keys(graphManifest.workflows).length
} workflow(s)`,
`${Date.now() - graphBuildStart}ms`
);
} catch (error) {
console.warn(
'Failed to extract graph from bundle:',
error instanceof Error ? error.message : String(error)
);
}
}
}
Loading
Loading