@principal-ai/principal-view-core 0.24.77 → 0.24.78
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.
- package/dist/workflow/edge-derivation.d.ts +109 -0
- package/dist/workflow/edge-derivation.d.ts.map +1 -0
- package/dist/workflow/edge-derivation.js +171 -0
- package/dist/workflow/edge-derivation.js.map +1 -0
- package/dist/workflow/edge-validation.d.ts +170 -0
- package/dist/workflow/edge-validation.d.ts.map +1 -0
- package/dist/workflow/edge-validation.js +323 -0
- package/dist/workflow/edge-validation.js.map +1 -0
- package/dist/workflow/index.d.ts +6 -1
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +20 -1
- package/dist/workflow/index.js.map +1 -1
- package/dist/workflow/template-renderer.d.ts.map +1 -1
- package/dist/workflow/template-renderer.js +8 -4
- package/dist/workflow/template-renderer.js.map +1 -1
- package/dist/workflow/types.d.ts +58 -4
- package/dist/workflow/types.d.ts.map +1 -1
- package/dist/workflow/types.js +29 -0
- package/dist/workflow/types.js.map +1 -1
- package/dist/workflow/validator.d.ts.map +1 -1
- package/dist/workflow/validator.js +13 -6
- package/dist/workflow/validator.js.map +1 -1
- package/package.json +1 -1
- package/src/workflow/__tests__/edge-derivation.test.ts +448 -0
- package/src/workflow/__tests__/edge-validation.test.ts +417 -0
- package/src/workflow/__tests__/types.test.ts +187 -0
- package/src/workflow/edge-derivation.ts +259 -0
- package/src/workflow/edge-validation.ts +494 -0
- package/src/workflow/index.ts +42 -0
- package/src/workflow/template-renderer.ts +8 -4
- package/src/workflow/types.ts +73 -4
- package/src/workflow/validator.ts +13 -6
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge Derivation from Workflows
|
|
3
|
+
*
|
|
4
|
+
* Extracts span context from workflow event templates and derives
|
|
5
|
+
* expected edges (span transitions) for validation against spans.canvas.
|
|
6
|
+
*
|
|
7
|
+
* @see .principal-views/WORKFLOW-SPAN-INTEGRATION.md
|
|
8
|
+
*/
|
|
9
|
+
import type { WorkflowTemplate, WorkflowScenario } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* A derived edge representing a span transition observed in a workflow
|
|
12
|
+
*/
|
|
13
|
+
export interface DerivedEdge {
|
|
14
|
+
/** Source span name (exact) */
|
|
15
|
+
fromSpan: string;
|
|
16
|
+
/** Target span name (exact) */
|
|
17
|
+
toSpan: string;
|
|
18
|
+
/** Workflow file where this edge was observed */
|
|
19
|
+
workflowFile?: string;
|
|
20
|
+
/** Scenario ID where this edge was observed */
|
|
21
|
+
scenarioId: string;
|
|
22
|
+
/** Event names that caused this transition */
|
|
23
|
+
eventNames: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Result of edge derivation from a single workflow
|
|
27
|
+
*/
|
|
28
|
+
export interface WorkflowEdgeDerivationResult {
|
|
29
|
+
/** Workflow name */
|
|
30
|
+
workflowName: string;
|
|
31
|
+
/** Root span for this workflow */
|
|
32
|
+
rootSpan: string | undefined;
|
|
33
|
+
/** All spans referenced in this workflow */
|
|
34
|
+
referencedSpans: string[];
|
|
35
|
+
/** Derived edges per scenario */
|
|
36
|
+
scenarioEdges: Array<{
|
|
37
|
+
scenarioId: string;
|
|
38
|
+
edges: DerivedEdge[];
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Result of edge derivation across all workflows
|
|
43
|
+
*/
|
|
44
|
+
export interface EdgeDerivationResult {
|
|
45
|
+
/** All derived edges (deduplicated) */
|
|
46
|
+
edges: DerivedEdge[];
|
|
47
|
+
/** Per-workflow breakdown */
|
|
48
|
+
workflows: WorkflowEdgeDerivationResult[];
|
|
49
|
+
/** All unique spans referenced across workflows */
|
|
50
|
+
allSpans: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract span context from a workflow's event templates
|
|
54
|
+
*
|
|
55
|
+
* @param scenario - Workflow scenario to analyze
|
|
56
|
+
* @param rootSpan - Default span for events without explicit span
|
|
57
|
+
* @returns Array of { eventName, span } entries in template order
|
|
58
|
+
*/
|
|
59
|
+
export declare function extractEventSpans(scenario: WorkflowScenario, rootSpan: string | undefined): Array<{
|
|
60
|
+
eventName: string;
|
|
61
|
+
span: string;
|
|
62
|
+
}>;
|
|
63
|
+
/**
|
|
64
|
+
* Derive edges from span transitions in event sequence
|
|
65
|
+
*
|
|
66
|
+
* Identifies when consecutive events are in different spans,
|
|
67
|
+
* which represents a potential edge (call relationship).
|
|
68
|
+
*
|
|
69
|
+
* Note: This captures temporal order, not parent-child nesting.
|
|
70
|
+
* We observe "span A was active, then span B was active" but
|
|
71
|
+
* cannot infer nesting without actual trace data.
|
|
72
|
+
*
|
|
73
|
+
* @param eventSpans - Event-span mappings in order
|
|
74
|
+
* @param scenarioId - ID of the scenario being analyzed
|
|
75
|
+
* @returns Array of derived edges
|
|
76
|
+
*/
|
|
77
|
+
export declare function deriveEdgesFromSequence(eventSpans: Array<{
|
|
78
|
+
eventName: string;
|
|
79
|
+
span: string;
|
|
80
|
+
}>, scenarioId: string): DerivedEdge[];
|
|
81
|
+
/**
|
|
82
|
+
* Derive all edges from a workflow template
|
|
83
|
+
*
|
|
84
|
+
* @param workflow - Workflow template to analyze
|
|
85
|
+
* @param workflowFile - Optional file path for tracking
|
|
86
|
+
* @returns Edge derivation result for this workflow
|
|
87
|
+
*/
|
|
88
|
+
export declare function deriveWorkflowEdges(workflow: WorkflowTemplate, workflowFile?: string): WorkflowEdgeDerivationResult;
|
|
89
|
+
/**
|
|
90
|
+
* Derive edges from multiple workflows
|
|
91
|
+
*
|
|
92
|
+
* @param workflows - Array of { workflow, filePath } pairs
|
|
93
|
+
* @returns Combined edge derivation result
|
|
94
|
+
*/
|
|
95
|
+
export declare function deriveEdgesFromWorkflows(workflows: Array<{
|
|
96
|
+
workflow: WorkflowTemplate;
|
|
97
|
+
filePath?: string;
|
|
98
|
+
}>): EdgeDerivationResult;
|
|
99
|
+
/**
|
|
100
|
+
* Group derived edges by source and target for display
|
|
101
|
+
*
|
|
102
|
+
* @param edges - Derived edges to group
|
|
103
|
+
* @returns Map of edge key to list of workflows/scenarios containing it
|
|
104
|
+
*/
|
|
105
|
+
export declare function groupEdgesBySources(edges: DerivedEdge[]): Map<string, Array<{
|
|
106
|
+
workflowFile?: string;
|
|
107
|
+
scenarioId: string;
|
|
108
|
+
}>>;
|
|
109
|
+
//# sourceMappingURL=edge-derivation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-derivation.d.ts","sourceRoot":"","sources":["../../src/workflow/edge-derivation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGlE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IAEjB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IAEf,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IAEnB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,oBAAoB;IACpB,YAAY,EAAE,MAAM,CAAC;IAErB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAE7B,4CAA4C;IAC5C,eAAe,EAAE,MAAM,EAAE,CAAC;IAE1B,iCAAiC;IACjC,aAAa,EAAE,KAAK,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,WAAW,EAAE,CAAC;KACtB,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,uCAAuC;IACvC,KAAK,EAAE,WAAW,EAAE,CAAC;IAErB,6BAA6B;IAC7B,SAAS,EAAE,4BAA4B,EAAE,CAAC;IAE1C,mDAAmD;IACnD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAsB5C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,KAAK,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACtD,UAAU,EAAE,MAAM,GACjB,WAAW,EAAE,CAyBf;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,gBAAgB,EAC1B,YAAY,CAAC,EAAE,MAAM,GACpB,4BAA4B,CAuC9B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAClE,oBAAoB,CA+BtB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAAE,GACnB,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAcnE"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Edge Derivation from Workflows
|
|
4
|
+
*
|
|
5
|
+
* Extracts span context from workflow event templates and derives
|
|
6
|
+
* expected edges (span transitions) for validation against spans.canvas.
|
|
7
|
+
*
|
|
8
|
+
* @see .principal-views/WORKFLOW-SPAN-INTEGRATION.md
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.groupEdgesBySources = exports.deriveEdgesFromWorkflows = exports.deriveWorkflowEdges = exports.deriveEdgesFromSequence = exports.extractEventSpans = void 0;
|
|
12
|
+
const types_1 = require("./types");
|
|
13
|
+
/**
|
|
14
|
+
* Extract span context from a workflow's event templates
|
|
15
|
+
*
|
|
16
|
+
* @param scenario - Workflow scenario to analyze
|
|
17
|
+
* @param rootSpan - Default span for events without explicit span
|
|
18
|
+
* @returns Array of { eventName, span } entries in template order
|
|
19
|
+
*/
|
|
20
|
+
function extractEventSpans(scenario, rootSpan) {
|
|
21
|
+
const events = scenario.template.events;
|
|
22
|
+
if (!events) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const result = [];
|
|
26
|
+
for (const [eventName, eventTemplate] of Object.entries(events)) {
|
|
27
|
+
const explicitSpan = (0, types_1.isEventTemplate)(eventTemplate)
|
|
28
|
+
? (0, types_1.getEventSpan)(eventTemplate)
|
|
29
|
+
: undefined;
|
|
30
|
+
// Use explicit span if provided, otherwise fall back to rootSpan
|
|
31
|
+
const span = explicitSpan ?? rootSpan;
|
|
32
|
+
if (span) {
|
|
33
|
+
result.push({ eventName, span });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
exports.extractEventSpans = extractEventSpans;
|
|
39
|
+
/**
|
|
40
|
+
* Derive edges from span transitions in event sequence
|
|
41
|
+
*
|
|
42
|
+
* Identifies when consecutive events are in different spans,
|
|
43
|
+
* which represents a potential edge (call relationship).
|
|
44
|
+
*
|
|
45
|
+
* Note: This captures temporal order, not parent-child nesting.
|
|
46
|
+
* We observe "span A was active, then span B was active" but
|
|
47
|
+
* cannot infer nesting without actual trace data.
|
|
48
|
+
*
|
|
49
|
+
* @param eventSpans - Event-span mappings in order
|
|
50
|
+
* @param scenarioId - ID of the scenario being analyzed
|
|
51
|
+
* @returns Array of derived edges
|
|
52
|
+
*/
|
|
53
|
+
function deriveEdgesFromSequence(eventSpans, scenarioId) {
|
|
54
|
+
const edges = [];
|
|
55
|
+
const seenEdges = new Set();
|
|
56
|
+
for (let i = 0; i < eventSpans.length - 1; i++) {
|
|
57
|
+
const current = eventSpans[i];
|
|
58
|
+
const next = eventSpans[i + 1];
|
|
59
|
+
// Transition occurs when spans differ
|
|
60
|
+
if (current.span !== next.span) {
|
|
61
|
+
const edgeKey = `${current.span}->${next.span}`;
|
|
62
|
+
if (!seenEdges.has(edgeKey)) {
|
|
63
|
+
seenEdges.add(edgeKey);
|
|
64
|
+
edges.push({
|
|
65
|
+
fromSpan: current.span,
|
|
66
|
+
toSpan: next.span,
|
|
67
|
+
scenarioId,
|
|
68
|
+
eventNames: [current.eventName, next.eventName],
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return edges;
|
|
74
|
+
}
|
|
75
|
+
exports.deriveEdgesFromSequence = deriveEdgesFromSequence;
|
|
76
|
+
/**
|
|
77
|
+
* Derive all edges from a workflow template
|
|
78
|
+
*
|
|
79
|
+
* @param workflow - Workflow template to analyze
|
|
80
|
+
* @param workflowFile - Optional file path for tracking
|
|
81
|
+
* @returns Edge derivation result for this workflow
|
|
82
|
+
*/
|
|
83
|
+
function deriveWorkflowEdges(workflow, workflowFile) {
|
|
84
|
+
const rootSpan = (0, types_1.getWorkflowRootSpan)(workflow);
|
|
85
|
+
const allSpans = new Set();
|
|
86
|
+
const scenarioEdges = [];
|
|
87
|
+
if (rootSpan) {
|
|
88
|
+
allSpans.add(rootSpan);
|
|
89
|
+
}
|
|
90
|
+
for (const scenario of workflow.scenarios) {
|
|
91
|
+
const eventSpans = extractEventSpans(scenario, rootSpan);
|
|
92
|
+
// Collect all referenced spans
|
|
93
|
+
for (const { span } of eventSpans) {
|
|
94
|
+
allSpans.add(span);
|
|
95
|
+
}
|
|
96
|
+
// Derive edges from transitions
|
|
97
|
+
const edges = deriveEdgesFromSequence(eventSpans, scenario.id);
|
|
98
|
+
// Attach workflow file to each edge
|
|
99
|
+
if (workflowFile) {
|
|
100
|
+
for (const edge of edges) {
|
|
101
|
+
edge.workflowFile = workflowFile;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
scenarioEdges.push({
|
|
105
|
+
scenarioId: scenario.id,
|
|
106
|
+
edges,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
workflowName: workflow.name,
|
|
111
|
+
rootSpan,
|
|
112
|
+
referencedSpans: Array.from(allSpans),
|
|
113
|
+
scenarioEdges,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
exports.deriveWorkflowEdges = deriveWorkflowEdges;
|
|
117
|
+
/**
|
|
118
|
+
* Derive edges from multiple workflows
|
|
119
|
+
*
|
|
120
|
+
* @param workflows - Array of { workflow, filePath } pairs
|
|
121
|
+
* @returns Combined edge derivation result
|
|
122
|
+
*/
|
|
123
|
+
function deriveEdgesFromWorkflows(workflows) {
|
|
124
|
+
const allSpans = new Set();
|
|
125
|
+
const workflowResults = [];
|
|
126
|
+
const edgeMap = new Map();
|
|
127
|
+
for (const { workflow, filePath } of workflows) {
|
|
128
|
+
const result = deriveWorkflowEdges(workflow, filePath);
|
|
129
|
+
workflowResults.push(result);
|
|
130
|
+
// Collect spans
|
|
131
|
+
for (const span of result.referencedSpans) {
|
|
132
|
+
allSpans.add(span);
|
|
133
|
+
}
|
|
134
|
+
// Collect and deduplicate edges
|
|
135
|
+
for (const scenarioResult of result.scenarioEdges) {
|
|
136
|
+
for (const edge of scenarioResult.edges) {
|
|
137
|
+
const key = `${edge.fromSpan}->${edge.toSpan}`;
|
|
138
|
+
if (!edgeMap.has(key)) {
|
|
139
|
+
edgeMap.set(key, edge);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
edges: Array.from(edgeMap.values()),
|
|
146
|
+
workflows: workflowResults,
|
|
147
|
+
allSpans: Array.from(allSpans),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
exports.deriveEdgesFromWorkflows = deriveEdgesFromWorkflows;
|
|
151
|
+
/**
|
|
152
|
+
* Group derived edges by source and target for display
|
|
153
|
+
*
|
|
154
|
+
* @param edges - Derived edges to group
|
|
155
|
+
* @returns Map of edge key to list of workflows/scenarios containing it
|
|
156
|
+
*/
|
|
157
|
+
function groupEdgesBySources(edges) {
|
|
158
|
+
const grouped = new Map();
|
|
159
|
+
for (const edge of edges) {
|
|
160
|
+
const key = `${edge.fromSpan}->${edge.toSpan}`;
|
|
161
|
+
const sources = grouped.get(key) || [];
|
|
162
|
+
sources.push({
|
|
163
|
+
workflowFile: edge.workflowFile,
|
|
164
|
+
scenarioId: edge.scenarioId,
|
|
165
|
+
});
|
|
166
|
+
grouped.set(key, sources);
|
|
167
|
+
}
|
|
168
|
+
return grouped;
|
|
169
|
+
}
|
|
170
|
+
exports.groupEdgesBySources = groupEdgesBySources;
|
|
171
|
+
//# sourceMappingURL=edge-derivation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-derivation.js","sourceRoot":"","sources":["../../src/workflow/edge-derivation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge Validation
|
|
3
|
+
*
|
|
4
|
+
* Validates derived edges from workflows against spans.canvas definitions.
|
|
5
|
+
* Ensures documented span relationships match observed workflow behavior.
|
|
6
|
+
*
|
|
7
|
+
* @see .principal-views/WORKFLOW-SPAN-INTEGRATION.md
|
|
8
|
+
*/
|
|
9
|
+
import type { ExtendedCanvas } from '../types/canvas';
|
|
10
|
+
import type { DerivedEdge } from './edge-derivation';
|
|
11
|
+
/**
|
|
12
|
+
* Span node info extracted from spans.canvas
|
|
13
|
+
*/
|
|
14
|
+
export interface SpanNodeInfo {
|
|
15
|
+
/** Node ID in the canvas */
|
|
16
|
+
nodeId: string;
|
|
17
|
+
/** Span pattern this node matches (e.g., "validate.*") */
|
|
18
|
+
spanPattern: string;
|
|
19
|
+
/** Human-readable name */
|
|
20
|
+
name?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Canvas edge info extracted from spans.canvas
|
|
24
|
+
*/
|
|
25
|
+
export interface CanvasEdgeInfo {
|
|
26
|
+
/** Source node ID */
|
|
27
|
+
fromNodeId: string;
|
|
28
|
+
/** Target node ID */
|
|
29
|
+
toNodeId: string;
|
|
30
|
+
/** Source span pattern */
|
|
31
|
+
fromSpanPattern?: string;
|
|
32
|
+
/** Target span pattern */
|
|
33
|
+
toSpanPattern?: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Edge validation result
|
|
37
|
+
*/
|
|
38
|
+
export interface EdgeValidationResult {
|
|
39
|
+
/** Edges that are documented in spans.canvas and observed in workflows */
|
|
40
|
+
validEdges: ValidatedEdge[];
|
|
41
|
+
/** Edges observed in workflows but missing from spans.canvas */
|
|
42
|
+
missingEdges: MissingEdge[];
|
|
43
|
+
/** Edges documented in spans.canvas but not observed in any workflow */
|
|
44
|
+
unusedEdges: UnusedEdge[];
|
|
45
|
+
/** Spans referenced in workflows that don't match any spans.canvas node */
|
|
46
|
+
unmatchedSpans: UnmatchedSpan[];
|
|
47
|
+
/** Summary statistics */
|
|
48
|
+
summary: {
|
|
49
|
+
totalDerivedEdges: number;
|
|
50
|
+
totalCanvasEdges: number;
|
|
51
|
+
matchedEdges: number;
|
|
52
|
+
missingEdges: number;
|
|
53
|
+
unusedEdges: number;
|
|
54
|
+
unmatchedSpans: number;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* An edge that passed validation
|
|
59
|
+
*/
|
|
60
|
+
export interface ValidatedEdge {
|
|
61
|
+
/** Source span name (exact) */
|
|
62
|
+
fromSpan: string;
|
|
63
|
+
/** Target span name (exact) */
|
|
64
|
+
toSpan: string;
|
|
65
|
+
/** Canvas edge it matched */
|
|
66
|
+
canvasEdge: CanvasEdgeInfo;
|
|
67
|
+
/** Workflows where this edge was observed */
|
|
68
|
+
sources: Array<{
|
|
69
|
+
workflowFile?: string;
|
|
70
|
+
scenarioId: string;
|
|
71
|
+
}>;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* An edge observed in workflows but missing from spans.canvas
|
|
75
|
+
*/
|
|
76
|
+
export interface MissingEdge {
|
|
77
|
+
/** Source span name */
|
|
78
|
+
fromSpan: string;
|
|
79
|
+
/** Target span name */
|
|
80
|
+
toSpan: string;
|
|
81
|
+
/** Source span matched to this node (if any) */
|
|
82
|
+
fromNodeId?: string;
|
|
83
|
+
/** Target span matched to this node (if any) */
|
|
84
|
+
toNodeId?: string;
|
|
85
|
+
/** Workflows where this edge was observed */
|
|
86
|
+
sources: Array<{
|
|
87
|
+
workflowFile?: string;
|
|
88
|
+
scenarioId: string;
|
|
89
|
+
}>;
|
|
90
|
+
/** Reason this edge is missing */
|
|
91
|
+
reason: 'no-edge-in-canvas' | 'span-not-matched';
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* An edge documented in spans.canvas but not observed in workflows
|
|
95
|
+
*/
|
|
96
|
+
export interface UnusedEdge {
|
|
97
|
+
/** Canvas edge */
|
|
98
|
+
canvasEdge: CanvasEdgeInfo;
|
|
99
|
+
/** Canvas file where this edge is defined */
|
|
100
|
+
canvasFile?: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* A span referenced in workflows that doesn't match any spans.canvas node
|
|
104
|
+
*/
|
|
105
|
+
export interface UnmatchedSpan {
|
|
106
|
+
/** Exact span name from workflow */
|
|
107
|
+
spanName: string;
|
|
108
|
+
/** Workflows that reference this span */
|
|
109
|
+
sources: Array<{
|
|
110
|
+
workflowFile?: string;
|
|
111
|
+
scenarioId: string;
|
|
112
|
+
}>;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Extract span nodes from a spans.canvas file
|
|
116
|
+
*
|
|
117
|
+
* @param canvas - Parsed spans.canvas content
|
|
118
|
+
* @returns Array of span node info
|
|
119
|
+
*/
|
|
120
|
+
export declare function extractSpanNodes(canvas: ExtendedCanvas): SpanNodeInfo[];
|
|
121
|
+
/**
|
|
122
|
+
* Extract edges from a spans.canvas file
|
|
123
|
+
*
|
|
124
|
+
* @param canvas - Parsed spans.canvas content
|
|
125
|
+
* @param spanNodes - Map of nodeId to span info
|
|
126
|
+
* @returns Array of canvas edge info
|
|
127
|
+
*/
|
|
128
|
+
export declare function extractCanvasEdges(canvas: ExtendedCanvas, spanNodes: SpanNodeInfo[]): CanvasEdgeInfo[];
|
|
129
|
+
/**
|
|
130
|
+
* Match an exact span name to a span pattern
|
|
131
|
+
*
|
|
132
|
+
* @param spanName - Exact span name (e.g., "validate.canvas")
|
|
133
|
+
* @param pattern - Span pattern (e.g., "validate.*")
|
|
134
|
+
* @returns true if the span matches the pattern
|
|
135
|
+
*/
|
|
136
|
+
export declare function matchSpanToPattern(spanName: string, pattern: string): boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Find the canvas node that matches a span name
|
|
139
|
+
*
|
|
140
|
+
* @param spanName - Exact span name
|
|
141
|
+
* @param spanNodes - Available span nodes
|
|
142
|
+
* @returns Matching node info or undefined
|
|
143
|
+
*/
|
|
144
|
+
export declare function findMatchingNode(spanName: string, spanNodes: SpanNodeInfo[]): SpanNodeInfo | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Check if a derived edge has a corresponding canvas edge
|
|
147
|
+
*
|
|
148
|
+
* @param derivedEdge - Edge derived from workflow
|
|
149
|
+
* @param canvasEdges - Edges from spans.canvas
|
|
150
|
+
* @param spanNodes - Span nodes from spans.canvas
|
|
151
|
+
* @returns Matching canvas edge or undefined
|
|
152
|
+
*/
|
|
153
|
+
export declare function findMatchingCanvasEdge(derivedEdge: DerivedEdge, canvasEdges: CanvasEdgeInfo[], spanNodes: SpanNodeInfo[]): CanvasEdgeInfo | undefined;
|
|
154
|
+
/**
|
|
155
|
+
* Validate derived edges against spans.canvas
|
|
156
|
+
*
|
|
157
|
+
* @param derivedEdges - Edges derived from workflows
|
|
158
|
+
* @param canvas - Parsed spans.canvas content
|
|
159
|
+
* @param canvasFile - Optional file path for tracking
|
|
160
|
+
* @returns Validation result
|
|
161
|
+
*/
|
|
162
|
+
export declare function validateEdges(derivedEdges: DerivedEdge[], canvas: ExtendedCanvas, canvasFile?: string): EdgeValidationResult;
|
|
163
|
+
/**
|
|
164
|
+
* Format validation result as human-readable text
|
|
165
|
+
*
|
|
166
|
+
* @param result - Validation result
|
|
167
|
+
* @returns Formatted string
|
|
168
|
+
*/
|
|
169
|
+
export declare function formatValidationResult(result: EdgeValidationResult): string;
|
|
170
|
+
//# sourceMappingURL=edge-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-validation.d.ts","sourceRoot":"","sources":["../../src/workflow/edge-validation.ts"],"names":[],"mappings":"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"}
|