@hexabot-ai/types 3.0.2-alpha.9 → 3.0.2-beta.1
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/README.md +28 -1
- package/dist/cjs/user/index.js +5 -1
- package/dist/cjs/user/mcp-token.js +31 -0
- package/dist/cjs/workflow/index.js +17 -1
- package/dist/cjs/workflow/workflow-run.js +6 -0
- package/dist/cjs/workflow/workflow-transfer.js +124 -0
- package/dist/esm/user/index.js +1 -0
- package/dist/esm/user/mcp-token.js +28 -0
- package/dist/esm/workflow/index.js +1 -0
- package/dist/esm/workflow/workflow-run.js +6 -0
- package/dist/esm/workflow/workflow-transfer.js +121 -0
- package/dist/types/user/index.d.ts +1 -0
- package/dist/types/user/index.d.ts.map +1 -1
- package/dist/types/user/mcp-token.d.ts +113 -0
- package/dist/types/user/mcp-token.d.ts.map +1 -0
- package/dist/types/workflow/index.d.ts +1 -0
- package/dist/types/workflow/index.d.ts.map +1 -1
- package/dist/types/workflow/memory-record.d.ts +2 -0
- package/dist/types/workflow/memory-record.d.ts.map +1 -1
- package/dist/types/workflow/workflow-run.d.ts +60 -0
- package/dist/types/workflow/workflow-run.d.ts.map +1 -1
- package/dist/types/workflow/workflow-transfer.d.ts +329 -0
- package/dist/types/workflow/workflow-transfer.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/index.test.ts +331 -0
- package/src/user/index.ts +9 -0
- package/src/user/mcp-token.ts +53 -0
- package/src/workflow/index.ts +30 -0
- package/src/workflow/workflow-run.ts +9 -0
- package/src/workflow/workflow-transfer.ts +190 -0
package/src/index.test.ts
CHANGED
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
IncomingMessageType,
|
|
32
32
|
labelFullSchema,
|
|
33
33
|
labelSchema,
|
|
34
|
+
mcpTokenSchema,
|
|
34
35
|
mcpServerFullSchema,
|
|
35
36
|
mcpServerSchema,
|
|
36
37
|
memoryRecordFullSchema,
|
|
@@ -56,6 +57,9 @@ import {
|
|
|
56
57
|
userFullSchema,
|
|
57
58
|
userSchema,
|
|
58
59
|
workflowFullSchema,
|
|
60
|
+
workflowExportBundleSchema,
|
|
61
|
+
workflowExportBundleV1Schema,
|
|
62
|
+
workflowImportResultSchema,
|
|
59
63
|
workflowRunFullSchema,
|
|
60
64
|
workflowRunSchema,
|
|
61
65
|
workflowVersionFullSchema,
|
|
@@ -682,6 +686,25 @@ describe("@hexabot-ai/types schemas", () => {
|
|
|
682
686
|
expect("value" in credential).toBe(false);
|
|
683
687
|
});
|
|
684
688
|
|
|
689
|
+
it("keeps MCP token outputs free of token hashes", () => {
|
|
690
|
+
const token = mcpTokenSchema.parse({
|
|
691
|
+
id: "mt_1",
|
|
692
|
+
createdAt: now,
|
|
693
|
+
updatedAt: now,
|
|
694
|
+
name: "Codex",
|
|
695
|
+
tokenPrefix: "hbt_mcp_abcd",
|
|
696
|
+
tokenHash: "secret-hash",
|
|
697
|
+
ownerId: "u_1",
|
|
698
|
+
expiresAt: null,
|
|
699
|
+
lastUsedAt: null,
|
|
700
|
+
revokedAt: null,
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
expect(token.name).toBe("Codex");
|
|
704
|
+
expect(token.owner).toBe("u_1");
|
|
705
|
+
expect("tokenHash" in token).toBe(false);
|
|
706
|
+
});
|
|
707
|
+
|
|
685
708
|
it("computes workflow derived fields via parser bridge", () => {
|
|
686
709
|
const parser = jest.fn((yml: string) => ({
|
|
687
710
|
defs: {},
|
|
@@ -757,6 +780,300 @@ describe("@hexabot-ai/types schemas", () => {
|
|
|
757
780
|
expect(parser).toHaveBeenCalledTimes(1);
|
|
758
781
|
});
|
|
759
782
|
|
|
783
|
+
it("parses workflow export bundles without credential secrets", () => {
|
|
784
|
+
const bundle = workflowExportBundleSchema.parse({
|
|
785
|
+
kind: "hexabot.workflow.bundle",
|
|
786
|
+
schemaVersion: 1,
|
|
787
|
+
exportedAt: now,
|
|
788
|
+
workflow: {
|
|
789
|
+
exportId: "wf_1",
|
|
790
|
+
name: "Main",
|
|
791
|
+
description: null,
|
|
792
|
+
type: WorkflowType.conversational,
|
|
793
|
+
schedule: null,
|
|
794
|
+
inputSchema: {},
|
|
795
|
+
layout: {
|
|
796
|
+
x: 0,
|
|
797
|
+
y: 0,
|
|
798
|
+
zoom: 1,
|
|
799
|
+
direction: "horizontal",
|
|
800
|
+
},
|
|
801
|
+
},
|
|
802
|
+
version: {
|
|
803
|
+
number: 3,
|
|
804
|
+
checksum: "sha",
|
|
805
|
+
message: null,
|
|
806
|
+
exportedVersionId: "wfv_1",
|
|
807
|
+
},
|
|
808
|
+
definitionYml: "defs: {}\nflow: []\noutputs: {}",
|
|
809
|
+
resources: {
|
|
810
|
+
memoryDefinitions: [
|
|
811
|
+
{
|
|
812
|
+
exportId: "mem_1",
|
|
813
|
+
name: "Profile",
|
|
814
|
+
slug: "profile",
|
|
815
|
+
scope: MemoryScope.workflow,
|
|
816
|
+
schema: { type: "object" },
|
|
817
|
+
ttlSeconds: null,
|
|
818
|
+
},
|
|
819
|
+
],
|
|
820
|
+
mcpServers: [
|
|
821
|
+
{
|
|
822
|
+
exportId: "mcp_1",
|
|
823
|
+
name: "Search",
|
|
824
|
+
enabled: true,
|
|
825
|
+
transport: McpServerTransport.http,
|
|
826
|
+
url: "https://mcp.example.com",
|
|
827
|
+
command: null,
|
|
828
|
+
args: null,
|
|
829
|
+
cwd: null,
|
|
830
|
+
credentialExportId: "cred_1",
|
|
831
|
+
},
|
|
832
|
+
],
|
|
833
|
+
credentials: [
|
|
834
|
+
{
|
|
835
|
+
exportId: "cred_1",
|
|
836
|
+
name: "Search API",
|
|
837
|
+
exportedOwnerId: "u_1",
|
|
838
|
+
},
|
|
839
|
+
],
|
|
840
|
+
contentTypes: [
|
|
841
|
+
{
|
|
842
|
+
exportId: "ct_1",
|
|
843
|
+
name: "Article",
|
|
844
|
+
schema: { type: "object" },
|
|
845
|
+
},
|
|
846
|
+
],
|
|
847
|
+
labelGroups: [
|
|
848
|
+
{
|
|
849
|
+
exportId: "lg_1",
|
|
850
|
+
name: "Status",
|
|
851
|
+
},
|
|
852
|
+
],
|
|
853
|
+
labels: [
|
|
854
|
+
{
|
|
855
|
+
exportId: "label_1",
|
|
856
|
+
title: "Qualified",
|
|
857
|
+
name: "QUALIFIED",
|
|
858
|
+
description: null,
|
|
859
|
+
groupExportId: "lg_1",
|
|
860
|
+
},
|
|
861
|
+
],
|
|
862
|
+
workflows: [
|
|
863
|
+
{
|
|
864
|
+
exportId: "wf_child",
|
|
865
|
+
workflow: {
|
|
866
|
+
name: "Child",
|
|
867
|
+
description: "Called child workflow",
|
|
868
|
+
type: WorkflowType.conversational,
|
|
869
|
+
schedule: null,
|
|
870
|
+
inputSchema: {},
|
|
871
|
+
layout: {
|
|
872
|
+
x: 10,
|
|
873
|
+
y: 20,
|
|
874
|
+
zoom: 1,
|
|
875
|
+
direction: "horizontal",
|
|
876
|
+
},
|
|
877
|
+
},
|
|
878
|
+
version: {
|
|
879
|
+
number: 2,
|
|
880
|
+
checksum: "child-sha",
|
|
881
|
+
message: "Child version",
|
|
882
|
+
exportedVersionId: "wfv_child",
|
|
883
|
+
},
|
|
884
|
+
definitionYml: "defs: {}\nflow: []\noutputs: {}",
|
|
885
|
+
},
|
|
886
|
+
],
|
|
887
|
+
knowledgeBases: [
|
|
888
|
+
{
|
|
889
|
+
exportId: "kb_1",
|
|
890
|
+
name: "Docs",
|
|
891
|
+
config: { index: "docs" },
|
|
892
|
+
},
|
|
893
|
+
],
|
|
894
|
+
},
|
|
895
|
+
});
|
|
896
|
+
|
|
897
|
+
expect(bundle.resources.credentials[0]).toEqual({
|
|
898
|
+
exportId: "cred_1",
|
|
899
|
+
name: "Search API",
|
|
900
|
+
exportedOwnerId: "u_1",
|
|
901
|
+
});
|
|
902
|
+
expect(bundle.workflow.exportId).toBe("wf_1");
|
|
903
|
+
expect(bundle.resources.contentTypes[0]?.name).toBe("Article");
|
|
904
|
+
expect(bundle.resources.labelGroups[0]?.name).toBe("Status");
|
|
905
|
+
expect(bundle.resources.labels[0]).toMatchObject({
|
|
906
|
+
exportId: "label_1",
|
|
907
|
+
groupExportId: "lg_1",
|
|
908
|
+
});
|
|
909
|
+
expect(bundle.resources.workflows[0]).toMatchObject({
|
|
910
|
+
exportId: "wf_child",
|
|
911
|
+
workflow: { name: "Child" },
|
|
912
|
+
version: { exportedVersionId: "wfv_child" },
|
|
913
|
+
});
|
|
914
|
+
expect(bundle.resources.knowledgeBases).toEqual([
|
|
915
|
+
{
|
|
916
|
+
exportId: "kb_1",
|
|
917
|
+
name: "Docs",
|
|
918
|
+
config: { index: "docs" },
|
|
919
|
+
},
|
|
920
|
+
]);
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
it("defaults new workflow bundle resource arrays for older bundles", () => {
|
|
924
|
+
const bundle = workflowExportBundleSchema.parse({
|
|
925
|
+
kind: "hexabot.workflow.bundle",
|
|
926
|
+
schemaVersion: 1,
|
|
927
|
+
exportedAt: now,
|
|
928
|
+
workflow: {
|
|
929
|
+
name: "Main",
|
|
930
|
+
description: null,
|
|
931
|
+
type: WorkflowType.conversational,
|
|
932
|
+
schedule: null,
|
|
933
|
+
inputSchema: {},
|
|
934
|
+
layout: {
|
|
935
|
+
x: 0,
|
|
936
|
+
y: 0,
|
|
937
|
+
zoom: 1,
|
|
938
|
+
direction: "horizontal",
|
|
939
|
+
},
|
|
940
|
+
},
|
|
941
|
+
version: {
|
|
942
|
+
number: 1,
|
|
943
|
+
checksum: "sha",
|
|
944
|
+
message: null,
|
|
945
|
+
exportedVersionId: "wfv_1",
|
|
946
|
+
},
|
|
947
|
+
definitionYml: "defs: {}\nflow: []\noutputs: {}",
|
|
948
|
+
resources: {
|
|
949
|
+
memoryDefinitions: [],
|
|
950
|
+
mcpServers: [],
|
|
951
|
+
credentials: [],
|
|
952
|
+
},
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
expect(bundle.resources.contentTypes).toEqual([]);
|
|
956
|
+
expect(bundle.resources.labelGroups).toEqual([]);
|
|
957
|
+
expect(bundle.resources.labels).toEqual([]);
|
|
958
|
+
expect(bundle.resources.workflows).toEqual([]);
|
|
959
|
+
});
|
|
960
|
+
|
|
961
|
+
it("rejects non-array custom workflow bundle resource buckets", () => {
|
|
962
|
+
expect(() =>
|
|
963
|
+
workflowExportBundleV1Schema.parse({
|
|
964
|
+
kind: "hexabot.workflow.bundle",
|
|
965
|
+
schemaVersion: 1,
|
|
966
|
+
exportedAt: now,
|
|
967
|
+
workflow: {
|
|
968
|
+
name: "Main",
|
|
969
|
+
description: null,
|
|
970
|
+
type: WorkflowType.conversational,
|
|
971
|
+
schedule: null,
|
|
972
|
+
inputSchema: {},
|
|
973
|
+
layout: {
|
|
974
|
+
x: 0,
|
|
975
|
+
y: 0,
|
|
976
|
+
zoom: 1,
|
|
977
|
+
direction: "horizontal",
|
|
978
|
+
},
|
|
979
|
+
},
|
|
980
|
+
version: {
|
|
981
|
+
number: 1,
|
|
982
|
+
checksum: "sha",
|
|
983
|
+
message: null,
|
|
984
|
+
exportedVersionId: "wfv_1",
|
|
985
|
+
},
|
|
986
|
+
definitionYml: "defs: {}\nflow: []\noutputs: {}",
|
|
987
|
+
resources: {
|
|
988
|
+
memoryDefinitions: [],
|
|
989
|
+
mcpServers: [],
|
|
990
|
+
credentials: [],
|
|
991
|
+
knowledgeBases: {
|
|
992
|
+
exportId: "kb_1",
|
|
993
|
+
},
|
|
994
|
+
},
|
|
995
|
+
}),
|
|
996
|
+
).toThrow();
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
it("rejects credential values in workflow export bundles", () => {
|
|
1000
|
+
expect(() =>
|
|
1001
|
+
workflowExportBundleV1Schema.parse({
|
|
1002
|
+
kind: "hexabot.workflow.bundle",
|
|
1003
|
+
schemaVersion: 1,
|
|
1004
|
+
exportedAt: now,
|
|
1005
|
+
workflow: {
|
|
1006
|
+
name: "Main",
|
|
1007
|
+
description: null,
|
|
1008
|
+
type: WorkflowType.conversational,
|
|
1009
|
+
schedule: null,
|
|
1010
|
+
inputSchema: {},
|
|
1011
|
+
layout: {
|
|
1012
|
+
x: 0,
|
|
1013
|
+
y: 0,
|
|
1014
|
+
zoom: 1,
|
|
1015
|
+
direction: "horizontal",
|
|
1016
|
+
},
|
|
1017
|
+
},
|
|
1018
|
+
version: {
|
|
1019
|
+
number: 1,
|
|
1020
|
+
checksum: "sha",
|
|
1021
|
+
message: null,
|
|
1022
|
+
exportedVersionId: "wfv_1",
|
|
1023
|
+
},
|
|
1024
|
+
definitionYml: "defs: {}\nflow: []\noutputs: {}",
|
|
1025
|
+
resources: {
|
|
1026
|
+
memoryDefinitions: [],
|
|
1027
|
+
mcpServers: [],
|
|
1028
|
+
credentials: [
|
|
1029
|
+
{
|
|
1030
|
+
exportId: "cred_1",
|
|
1031
|
+
name: "Search API",
|
|
1032
|
+
value: "secret",
|
|
1033
|
+
},
|
|
1034
|
+
],
|
|
1035
|
+
},
|
|
1036
|
+
}),
|
|
1037
|
+
).toThrow();
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
it("parses workflow import results", () => {
|
|
1041
|
+
const result = workflowImportResultSchema.parse({
|
|
1042
|
+
workflow: {
|
|
1043
|
+
id: "wf_1",
|
|
1044
|
+
createdAt: now,
|
|
1045
|
+
updatedAt: now,
|
|
1046
|
+
name: "Imported",
|
|
1047
|
+
description: null,
|
|
1048
|
+
type: WorkflowType.conversational,
|
|
1049
|
+
schedule: null,
|
|
1050
|
+
inputSchema: {},
|
|
1051
|
+
builtin: false,
|
|
1052
|
+
x: 0,
|
|
1053
|
+
y: 0,
|
|
1054
|
+
zoom: 1,
|
|
1055
|
+
direction: "horizontal",
|
|
1056
|
+
currentVersion: "wfv_1",
|
|
1057
|
+
publishedVersion: null,
|
|
1058
|
+
createdBy: "u_1",
|
|
1059
|
+
runAfterMs: 0,
|
|
1060
|
+
},
|
|
1061
|
+
resources: [
|
|
1062
|
+
{
|
|
1063
|
+
kind: "knowledgeBase",
|
|
1064
|
+
exportId: "kb_1",
|
|
1065
|
+
localId: "kb_local",
|
|
1066
|
+
name: "Docs",
|
|
1067
|
+
action: "reused",
|
|
1068
|
+
},
|
|
1069
|
+
],
|
|
1070
|
+
warnings: ["Credential placeholder created."],
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
expect(result.resources[0]?.action).toBe("reused");
|
|
1074
|
+
expect(result.resources[0]?.kind).toBe("knowledgeBase");
|
|
1075
|
+
});
|
|
1076
|
+
|
|
760
1077
|
it("computes workflow run duration and mixed triggeredBy coercion", () => {
|
|
761
1078
|
const run = workflowRunSchema.parse({
|
|
762
1079
|
id: "run_1",
|
|
@@ -768,6 +1085,7 @@ describe("@hexabot-ai/types schemas", () => {
|
|
|
768
1085
|
workflowVersionId: "wfv_1",
|
|
769
1086
|
triggeredById: "s_1",
|
|
770
1087
|
threadId: "t_1",
|
|
1088
|
+
parentRun: "parent_run_1",
|
|
771
1089
|
finishedAt: "2026-01-01T00:02:00.000Z",
|
|
772
1090
|
});
|
|
773
1091
|
const full = workflowRunFullSchema.parse({
|
|
@@ -817,10 +1135,23 @@ describe("@hexabot-ai/types schemas", () => {
|
|
|
817
1135
|
avatar: null,
|
|
818
1136
|
},
|
|
819
1137
|
thread: null,
|
|
1138
|
+
parentRun: {
|
|
1139
|
+
id: "parent_run_1",
|
|
1140
|
+
createdAt: now,
|
|
1141
|
+
updatedAt: now,
|
|
1142
|
+
status: "suspended",
|
|
1143
|
+
context: {},
|
|
1144
|
+
workflowId: "parent_wf_1",
|
|
1145
|
+
workflowVersionId: null,
|
|
1146
|
+
triggeredById: null,
|
|
1147
|
+
parentRun: null,
|
|
1148
|
+
},
|
|
820
1149
|
});
|
|
821
1150
|
|
|
822
1151
|
expect(run.duration).toBe(120000);
|
|
1152
|
+
expect(run.parentRun).toBe("parent_run_1");
|
|
823
1153
|
expect(full.triggeredBy?.id).toBe("s_1");
|
|
1154
|
+
expect(full.parentRun?.workflow).toBe("parent_wf_1");
|
|
824
1155
|
expect(typeof resolveRunDurationMs(run)).toBe("number");
|
|
825
1156
|
});
|
|
826
1157
|
|
package/src/user/index.ts
CHANGED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2026 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
|
|
9
|
+
import { asId, withAliases } from "../shared/aliases";
|
|
10
|
+
import { baseStubSchema } from "../shared/base";
|
|
11
|
+
import { preprocess } from "../shared/preprocess";
|
|
12
|
+
|
|
13
|
+
import { userSchema } from "./user";
|
|
14
|
+
|
|
15
|
+
const nullableDateSchema = preprocess(
|
|
16
|
+
(value) => (value == null ? null : value),
|
|
17
|
+
z.coerce.date().nullable(),
|
|
18
|
+
);
|
|
19
|
+
const mcpTokenAliasMap = {
|
|
20
|
+
ownerId: "owner",
|
|
21
|
+
} as const;
|
|
22
|
+
const mcpTokenStubObjectSchema = baseStubSchema.extend({
|
|
23
|
+
name: z.string(),
|
|
24
|
+
tokenPrefix: z.string(),
|
|
25
|
+
expiresAt: nullableDateSchema,
|
|
26
|
+
lastUsedAt: nullableDateSchema,
|
|
27
|
+
revokedAt: nullableDateSchema,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export const mcpTokenStubSchema = mcpTokenStubObjectSchema;
|
|
31
|
+
|
|
32
|
+
export const mcpTokenSchema = preprocess(
|
|
33
|
+
(value) => withAliases(value, mcpTokenAliasMap),
|
|
34
|
+
mcpTokenStubObjectSchema.extend({
|
|
35
|
+
owner: preprocess(
|
|
36
|
+
(value) => (value == null ? null : asId(value)),
|
|
37
|
+
z.string(),
|
|
38
|
+
),
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
export const mcpTokenFullSchema = mcpTokenStubObjectSchema.extend({
|
|
43
|
+
owner: preprocess(
|
|
44
|
+
(value) => (value == null ? null : value),
|
|
45
|
+
z.lazy(() => userSchema).nullable(),
|
|
46
|
+
),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export type McpTokenStub = z.infer<typeof mcpTokenStubSchema>;
|
|
50
|
+
|
|
51
|
+
export type McpToken = z.infer<typeof mcpTokenSchema>;
|
|
52
|
+
|
|
53
|
+
export type McpTokenFull = z.infer<typeof mcpTokenFullSchema>;
|
package/src/workflow/index.ts
CHANGED
|
@@ -68,3 +68,33 @@ export {
|
|
|
68
68
|
type McpServerFull,
|
|
69
69
|
type McpServerStub,
|
|
70
70
|
} from "./mcp-server";
|
|
71
|
+
|
|
72
|
+
export {
|
|
73
|
+
WORKFLOW_EXPORT_BUNDLE_KIND,
|
|
74
|
+
WORKFLOW_TRANSFER_RESOURCE_KIND_PATTERN,
|
|
75
|
+
workflowExportBundleContentTypeSchema,
|
|
76
|
+
workflowExportBundleCredentialSchema,
|
|
77
|
+
workflowExportBundleLabelGroupSchema,
|
|
78
|
+
workflowExportBundleLabelSchema,
|
|
79
|
+
workflowExportBundleMcpServerSchema,
|
|
80
|
+
workflowExportBundleMemoryDefinitionSchema,
|
|
81
|
+
workflowExportBundleSchema,
|
|
82
|
+
workflowExportBundleV1Schema,
|
|
83
|
+
workflowExportBundleWorkflowDependencySchema,
|
|
84
|
+
workflowImportResourceActionSchema,
|
|
85
|
+
workflowImportResourceResultSchema,
|
|
86
|
+
workflowImportResultSchema,
|
|
87
|
+
workflowTransferResourceKindSchema,
|
|
88
|
+
type WorkflowExportBundle,
|
|
89
|
+
type WorkflowExportBundleContentType,
|
|
90
|
+
type WorkflowExportBundleCredential,
|
|
91
|
+
type WorkflowExportBundleLabel,
|
|
92
|
+
type WorkflowExportBundleLabelGroup,
|
|
93
|
+
type WorkflowExportBundleMcpServer,
|
|
94
|
+
type WorkflowExportBundleMemoryDefinition,
|
|
95
|
+
type WorkflowExportBundleV1,
|
|
96
|
+
type WorkflowExportBundleWorkflowDependency,
|
|
97
|
+
type WorkflowImportResourceAction,
|
|
98
|
+
type WorkflowImportResourceResult,
|
|
99
|
+
type WorkflowImportResult,
|
|
100
|
+
} from "./workflow-transfer";
|
|
@@ -68,6 +68,7 @@ const workflowRunAliasMap = {
|
|
|
68
68
|
workflowVersionId: "workflowVersion",
|
|
69
69
|
triggeredById: "triggeredBy",
|
|
70
70
|
threadId: "thread",
|
|
71
|
+
parentRunId: "parentRun",
|
|
71
72
|
} as const;
|
|
72
73
|
const workflowRunStubObjectSchema = baseStubSchema.extend({
|
|
73
74
|
status: workflowRunStatusSchema,
|
|
@@ -133,6 +134,10 @@ export const workflowRunSchema = preprocess(
|
|
|
133
134
|
(value) => (value == null ? null : asId(value)),
|
|
134
135
|
z.string().nullable(),
|
|
135
136
|
),
|
|
137
|
+
parentRun: preprocess(
|
|
138
|
+
(value) => (value == null ? null : asId(value)),
|
|
139
|
+
z.string().nullable(),
|
|
140
|
+
),
|
|
136
141
|
}),
|
|
137
142
|
);
|
|
138
143
|
|
|
@@ -146,6 +151,10 @@ export const workflowRunFullSchema = preprocess(
|
|
|
146
151
|
.optional(),
|
|
147
152
|
triggeredBy: nullableUserOrSubscriberSchema,
|
|
148
153
|
thread: threadSchema.nullable().optional(),
|
|
154
|
+
parentRun: z
|
|
155
|
+
.lazy(() => workflowRunSchema)
|
|
156
|
+
.nullable()
|
|
157
|
+
.optional(),
|
|
149
158
|
}),
|
|
150
159
|
);
|
|
151
160
|
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Hexabot — Fair Core License (FCL-1.0-ALv2)
|
|
3
|
+
* Copyright (c) 2026 Hexastack.
|
|
4
|
+
* Full terms: see LICENSE.md.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
directionTypeSchema,
|
|
11
|
+
mcpServerTransportSchema,
|
|
12
|
+
memoryScopeSchema,
|
|
13
|
+
workflowTypeSchema,
|
|
14
|
+
} from "./domain";
|
|
15
|
+
import { workflowSchema } from "./workflow";
|
|
16
|
+
|
|
17
|
+
export const WORKFLOW_EXPORT_BUNDLE_KIND = "hexabot.workflow.bundle";
|
|
18
|
+
|
|
19
|
+
export const WORKFLOW_TRANSFER_RESOURCE_KIND_PATTERN =
|
|
20
|
+
/^[a-z][A-Za-z0-9]*(?:[._-][A-Za-z0-9]+)*$/;
|
|
21
|
+
|
|
22
|
+
export const workflowTransferResourceKindSchema = z
|
|
23
|
+
.string()
|
|
24
|
+
.min(1)
|
|
25
|
+
.regex(WORKFLOW_TRANSFER_RESOURCE_KIND_PATTERN);
|
|
26
|
+
|
|
27
|
+
const workflowExportBundleLayoutSchema = z.strictObject({
|
|
28
|
+
x: z.coerce.number(),
|
|
29
|
+
y: z.coerce.number(),
|
|
30
|
+
zoom: z.coerce.number(),
|
|
31
|
+
direction: directionTypeSchema,
|
|
32
|
+
});
|
|
33
|
+
const workflowExportBundleWorkflowSchema = z.strictObject({
|
|
34
|
+
exportId: z.string().min(1).optional(),
|
|
35
|
+
name: z.string().min(1),
|
|
36
|
+
description: z.string().nullable(),
|
|
37
|
+
type: workflowTypeSchema,
|
|
38
|
+
schedule: z.string().nullable(),
|
|
39
|
+
inputSchema: z.any(),
|
|
40
|
+
layout: workflowExportBundleLayoutSchema,
|
|
41
|
+
});
|
|
42
|
+
const workflowExportBundleVersionSchema = z.strictObject({
|
|
43
|
+
number: z.coerce.number(),
|
|
44
|
+
checksum: z.string(),
|
|
45
|
+
message: z.string().nullable(),
|
|
46
|
+
exportedVersionId: z.string().min(1),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const workflowExportBundleMemoryDefinitionSchema = z.strictObject({
|
|
50
|
+
exportId: z.string().min(1),
|
|
51
|
+
name: z.string().min(1),
|
|
52
|
+
slug: z.string().min(1),
|
|
53
|
+
scope: memoryScopeSchema,
|
|
54
|
+
schema: z.any(),
|
|
55
|
+
ttlSeconds: z.coerce.number().nullable().optional(),
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const workflowExportBundleCredentialSchema = z.strictObject({
|
|
59
|
+
exportId: z.string().min(1),
|
|
60
|
+
name: z.string().min(1),
|
|
61
|
+
exportedOwnerId: z.string().optional(),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
export const workflowExportBundleMcpServerSchema = z.strictObject({
|
|
65
|
+
exportId: z.string().min(1),
|
|
66
|
+
name: z.string().min(1),
|
|
67
|
+
enabled: z.coerce.boolean(),
|
|
68
|
+
transport: mcpServerTransportSchema,
|
|
69
|
+
url: z.string().nullable(),
|
|
70
|
+
command: z.string().nullable(),
|
|
71
|
+
args: z.array(z.string()).nullable(),
|
|
72
|
+
cwd: z.string().nullable(),
|
|
73
|
+
credentialExportId: z.string().nullable().optional(),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export const workflowExportBundleContentTypeSchema = z.strictObject({
|
|
77
|
+
exportId: z.string().min(1),
|
|
78
|
+
name: z.string().min(1),
|
|
79
|
+
schema: z.any(),
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const workflowExportBundleLabelGroupSchema = z.strictObject({
|
|
83
|
+
exportId: z.string().min(1),
|
|
84
|
+
name: z.string().min(1),
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
export const workflowExportBundleLabelSchema = z.strictObject({
|
|
88
|
+
exportId: z.string().min(1),
|
|
89
|
+
title: z.string().min(1),
|
|
90
|
+
name: z.string().min(1),
|
|
91
|
+
description: z.string().nullable(),
|
|
92
|
+
groupExportId: z.string().nullable(),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
export const workflowExportBundleWorkflowDependencySchema = z.strictObject({
|
|
96
|
+
exportId: z.string().min(1),
|
|
97
|
+
workflow: workflowExportBundleWorkflowSchema.omit({ exportId: true }),
|
|
98
|
+
version: workflowExportBundleVersionSchema,
|
|
99
|
+
definitionYml: z.string().min(1),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const workflowExportBundleResourcesSchema = z
|
|
103
|
+
.object({
|
|
104
|
+
memoryDefinitions: z.array(workflowExportBundleMemoryDefinitionSchema),
|
|
105
|
+
mcpServers: z.array(workflowExportBundleMcpServerSchema),
|
|
106
|
+
credentials: z.array(workflowExportBundleCredentialSchema),
|
|
107
|
+
contentTypes: z.array(workflowExportBundleContentTypeSchema).default([]),
|
|
108
|
+
labelGroups: z.array(workflowExportBundleLabelGroupSchema).default([]),
|
|
109
|
+
labels: z.array(workflowExportBundleLabelSchema).default([]),
|
|
110
|
+
workflows: z
|
|
111
|
+
.array(workflowExportBundleWorkflowDependencySchema)
|
|
112
|
+
.default([]),
|
|
113
|
+
})
|
|
114
|
+
.catchall(z.array(z.unknown()));
|
|
115
|
+
|
|
116
|
+
export const workflowExportBundleV1Schema = z.strictObject({
|
|
117
|
+
kind: z.literal(WORKFLOW_EXPORT_BUNDLE_KIND),
|
|
118
|
+
schemaVersion: z.literal(1),
|
|
119
|
+
exportedAt: z.iso.datetime(),
|
|
120
|
+
workflow: workflowExportBundleWorkflowSchema,
|
|
121
|
+
version: workflowExportBundleVersionSchema,
|
|
122
|
+
definitionYml: z.string().min(1),
|
|
123
|
+
resources: workflowExportBundleResourcesSchema,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export const workflowExportBundleSchema = workflowExportBundleV1Schema;
|
|
127
|
+
|
|
128
|
+
export const workflowImportResourceActionSchema = z.enum([
|
|
129
|
+
"created",
|
|
130
|
+
"reused",
|
|
131
|
+
"placeholder_created",
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
export const workflowImportResourceResultSchema = z.strictObject({
|
|
135
|
+
kind: workflowTransferResourceKindSchema,
|
|
136
|
+
exportId: z.string().min(1),
|
|
137
|
+
localId: z.string().min(1),
|
|
138
|
+
name: z.string().min(1),
|
|
139
|
+
action: workflowImportResourceActionSchema,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
export const workflowImportResultSchema = z.strictObject({
|
|
143
|
+
workflow: workflowSchema,
|
|
144
|
+
resources: z.array(workflowImportResourceResultSchema),
|
|
145
|
+
warnings: z.array(z.string()),
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
export type WorkflowExportBundleMemoryDefinition = z.infer<
|
|
149
|
+
typeof workflowExportBundleMemoryDefinitionSchema
|
|
150
|
+
>;
|
|
151
|
+
|
|
152
|
+
export type WorkflowExportBundleCredential = z.infer<
|
|
153
|
+
typeof workflowExportBundleCredentialSchema
|
|
154
|
+
>;
|
|
155
|
+
|
|
156
|
+
export type WorkflowExportBundleMcpServer = z.infer<
|
|
157
|
+
typeof workflowExportBundleMcpServerSchema
|
|
158
|
+
>;
|
|
159
|
+
|
|
160
|
+
export type WorkflowExportBundleContentType = z.infer<
|
|
161
|
+
typeof workflowExportBundleContentTypeSchema
|
|
162
|
+
>;
|
|
163
|
+
|
|
164
|
+
export type WorkflowExportBundleLabelGroup = z.infer<
|
|
165
|
+
typeof workflowExportBundleLabelGroupSchema
|
|
166
|
+
>;
|
|
167
|
+
|
|
168
|
+
export type WorkflowExportBundleLabel = z.infer<
|
|
169
|
+
typeof workflowExportBundleLabelSchema
|
|
170
|
+
>;
|
|
171
|
+
|
|
172
|
+
export type WorkflowExportBundleWorkflowDependency = z.infer<
|
|
173
|
+
typeof workflowExportBundleWorkflowDependencySchema
|
|
174
|
+
>;
|
|
175
|
+
|
|
176
|
+
export type WorkflowExportBundleV1 = z.infer<
|
|
177
|
+
typeof workflowExportBundleV1Schema
|
|
178
|
+
>;
|
|
179
|
+
|
|
180
|
+
export type WorkflowExportBundle = z.infer<typeof workflowExportBundleSchema>;
|
|
181
|
+
|
|
182
|
+
export type WorkflowImportResourceAction = z.infer<
|
|
183
|
+
typeof workflowImportResourceActionSchema
|
|
184
|
+
>;
|
|
185
|
+
|
|
186
|
+
export type WorkflowImportResourceResult = z.infer<
|
|
187
|
+
typeof workflowImportResourceResultSchema
|
|
188
|
+
>;
|
|
189
|
+
|
|
190
|
+
export type WorkflowImportResult = z.infer<typeof workflowImportResultSchema>;
|