feat(workflow) - Add validation layer (#21422)

Add workflow validation framework and consolidate output schema
types/search logic into twenty-shared

This PR introduces a comprehensive workflow validation system that
catches configuration errors at build-time, and consolidates the
fragmented output-schema type definitions and variable-search logic from
the front-end into twenty-shared

**Workflow validation** — A new system that checks workflows for errors
before activation: graph connectivity (unreachable steps, dangling
references), step parameter schemas (via Zod), variable references
(typos, wrong step order), and workspace metadata (non-existent
objects). Returns structured errors/warnings with "did you mean?"
suggestions. Runs automatically after create_complete_workflow and
update_workflow_version_step, and is also available as a standalone
validate_workflow tool.

**Output schema consolidation** — Moves all output schema types and the
variable-search logic from scattered front-end files into twenty-shared,
replacing ~800 lines of duplicated per-schema-type code with a single
unified searchVariableInOutputSchema dispatcher.


To do : 
- validation on CODE and AGENT step

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Etienne
2026-06-12 10:23:03 +02:00
committed by GitHub
parent 2538239e05
commit fefd9d7704
120 changed files with 4445 additions and 1192 deletions
@@ -0,0 +1,30 @@
import { isObject } from '@sniptt/guards';
import { type BaseOutputSchemaV2 } from '@/workflow/workflow-schema/types/base-output-schema.type';
export const collectOutputSchemaPaths = (
schema: BaseOutputSchemaV2,
prefix: string[] = [],
): string[] => {
const paths: string[] = [];
if (!isObject(schema)) {
return paths;
}
for (const [key, field] of Object.entries(schema)) {
if (!isObject(field)) {
continue;
}
const currentPath = [...prefix, key];
paths.push(currentPath.join('.'));
if (!field.isLeaf && isObject(field.value)) {
paths.push(...collectOutputSchemaPaths(field.value, currentPath));
}
}
return paths;
};