@you-agent-factory/factory-graph 0.0.0

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/LICENSE.md ADDED
@@ -0,0 +1,3 @@
1
+ MIT License
2
+
3
+ Copyright (c) you-agent-factory contributors
package/README.md ADDED
@@ -0,0 +1,22 @@
1
+ # `@you-agent-factory/factory-graph`
2
+
3
+ The canonical, lossless input boundary for Factory graph renderers. A graph
4
+ source always contains the complete Factory definition, selected-tick runtime
5
+ projection, and optional saved visualization layout. Hosts retain event
6
+ streaming, persistence, and editor-session ownership.
7
+
8
+ The package also owns the reusable semantic node presentations (documents,
9
+ workers, work types, resources, work states, constraints, icons, handles, and
10
+ node chrome). Hosts supply selection callbacks and keep routing decisions
11
+ outside the package.
12
+
13
+ ```ts
14
+ import { createFactoryGraphSource } from "@you-agent-factory/factory-graph";
15
+
16
+ const source = createFactoryGraphSource({
17
+ factory,
18
+ runtime: { topology, activity, load },
19
+ selectedTick,
20
+ layout,
21
+ });
22
+ ```
@@ -0,0 +1,21 @@
1
+ import { type Edge } from "@xyflow/react";
2
+ import type { FactoryGraphSource } from "./source.js";
3
+ import { type FactoryGraphNode } from "./semantic-nodes.js";
4
+ export interface FactoryGraphReplaySurfaceProps {
5
+ className?: string;
6
+ onSelectNode?: (nodeId: string) => void;
7
+ selectedNodeId?: string;
8
+ source: FactoryGraphSource;
9
+ }
10
+ /**
11
+ * Read-only canonical Factory graph for replay and emulator hosts.
12
+ * It consumes the complete Factory and its selected-tick runtime projection,
13
+ * retaining the authored Factory layout rather than re-inventing topology.
14
+ */
15
+ export declare function FactoryGraphReplaySurface({ className, onSelectNode, selectedNodeId, source, }: FactoryGraphReplaySurfaceProps): import("react").JSX.Element;
16
+ export interface FactoryGraphReplayFlow {
17
+ edges: Edge[];
18
+ nodes: FactoryGraphNode[];
19
+ }
20
+ /** Project replay data into the original Factory semantic node family. */
21
+ export declare function projectFactoryGraphReplayFlow(source: FactoryGraphSource, selectedNodeId?: string): FactoryGraphReplayFlow;
@@ -0,0 +1,189 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Background, Controls, ReactFlow, } from "@xyflow/react";
3
+ import { GraphViewportSurface } from "@you-agent-factory/components/graphs";
4
+ import { FACTORY_GRAPH_NODE_TYPES, } from "./semantic-nodes.js";
5
+ /**
6
+ * Read-only canonical Factory graph for replay and emulator hosts.
7
+ * It consumes the complete Factory and its selected-tick runtime projection,
8
+ * retaining the authored Factory layout rather than re-inventing topology.
9
+ */
10
+ export function FactoryGraphReplaySurface({ className, onSelectNode, selectedNodeId, source, }) {
11
+ const flow = projectFactoryGraphReplayFlow(source, selectedNodeId);
12
+ return (_jsx(GraphViewportSurface, { className: className, "data-factory-graph-replay": true, children: _jsxs(ReactFlow, { defaultViewport: source.factory.layout?.viewport, edges: flow.edges, edgesFocusable: false, fitView: true, fitViewOptions: { padding: 0.12 }, nodes: flow.nodes, nodesConnectable: false, nodesDraggable: false, nodeTypes: FACTORY_GRAPH_NODE_TYPES, onNodeClick: (_event, node) => onSelectNode?.(node.id), proOptions: { hideAttribution: true }, children: [_jsx(Background, {}), _jsx(Controls, { showInteractive: false })] }) }));
13
+ }
14
+ /** Project replay data into the original Factory semantic node family. */
15
+ export function projectFactoryGraphReplayFlow(source, selectedNodeId) {
16
+ const positions = new Map((source.factory.layout?.nodes ?? []).map((node) => [
17
+ node.id,
18
+ node.position,
19
+ ]));
20
+ const activeIds = replayActiveNodeIds(source);
21
+ const topologyNodes = source.runtime.topology.nodes.map((topologyNode, index) => semanticNode(topologyNode, {
22
+ active: activeIds.has(topologyNode.id),
23
+ position: positions.get(topologyNode.id) ?? fallbackPosition(index),
24
+ selected: topologyNode.id === selectedNodeId,
25
+ source,
26
+ }));
27
+ const docs = (source.factory.supportingFiles?.bundledFiles ?? []).flatMap((file, index) => {
28
+ const id = `doc:${file.id?.trim() || file.targetPath}`;
29
+ if (topologyNodes.some((node) => node.id === id))
30
+ return [];
31
+ return [
32
+ {
33
+ data: {
34
+ displayLabel: file.targetPath.split("/").at(-1) ?? file.targetPath,
35
+ factoryGraphNodeId: id,
36
+ fileType: file.type,
37
+ handles: [],
38
+ kind: "doc",
39
+ selectedDoc: id === selectedNodeId,
40
+ targetPath: file.targetPath,
41
+ },
42
+ id,
43
+ position: positions.get(id) ?? fallbackPosition(topologyNodes.length + index),
44
+ type: "doc",
45
+ },
46
+ ];
47
+ });
48
+ return {
49
+ edges: source.runtime.topology.connections.map((connection) => ({
50
+ animated: source.runtime.activity.activeDispatchOverlays.some((overlay) => overlay.connectionIds.includes(connection.id)),
51
+ id: connection.id,
52
+ source: connection.source.nodeId,
53
+ sourceHandle: connection.source.handleId,
54
+ target: connection.target.nodeId,
55
+ targetHandle: connection.target.handleId,
56
+ })),
57
+ nodes: [...topologyNodes, ...docs],
58
+ };
59
+ }
60
+ function semanticNode(node, input) {
61
+ const handles = node.handles.map(toSemanticHandle);
62
+ const base = { position: input.position };
63
+ switch (node.kind) {
64
+ case "worker":
65
+ return {
66
+ ...base,
67
+ data: {
68
+ activeFlow: input.active,
69
+ factoryGraphNodeId: node.id,
70
+ handles,
71
+ kind: "worker",
72
+ muted: false,
73
+ place: { place_id: node.id, state_value: node.label },
74
+ selectedWorker: input.selected,
75
+ },
76
+ id: node.id,
77
+ type: "worker",
78
+ };
79
+ case "work-type":
80
+ return {
81
+ ...base,
82
+ data: {
83
+ activeFlow: input.active,
84
+ factoryGraphNodeId: node.id,
85
+ handles,
86
+ kind: "work-type",
87
+ muted: false,
88
+ place: { place_id: node.id, state_value: node.label },
89
+ selectedWorkType: input.selected,
90
+ },
91
+ id: node.id,
92
+ type: "workType",
93
+ };
94
+ case "resource":
95
+ return {
96
+ ...base,
97
+ data: {
98
+ activeFlow: input.active,
99
+ factoryGraphNodeId: node.id,
100
+ handles,
101
+ kind: "resource",
102
+ muted: false,
103
+ place: { kind: "resource", place_id: node.id, type_id: node.label },
104
+ selectedResource: input.selected,
105
+ tokenCount: resourceCount(node.id, input.source),
106
+ },
107
+ id: node.id,
108
+ type: "resource",
109
+ };
110
+ case "work-state":
111
+ return {
112
+ ...base,
113
+ data: {
114
+ activeFlow: input.active,
115
+ activeItemLabels: [],
116
+ factoryGraphNodeId: node.id,
117
+ handles,
118
+ muted: false,
119
+ place: {
120
+ kind: "work_state",
121
+ place_id: node.id,
122
+ state_category: node.category,
123
+ state_value: node.label,
124
+ },
125
+ selectedStateNode: input.selected,
126
+ tokenCount: workStateCount(node.id, input.source),
127
+ },
128
+ id: node.id,
129
+ type: "statePosition",
130
+ };
131
+ case "workstation":
132
+ return {
133
+ ...base,
134
+ data: {
135
+ active: input.active,
136
+ activeFlow: input.active,
137
+ executions: [],
138
+ factoryGraphNodeId: node.id,
139
+ handles,
140
+ muted: false,
141
+ now: 0,
142
+ selectedWorkID: null,
143
+ selectedWorkstation: input.selected,
144
+ summaryOnly: true,
145
+ workstation: {
146
+ node_id: node.id,
147
+ transition_id: node.label,
148
+ workstation_name: node.label,
149
+ },
150
+ },
151
+ id: node.id,
152
+ type: "workstation",
153
+ };
154
+ }
155
+ }
156
+ function toSemanticHandle(handle) {
157
+ return {
158
+ connectable: false,
159
+ id: handle.id,
160
+ label: handle.id,
161
+ side: handle.role === "target" ? "left" : "right",
162
+ type: handle.role,
163
+ };
164
+ }
165
+ function replayActiveNodeIds(source) {
166
+ const ids = new Set();
167
+ for (const overlay of source.runtime.activity.activeDispatchOverlays) {
168
+ if (overlay.workstationNodeId)
169
+ ids.add(overlay.workstationNodeId);
170
+ if (overlay.workerNodeId)
171
+ ids.add(overlay.workerNodeId);
172
+ for (const id of overlay.resourceNodeIds ?? [])
173
+ ids.add(id);
174
+ }
175
+ return ids;
176
+ }
177
+ function resourceCount(nodeId, source) {
178
+ const occupancy = source.runtime.load.resourceOccupancy.find((entry) => entry.resourceNodeId === nodeId);
179
+ return occupancy?.evidence === "known"
180
+ ? (occupancy.occupiedQuantity ?? 0)
181
+ : 0;
182
+ }
183
+ function workStateCount(nodeId, source) {
184
+ const count = source.runtime.load.workStateCounts.find((entry) => entry.workStateNodeId === nodeId);
185
+ return count?.evidence === "known" ? (count.count ?? 0) : 0;
186
+ }
187
+ function fallbackPosition(index) {
188
+ return { x: (index % 4) * 280, y: Math.floor(index / 4) * 180 };
189
+ }
@@ -0,0 +1,12 @@
1
+ export { createFactoryGraphSource, type FactoryGraphObserveControls, type FactoryGraphRuntimeProjection, type FactoryGraphSource, isFactoryGraphSource, } from "./source.js";
2
+ export { GRAPH_SEMANTIC_ICON_KINDS, GraphSemanticIcon, graphSemanticIconLabel, type GraphSemanticIconKind, type GraphSemanticIconProps, } from "./semantic-icon.js";
3
+ export { factoryGraphNodeHoverClassName, factoryGraphNodeSurfaceClassName, factoryGraphNodeTitleClassName, type FactoryGraphNodeHoverState, type FactoryGraphNodeHoverSurface, type FactoryGraphNodeSurfaceTone, } from "./semantic-node-style.js";
4
+ export { FACTORY_GRAPH_WORK_STATE_TYPES, type FactoryGraphWorkStateType, workStatePhaseSemanticIconClassName, workStatePhaseSemanticIconKind, workStatePhaseSurfaceClassName, workStatePhaseSwatchClassName, WORK_STATE_PHASE_LEGEND_ORDER, } from "./work-state-presentation.js";
5
+ export { factoryGraphHandleToneFromId, FactoryGraphNodeShell, type FactoryGraphNodeHandle, type FactoryGraphNodeShellProps, type FactoryGraphPlaceNodeType, type FactoryGraphZAxisIncompleteHints, } from "./semantic-node-shell.js";
6
+ export { FactoryGraphDocNodeView, type FactoryGraphDocNode, type FactoryGraphDocNodeData, } from "./semantic-doc-node.js";
7
+ export { FactoryGraphNodeBadge, FactoryGraphResourceNodeView, FactoryGraphWorkerNodeView, FactoryGraphWorkTypeNodeView, type FactoryGraphPlaceRef, type FactoryGraphResourceNode, type FactoryGraphResourceNodeData, type FactoryGraphWorkerNode, type FactoryGraphWorkerNodeData, type FactoryGraphWorkTypeNode, type FactoryGraphWorkTypeNodeData, } from "./semantic-support-nodes.js";
8
+ export { FactoryGraphConstraintNodeView, FactoryGraphStatePositionNodeView, FactoryGraphWorkProgressMarker, type FactoryGraphBasePlaceNodeData, type FactoryGraphConstraintNode, type FactoryGraphConstraintNodeData, type FactoryGraphPlaceNode, type FactoryGraphSemanticPlaceRef, type FactoryGraphStatePositionNode, type FactoryGraphStatePositionNodeData, } from "./semantic-place-nodes.js";
9
+ export { FactoryGraphWorkstationNodeView, type FactoryGraphActiveExecution, type FactoryGraphWorkstationNode, type FactoryGraphWorkstationNodeData, } from "./semantic-workstation-node.js";
10
+ export type { FactoryGraphWorkItemRef, FactoryGraphWorkstationRef, } from "./semantic-workstation-presentation.js";
11
+ export { FACTORY_GRAPH_NODE_TYPES, type FactoryGraphNode, } from "./semantic-nodes.js";
12
+ export { FactoryGraphReplaySurface, projectFactoryGraphReplayFlow, type FactoryGraphReplayFlow, type FactoryGraphReplaySurfaceProps, } from "./factory-graph-replay-surface.js";
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ export { createFactoryGraphSource, isFactoryGraphSource, } from "./source.js";
2
+ export { GRAPH_SEMANTIC_ICON_KINDS, GraphSemanticIcon, graphSemanticIconLabel, } from "./semantic-icon.js";
3
+ export { factoryGraphNodeHoverClassName, factoryGraphNodeSurfaceClassName, factoryGraphNodeTitleClassName, } from "./semantic-node-style.js";
4
+ export { FACTORY_GRAPH_WORK_STATE_TYPES, workStatePhaseSemanticIconClassName, workStatePhaseSemanticIconKind, workStatePhaseSurfaceClassName, workStatePhaseSwatchClassName, WORK_STATE_PHASE_LEGEND_ORDER, } from "./work-state-presentation.js";
5
+ export { factoryGraphHandleToneFromId, FactoryGraphNodeShell, } from "./semantic-node-shell.js";
6
+ export { FactoryGraphDocNodeView, } from "./semantic-doc-node.js";
7
+ export { FactoryGraphNodeBadge, FactoryGraphResourceNodeView, FactoryGraphWorkerNodeView, FactoryGraphWorkTypeNodeView, } from "./semantic-support-nodes.js";
8
+ export { FactoryGraphConstraintNodeView, FactoryGraphStatePositionNodeView, FactoryGraphWorkProgressMarker, } from "./semantic-place-nodes.js";
9
+ export { FactoryGraphWorkstationNodeView, } from "./semantic-workstation-node.js";
10
+ export { FACTORY_GRAPH_NODE_TYPES, } from "./semantic-nodes.js";
11
+ export { FactoryGraphReplaySurface, projectFactoryGraphReplayFlow, } from "./factory-graph-replay-surface.js";
@@ -0,0 +1,16 @@
1
+ import type { Node, NodeProps } from "@xyflow/react";
2
+ import { type FactoryGraphNodeHandle } from "./semantic-node-shell.js";
3
+ export interface FactoryGraphDocNodeData extends Record<string, unknown> {
4
+ displayLabel: string;
5
+ factoryGraphNodeId?: string;
6
+ fileType?: string;
7
+ handles: FactoryGraphNodeHandle[];
8
+ kind: "doc";
9
+ locale?: string;
10
+ onSelectDoc?: (targetPath: string) => void;
11
+ selectedDoc: boolean;
12
+ targetPath: string;
13
+ }
14
+ export type FactoryGraphDocNode = Node<FactoryGraphDocNodeData, "doc">;
15
+ /** Original Factory document node, with host-owned selection callback. */
16
+ export declare function FactoryGraphDocNodeView({ data, }: NodeProps<FactoryGraphDocNode>): import("react").JSX.Element;
@@ -0,0 +1,29 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { GraphNodeButton } from "@you-agent-factory/components/graphs";
3
+ import { GraphSemanticIcon } from "./semantic-icon.js";
4
+ import { FactoryGraphNodeShell } from "./semantic-node-shell.js";
5
+ import { factoryGraphNodeHoverClassName, factoryGraphNodeSurfaceClassName, } from "./semantic-node-style.js";
6
+ /** Original Factory document node, with host-owned selection callback. */
7
+ export function FactoryGraphDocNodeView({ data, }) {
8
+ const selectable = data.onSelectDoc !== undefined;
9
+ const docLabel = "Document";
10
+ return (_jsx(FactoryGraphNodeShell, { className: [
11
+ factoryGraphNodeSurfaceClassName("neutral"),
12
+ "justify-center text-left text-on-surface",
13
+ factoryGraphNodeHoverClassName({ selected: data.selectedDoc }),
14
+ data.selectedDoc && "border-primary shadow-af-accent-selected",
15
+ ]
16
+ .filter(Boolean)
17
+ .join(" "), handles: data.handles, nodeType: "doc", children: selectable ? (_jsx(GraphNodeButton, { "aria-label": selectDocLabel(data.displayLabel, data.locale), "aria-pressed": data.selectedDoc, className: "grid min-w-0 gap-0.5 overflow-hidden", "data-selected-doc": data.selectedDoc ? "true" : undefined, onClick: (event) => {
18
+ event.stopPropagation();
19
+ data.onSelectDoc?.(data.targetPath);
20
+ }, children: _jsx(FactoryGraphDocNodeContent, { displayLabel: data.displayLabel, docLabel: docLabel, targetPath: data.targetPath }) })) : (_jsx(FactoryGraphDocNodeContent, { displayLabel: data.displayLabel, docLabel: docLabel, targetPath: data.targetPath })) }));
21
+ }
22
+ function FactoryGraphDocNodeContent({ displayLabel, docLabel, targetPath, }) {
23
+ return (_jsxs("div", { className: "grid min-w-0 gap-1 px-2 py-1", children: [_jsxs("div", { className: "flex min-w-0 items-center gap-1.5", children: [_jsx(GraphSemanticIcon, { className: "text-on-surface-variant", kind: "doc", label: docLabel }), _jsx("span", { className: "truncate text-sm font-medium text-on-surface", children: displayLabel })] }), _jsx("span", { className: "truncate text-xs text-on-surface-variant", children: targetPath })] }));
24
+ }
25
+ function selectDocLabel(displayLabel, locale) {
26
+ return locale === "zh-CN"
27
+ ? `选择 ${displayLabel} 文档`
28
+ : `Select ${displayLabel} doc`;
29
+ }
@@ -0,0 +1,10 @@
1
+ export declare const GRAPH_SEMANTIC_ICON_KINDS: readonly ["queue", "processing", "terminal", "failed", "resource", "worker", "work-type", "constraint", "doc", "limit", "workstation", "repeater", "cron", "poller", "exhaustion", "active-work"];
2
+ export type GraphSemanticIconKind = (typeof GRAPH_SEMANTIC_ICON_KINDS)[number];
3
+ export interface GraphSemanticIconProps {
4
+ className?: string;
5
+ kind: GraphSemanticIconKind | (string & {});
6
+ label?: string;
7
+ locale?: string;
8
+ }
9
+ export declare function graphSemanticIconLabel(kind: GraphSemanticIconProps["kind"]): string;
10
+ export declare function GraphSemanticIcon({ className, kind, label, }: GraphSemanticIconProps): import("react").JSX.Element;
@@ -0,0 +1,87 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ function cn(...classNames) {
3
+ return classNames.filter(Boolean).join(" ");
4
+ }
5
+ export const GRAPH_SEMANTIC_ICON_KINDS = [
6
+ "queue",
7
+ "processing",
8
+ "terminal",
9
+ "failed",
10
+ "resource",
11
+ "worker",
12
+ "work-type",
13
+ "constraint",
14
+ "doc",
15
+ "limit",
16
+ "workstation",
17
+ "repeater",
18
+ "cron",
19
+ "poller",
20
+ "exhaustion",
21
+ "active-work",
22
+ ];
23
+ const DEFAULT_ICON_CLASS_NAME = "h-4 w-4 shrink-0 text-on-surface-variant";
24
+ const GRAPH_SEMANTIC_ICON_DEFINITIONS = {
25
+ "active-work": {
26
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M8 5v14l11-7-11-7Z" }), _jsx("path", { d: "M4.5 8.5v7" })] })),
27
+ },
28
+ constraint: {
29
+ paths: (_jsxs(_Fragment, { children: [_jsx("rect", { height: "9", rx: "2", width: "14", x: "5", y: "10" }), _jsx("path", { d: "M8 10V8a4 4 0 0 1 8 0v2" }), _jsx("path", { d: "M12 13.5v2" })] })),
30
+ },
31
+ doc: {
32
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M8 4h7l5 5v11a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1Z" }), _jsx("path", { d: "M15 4v5h5" }), _jsx("path", { d: "M9 12h6" }), _jsx("path", { d: "M9 16h4" })] })),
33
+ },
34
+ cron: {
35
+ paths: (_jsxs(_Fragment, { children: [_jsx("circle", { cx: "12", cy: "12", r: "8" }), _jsx("path", { d: "M12 7.5V12l3 2" })] })),
36
+ },
37
+ poller: {
38
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M6 6.5h8a4 4 0 1 1 0 8H9.5" }), _jsx("path", { d: "m7.5 4-3 2.5 3 2.5" }), _jsx("path", { d: "M18 17.5H10a4 4 0 1 1 0-8h4.5" }), _jsx("path", { d: "m16.5 20 3-2.5-3-2.5" })] })),
39
+ },
40
+ exhaustion: {
41
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M12 4 21 19H3L12 4Z" }), _jsx("path", { d: "M12 9v4" }), _jsx("path", { d: "M12 16.5h.01" })] })),
42
+ },
43
+ failed: {
44
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M8.5 3.5h7L20.5 8.5v7l-5 5h-7l-5-5v-7l5-5Z" }), _jsx("path", { d: "m9 9 6 6" }), _jsx("path", { d: "m15 9-6 6" })] })),
45
+ },
46
+ limit: {
47
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M5 17a7 7 0 0 1 14 0" }), _jsx("path", { d: "M12 17l4-6" }), _jsx("path", { d: "M8 19h8" })] })),
48
+ },
49
+ processing: {
50
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M18.5 9A7 7 0 0 0 6.2 6.2L4.5 8" }), _jsx("path", { d: "M4.5 4.5V8h3.5" }), _jsx("path", { d: "M5.5 15a7 7 0 0 0 12.3 2.8L19.5 16" }), _jsx("path", { d: "M19.5 19.5V16H16" })] })),
51
+ },
52
+ queue: {
53
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M5 7h11" }), _jsx("path", { d: "M5 12h14" }), _jsx("path", { d: "M5 17h8" }), _jsx("path", { d: "m16 15 3 2-3 2" })] })),
54
+ },
55
+ repeater: {
56
+ paths: (_jsxs(_Fragment, { children: [_jsx("path", { d: "M17 7h-6a5 5 0 0 0 0 10h1" }), _jsx("path", { d: "m15 4 3 3-3 3" }), _jsx("path", { d: "M7 17h6a5 5 0 0 0 0-10h-1" }), _jsx("path", { d: "m9 20-3-3 3-3" })] })),
57
+ },
58
+ resource: {
59
+ paths: (_jsxs(_Fragment, { children: [_jsx("ellipse", { cx: "12", cy: "6", rx: "6.5", ry: "3" }), _jsx("path", { d: "M5.5 6v6c0 1.7 2.9 3 6.5 3s6.5-1.3 6.5-3V6" }), _jsx("path", { d: "M5.5 12v6c0 1.7 2.9 3 6.5 3s6.5-1.3 6.5-3v-6" })] })),
60
+ },
61
+ worker: {
62
+ paths: (_jsxs(_Fragment, { children: [_jsx("circle", { cx: "12", cy: "7", r: "3.2" }), _jsx("path", { d: "M5.5 20a6.5 6.5 0 0 1 13 0" }), _jsx("path", { d: "M8.5 14.5 12 18l3.5-3.5" })] })),
63
+ },
64
+ "work-type": {
65
+ paths: (_jsxs(_Fragment, { children: [_jsx("rect", { height: "14", rx: "2.5", width: "12", x: "6", y: "5" }), _jsx("path", { d: "M9 9h6" }), _jsx("path", { d: "M9 12h6" }), _jsx("path", { d: "M9 15h4" })] })),
66
+ },
67
+ terminal: {
68
+ paths: (_jsxs(_Fragment, { children: [_jsx("circle", { cx: "12", cy: "12", r: "8" }), _jsx("path", { d: "m8.5 12 2.3 2.3 4.7-5" })] })),
69
+ },
70
+ workstation: {
71
+ paths: (_jsxs(_Fragment, { children: [_jsx("rect", { height: "10", rx: "2", width: "14", x: "5", y: "5" }), _jsx("path", { d: "M9 19h6" }), _jsx("path", { d: "M12 15v4" })] })),
72
+ },
73
+ };
74
+ function unknownIconPaths() {
75
+ return (_jsxs(_Fragment, { children: [_jsx("path", { d: "M12 3.5 20.5 8.2v7.6L12 20.5 3.5 15.8V8.2L12 3.5Z" }), _jsx("path", { d: "M9.5 9a2.6 2.6 0 1 1 3.2 2.5c-.5.2-.7.6-.7 1.2v.3" }), _jsx("path", { d: "M12 16.5h.01" })] }));
76
+ }
77
+ export function graphSemanticIconLabel(kind) {
78
+ return GRAPH_SEMANTIC_ICON_DEFINITIONS[kind] !==
79
+ undefined
80
+ ? String(kind)
81
+ : "Unknown graph semantic";
82
+ }
83
+ export function GraphSemanticIcon({ className, kind, label, }) {
84
+ const definition = GRAPH_SEMANTIC_ICON_DEFINITIONS[kind];
85
+ const accessibleLabel = label ?? graphSemanticIconLabel(kind);
86
+ return (_jsx("svg", { "aria-label": accessibleLabel, className: cn(DEFAULT_ICON_CLASS_NAME, className), "data-graph-semantic-icon": definition ? kind : "unknown", fill: "none", focusable: "false", role: "img", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: "1.8", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg", children: definition?.paths ?? unknownIconPaths() }));
87
+ }
@@ -0,0 +1,18 @@
1
+ import { type GraphNodeHandle } from "@you-agent-factory/components/graphs";
2
+ import type { ReactNode } from "react";
3
+ export type FactoryGraphPlaceNodeType = "constraint" | "doc" | "resource" | "statePosition" | "worker" | "workType";
4
+ export type FactoryGraphNodeHandle = GraphNodeHandle;
5
+ export interface FactoryGraphZAxisIncompleteHints {
6
+ accessibleLabel: string;
7
+ title: string;
8
+ }
9
+ export interface FactoryGraphNodeShellProps {
10
+ children: ReactNode;
11
+ className?: string;
12
+ handles: FactoryGraphNodeHandle[];
13
+ nodeType: "workstation" | FactoryGraphPlaceNodeType;
14
+ zAxisIncompleteHints?: FactoryGraphZAxisIncompleteHints | null;
15
+ }
16
+ /** Original semantic Factory node frame, including its typed connection rails. */
17
+ export declare function FactoryGraphNodeShell({ children, className, handles, nodeType, zAxisIncompleteHints, }: FactoryGraphNodeShellProps): import("react").JSX.Element;
18
+ export declare function factoryGraphHandleToneFromId(handleId: string): NonNullable<GraphNodeHandle["tone"]>;
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { GraphNodeShell, } from "@you-agent-factory/components/graphs";
3
+ const WORKSTATION_RIGHT_RAIL_ANCHOR_IDS = [
4
+ "workstation-output-source",
5
+ "workstation-on-continue-source",
6
+ "workstation-on-failure-source",
7
+ "workstation-on-rejection-source",
8
+ ];
9
+ const Z_AXIS_INCOMPLETE_HINT_ANCHOR_IDS = [
10
+ "workstation-on-continue-source",
11
+ "workstation-on-rejection-source",
12
+ ];
13
+ /** Original semantic Factory node frame, including its typed connection rails. */
14
+ export function FactoryGraphNodeShell({ children, className = "", handles, nodeType, zAxisIncompleteHints = null, }) {
15
+ const packageHandles = handles.map((handle) => ({
16
+ ...handle,
17
+ tone: handle.tone ?? factoryGraphHandleToneFromId(handle.id),
18
+ }));
19
+ const activeHints = nodeType === "workstation" ? zAxisIncompleteHints : null;
20
+ return (_jsxs("div", { className: "relative h-full min-w-0 w-full", children: [_jsx(GraphNodeShell, { className: className, "data-current-activity-node-type": nodeType, handles: packageHandles, nodeKind: nodeType, showStateIndicator: false, children: children }), activeHints
21
+ ? workstationZAxisIncompleteHintSlots().map((slot) => (_jsx(ZAxisIncompleteHintOrb, { accessibleLabel: activeHints.accessibleLabel, anchorId: slot.anchorId, title: activeHints.title, top: slot.top }, slot.anchorId)))
22
+ : null] }));
23
+ }
24
+ export function factoryGraphHandleToneFromId(handleId) {
25
+ if (handleId.includes("resource"))
26
+ return "resource";
27
+ if (handleId.includes("worker-assignment") ||
28
+ handleId.includes("worker-input"))
29
+ return "worker";
30
+ if (handleId.includes("on-continue"))
31
+ return "continue";
32
+ if (handleId.includes("on-failure"))
33
+ return "failure";
34
+ if (handleId.includes("on-rejection"))
35
+ return "rejection";
36
+ if (handleId.includes("output"))
37
+ return "output";
38
+ if (handleId.includes("input"))
39
+ return "input";
40
+ if (handleId.includes("assignment"))
41
+ return "assignment";
42
+ return "default";
43
+ }
44
+ function workstationZAxisIncompleteHintSlots() {
45
+ const railCount = WORKSTATION_RIGHT_RAIL_ANCHOR_IDS.length;
46
+ return Z_AXIS_INCOMPLETE_HINT_ANCHOR_IDS.map((anchorId) => {
47
+ const index = WORKSTATION_RIGHT_RAIL_ANCHOR_IDS.indexOf(anchorId);
48
+ return {
49
+ anchorId,
50
+ top: `${((index + 1) * 100) / (railCount + 1)}%`,
51
+ };
52
+ });
53
+ }
54
+ function ZAxisIncompleteHintOrb({ accessibleLabel, anchorId, title, top, }) {
55
+ return (_jsx("span", { "aria-label": accessibleLabel, className: "pointer-events-none absolute top-0 right-0 z-20 flex -translate-y-1/2 translate-x-1 flex-row-reverse", "data-z-axis-incomplete-hint": anchorId, role: "img", style: { top }, title: title, children: _jsx("span", { "aria-hidden": "true", className: "block h-2.5 w-2.5 rounded-full border border-af-danger-border bg-error shadow-[0_0_0_3px_var(--color-error-container)] motion-safe:animate-pulse" }) }));
56
+ }
@@ -0,0 +1,12 @@
1
+ export type FactoryGraphNodeSurfaceTone = "danger" | "info" | "neutral" | "neutralHigh" | "primary" | "resource" | "success" | "warning" | "workState" | "workstation";
2
+ export interface FactoryGraphNodeHoverState {
3
+ activeFlow?: boolean;
4
+ muted?: boolean;
5
+ selected?: boolean;
6
+ validationError?: boolean;
7
+ }
8
+ export type FactoryGraphNodeHoverSurface = "primary" | "warning";
9
+ export declare function factoryGraphNodeSurfaceClassName(tone: FactoryGraphNodeSurfaceTone): string;
10
+ export declare function factoryGraphNodeTitleClassName(className?: string): string;
11
+ /** Accent feedback used by the original Factory graph's semantic node views. */
12
+ export declare function factoryGraphNodeHoverClassName(state: FactoryGraphNodeHoverState, surface?: FactoryGraphNodeHoverSurface): string | undefined;
@@ -0,0 +1,29 @@
1
+ const SURFACE_TONE_CLASS_NAME = {
2
+ danger: "border-af-danger-border bg-error-container",
3
+ info: "border-info-border bg-info-container",
4
+ neutral: "border-outline bg-surface",
5
+ neutralHigh: "border-outline-variant bg-surface-container-high",
6
+ primary: "border-primary bg-primary-container",
7
+ resource: "border-outline bg-background",
8
+ success: "border-af-success-border bg-success-container",
9
+ warning: "border-af-warning-border bg-warning-container",
10
+ workState: "border-info-border bg-info-container",
11
+ workstation: "border-outline-variant bg-surface-container-highest",
12
+ };
13
+ const NODE_TITLE_CLASS_NAME = "block min-w-0 truncate whitespace-nowrap font-bold leading-tight text-on-surface";
14
+ const HOVER_CLASS_BY_SURFACE = {
15
+ primary: "transition-[background-color,border-color,box-shadow,opacity] hover:border-primary hover:bg-primary-container hover:opacity-100 hover:shadow-af-accent-chip",
16
+ warning: "transition-[background-color,border-color,box-shadow,opacity] hover:border-primary hover:bg-warning-container hover:opacity-100 hover:shadow-af-accent-chip",
17
+ };
18
+ export function factoryGraphNodeSurfaceClassName(tone) {
19
+ return SURFACE_TONE_CLASS_NAME[tone];
20
+ }
21
+ export function factoryGraphNodeTitleClassName(className) {
22
+ return [NODE_TITLE_CLASS_NAME, className].filter(Boolean).join(" ");
23
+ }
24
+ /** Accent feedback used by the original Factory graph's semantic node views. */
25
+ export function factoryGraphNodeHoverClassName(state, surface = "warning") {
26
+ if (state.selected || state.validationError)
27
+ return undefined;
28
+ return HOVER_CLASS_BY_SURFACE[surface];
29
+ }
@@ -0,0 +1,15 @@
1
+ import { FactoryGraphDocNodeView, type FactoryGraphDocNode } from "./semantic-doc-node.js";
2
+ import { FactoryGraphConstraintNodeView, FactoryGraphStatePositionNodeView, type FactoryGraphPlaceNode } from "./semantic-place-nodes.js";
3
+ import { FactoryGraphResourceNodeView, FactoryGraphWorkerNodeView, FactoryGraphWorkTypeNodeView, type FactoryGraphResourceNode, type FactoryGraphWorkerNode, type FactoryGraphWorkTypeNode } from "./semantic-support-nodes.js";
4
+ import { FactoryGraphWorkstationNodeView, type FactoryGraphWorkstationNode } from "./semantic-workstation-node.js";
5
+ /** The complete original Factory semantic renderer registry. */
6
+ export declare const FACTORY_GRAPH_NODE_TYPES: {
7
+ constraint: typeof FactoryGraphConstraintNodeView;
8
+ doc: typeof FactoryGraphDocNodeView;
9
+ resource: typeof FactoryGraphResourceNodeView;
10
+ statePosition: typeof FactoryGraphStatePositionNodeView;
11
+ worker: typeof FactoryGraphWorkerNodeView;
12
+ workType: typeof FactoryGraphWorkTypeNodeView;
13
+ workstation: typeof FactoryGraphWorkstationNodeView;
14
+ };
15
+ export type FactoryGraphNode = FactoryGraphWorkstationNode | FactoryGraphPlaceNode | FactoryGraphDocNode | FactoryGraphResourceNode | FactoryGraphWorkerNode | FactoryGraphWorkTypeNode;
@@ -0,0 +1,14 @@
1
+ import { FactoryGraphDocNodeView, } from "./semantic-doc-node.js";
2
+ import { FactoryGraphConstraintNodeView, FactoryGraphStatePositionNodeView, } from "./semantic-place-nodes.js";
3
+ import { FactoryGraphResourceNodeView, FactoryGraphWorkerNodeView, FactoryGraphWorkTypeNodeView, } from "./semantic-support-nodes.js";
4
+ import { FactoryGraphWorkstationNodeView, } from "./semantic-workstation-node.js";
5
+ /** The complete original Factory semantic renderer registry. */
6
+ export const FACTORY_GRAPH_NODE_TYPES = {
7
+ constraint: FactoryGraphConstraintNodeView,
8
+ doc: FactoryGraphDocNodeView,
9
+ resource: FactoryGraphResourceNodeView,
10
+ statePosition: FactoryGraphStatePositionNodeView,
11
+ worker: FactoryGraphWorkerNodeView,
12
+ workType: FactoryGraphWorkTypeNodeView,
13
+ workstation: FactoryGraphWorkstationNodeView,
14
+ };
@@ -0,0 +1,47 @@
1
+ import type { Node, NodeProps } from "@xyflow/react";
2
+ import type { ComponentPropsWithoutRef, ReactNode } from "react";
3
+ import { type FactoryGraphNodeHandle } from "./semantic-node-shell.js";
4
+ import { type FactoryGraphPlaceRef } from "./semantic-support-nodes.js";
5
+ import { type FactoryGraphWorkStateType } from "./work-state-presentation.js";
6
+ export interface FactoryGraphSemanticPlaceRef extends FactoryGraphPlaceRef {
7
+ kind: "constraint" | "limit" | "resource" | "work_state" | (string & {});
8
+ state_category?: FactoryGraphWorkStateType;
9
+ }
10
+ export interface FactoryGraphBasePlaceNodeData extends Record<string, unknown> {
11
+ activeFlow: boolean;
12
+ activeItemLabels: string[];
13
+ factoryGraphNodeId?: string;
14
+ handles: FactoryGraphNodeHandle[];
15
+ kind?: string;
16
+ locale?: string;
17
+ muted: boolean;
18
+ onSelectStateNode?: (placeId: string) => void;
19
+ place: FactoryGraphSemanticPlaceRef;
20
+ selectedStateNode: boolean;
21
+ tokenCount: number;
22
+ validationError?: boolean;
23
+ validationMessage?: string;
24
+ }
25
+ export interface FactoryGraphStatePositionNodeData extends FactoryGraphBasePlaceNodeData {
26
+ }
27
+ export interface FactoryGraphConstraintNodeData extends FactoryGraphBasePlaceNodeData {
28
+ }
29
+ export type FactoryGraphStatePositionNode = Node<FactoryGraphStatePositionNodeData, "statePosition">;
30
+ export type FactoryGraphConstraintNode = Node<FactoryGraphConstraintNodeData, "constraint">;
31
+ export type FactoryGraphPlaceNode = FactoryGraphConstraintNode | FactoryGraphStatePositionNode;
32
+ export declare function FactoryGraphStatePositionNodeView(props: NodeProps<FactoryGraphStatePositionNode>): import("react").JSX.Element;
33
+ export declare function FactoryGraphConstraintNodeView(props: NodeProps<FactoryGraphConstraintNode>): import("react").JSX.Element;
34
+ export declare function FactoryGraphWorkProgressMarker(props: ({
35
+ ariaLabel: string;
36
+ className?: string;
37
+ count: number;
38
+ kind: "numeric";
39
+ } & ComponentPropsWithoutRef<"span">) | ({
40
+ ariaLabel: string;
41
+ className?: string;
42
+ dotClassName?: string;
43
+ dotCount: number;
44
+ dotDataAttribute: string;
45
+ kind: "dots";
46
+ suffix?: ReactNode;
47
+ } & ComponentPropsWithoutRef<"span">)): import("react").JSX.Element;