diff --git a/CLAUDE.md b/CLAUDE.md
index db2645e..1e0792e 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Project Overview
-Visual workflow builder for agentic LLM pipelines. Users drag-and-drop nodes (Start, Agent, If/Else, Approval, End) onto a canvas, connect them, configure LLM prompts and branching logic, then execute workflows server-side against OpenAI. Run results are persisted as JSON audit trails.
+Visual workflow builder for agentic LLM pipelines. Users drag-and-drop nodes (Start, Agent, If/Else, Approval) onto a canvas, connect them, configure LLM prompts and branching logic, then execute workflows server-side against OpenAI. Run results are persisted as JSON audit trails.
## Monorepo Layout
diff --git a/README.md b/README.md
index 609b0b4..ec55175 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Agentic Workflow Builder
-Agentic Workflow Builder is a web app for visually composing, executing, and auditing LLM workflows. Drag Start, Agent, If/Else, Approval, and End nodes onto the canvas, connect them with Bezier edges, configure prompts inline, and run the flow through a server-side engine that records every step for later review.
+Agentic Workflow Builder is a web app for visually composing, executing, and auditing LLM workflows. Drag Start, Agent, If/Else, and Approval nodes onto the canvas, connect them with Bezier edges, configure prompts inline, and run the flow through a server-side engine that records every step for later review.
## Repository Layout
diff --git a/apps/web/index.html b/apps/web/index.html
index 6aba8e9..6b6164e 100644
--- a/apps/web/index.html
+++ b/apps/web/index.html
@@ -39,9 +39,6 @@
diff --git a/apps/web/src/app/workflow-editor.test.ts b/apps/web/src/app/workflow-editor.test.ts
new file mode 100644
index 0000000..5fcaadc
--- /dev/null
+++ b/apps/web/src/app/workflow-editor.test.ts
@@ -0,0 +1,33 @@
+import { describe, expect, it, vi } from 'vitest';
+
+import { WorkflowEditor } from './workflow-editor';
+
+describe('WorkflowEditor renderPorts', () => {
+ it('renders an output port for start nodes', () => {
+ const renderPorts = (
+ WorkflowEditor.prototype as unknown as {
+ renderPorts: (
+ node: { id: string; type: string },
+ el: { appendChild: (port: { handle: string }) => void }
+ ) => void;
+ }
+ ).renderPorts;
+ const createPort = vi.fn((_nodeId: string, handle: string) => ({ handle }));
+ const appended: Array<{ handle: string }> = [];
+ const element = {
+ appendChild: (port: { handle: string }) => {
+ appended.push(port);
+ }
+ };
+
+ renderPorts.call(
+ { createPort, getNodeHeaderPortTop: () => 24 },
+ { id: 'node_start', type: 'start' },
+ element
+ );
+
+ expect(createPort).toHaveBeenCalledTimes(1);
+ expect(createPort).toHaveBeenCalledWith('node_start', 'output', 'port-out', 'Next step', 24);
+ expect(appended).toEqual([{ handle: 'output' }]);
+ });
+});
diff --git a/apps/web/src/app/workflow-editor.ts b/apps/web/src/app/workflow-editor.ts
index a639af7..65aafe8 100644
--- a/apps/web/src/app/workflow-editor.ts
+++ b/apps/web/src/app/workflow-editor.ts
@@ -1722,7 +1722,6 @@ export class WorkflowEditor {
case 'approval':
return { prompt: 'Review and approve this step.', collapsed: true };
case 'start':
- case 'end':
return { collapsed: true };
default:
return { collapsed: true };
@@ -1802,7 +1801,7 @@ export class WorkflowEditor {
if (!node.data) node.data = {};
if (node.data.collapsed === undefined) {
- node.data.collapsed = node.type === 'start' || node.type === 'end';
+ node.data.collapsed = node.type === 'start';
}
const hasSettings = this.nodeHasSettings(node);
el.classList.toggle('expanded', !node.data.collapsed);
@@ -1954,7 +1953,6 @@ export class WorkflowEditor {
return `
${escapeHtml(name)}`;
}
if (node.type === 'start') return '
Start';
- if (node.type === 'end') return '
End';
if (node.type === 'if') return '
Condition';
if (node.type === 'approval') return '
User Approval';
return `
${node.type}`;
@@ -2313,13 +2311,11 @@ export class WorkflowEditor {
}
if (node.type !== 'start') {
- const inputTooltip = node.type === 'end' ? 'End input' : 'Input';
- const portIn = this.createPort(node.id, 'input', 'port-in', inputTooltip, this.getNodeHeaderPortTop(node));
+ const portIn = this.createPort(node.id, 'input', 'port-in', 'Input', this.getNodeHeaderPortTop(node));
el.appendChild(portIn);
}
- if (node.type !== 'end') {
- if (node.type === 'if') {
+ if (node.type === 'if') {
const conditions = this.getIfConditions(node);
if (this.shouldAggregateCollapsedIfPorts(node)) {
const aggregateConditionPort = this.createPort(
@@ -2399,7 +2395,6 @@ export class WorkflowEditor {
const outputTooltip = node.type === 'start' ? 'Next step' : 'Output';
el.appendChild(this.createPort(node.id, 'output', 'port-out', outputTooltip, this.getNodeHeaderPortTop(node)));
}
- }
}
createPort(
diff --git a/apps/web/src/data/help-content.ts b/apps/web/src/data/help-content.ts
index 7ad99cd..82f1a24 100644
--- a/apps/web/src/data/help-content.ts
+++ b/apps/web/src/data/help-content.ts
@@ -12,7 +12,7 @@ export const helpContent = `
Overview
- The Agentic Workflow Builder lets you compose agent flows with Start, Agent, Condition, Approval, and End nodes. Drag nodes, connect them, configure prompts, and run against the server-side workflow engine.
+ The Agentic Workflow Builder lets you compose agent flows with Start, Agent, Condition, and Approval nodes. Drag nodes, connect them, configure prompts, and run against the server-side workflow engine.
diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts
index c6bbd73..8cef669 100644
--- a/packages/types/src/index.ts
+++ b/packages/types/src/index.ts
@@ -1,4 +1,4 @@
-export type NodeType = 'start' | 'agent' | 'if' | 'approval' | 'end' | string;
+export type NodeType = 'start' | 'agent' | 'if' | 'approval' | string;
export interface BaseNodeData {
collapsed?: boolean;
diff --git a/packages/workflow-engine/src/index.ts b/packages/workflow-engine/src/index.ts
index 77f3c71..1ecd789 100644
--- a/packages/workflow-engine/src/index.ts
+++ b/packages/workflow-engine/src/index.ts
@@ -339,8 +339,6 @@ export class WorkflowEngine {
this.waitingForInput = true;
this.log(node.id, 'wait_input', 'Waiting for user approval');
return undefined;
- case 'end':
- return undefined;
default:
this.log(node.id, 'warn', `Unknown node type "${node.type}" skipped`);
}
@@ -456,8 +454,6 @@ export class WorkflowEngine {
return 'condition node';
case 'approval':
return 'approval node';
- case 'end':
- return 'end node';
default:
return `${node.type} node`;
}