@elevasis/core 0.15.0 → 0.16.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.
Files changed (88) hide show
  1. package/dist/index.d.ts +1718 -19
  2. package/dist/index.js +369 -25
  3. package/dist/organization-model/index.d.ts +1718 -19
  4. package/dist/organization-model/index.js +369 -25
  5. package/dist/test-utils/index.d.ts +1108 -371
  6. package/dist/test-utils/index.js +357 -17
  7. package/package.json +5 -1
  8. package/src/__tests__/publish.test.ts +14 -13
  9. package/src/__tests__/template-core-compatibility.test.ts +4 -4
  10. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +1109 -882
  11. package/src/auth/multi-tenancy/index.ts +3 -0
  12. package/src/auth/multi-tenancy/theme-presets.ts +45 -0
  13. package/src/auth/multi-tenancy/types.ts +57 -83
  14. package/src/auth/multi-tenancy/users/api-schemas.ts +165 -194
  15. package/src/business/acquisition/activity-events.ts +13 -4
  16. package/src/business/acquisition/api-schemas.test.ts +315 -4
  17. package/src/business/acquisition/api-schemas.ts +122 -8
  18. package/src/business/acquisition/build-templates.ts +44 -0
  19. package/src/business/acquisition/crm-next-action.test.ts +262 -0
  20. package/src/business/acquisition/crm-next-action.ts +220 -0
  21. package/src/business/acquisition/crm-priority.test.ts +216 -0
  22. package/src/business/acquisition/crm-priority.ts +349 -0
  23. package/src/business/acquisition/crm-state-actions.test.ts +151 -160
  24. package/src/business/acquisition/deal-ownership.test.ts +351 -0
  25. package/src/business/acquisition/deal-ownership.ts +120 -0
  26. package/src/business/acquisition/derive-actions.test.ts +101 -37
  27. package/src/business/acquisition/derive-actions.ts +102 -87
  28. package/src/business/acquisition/index.ts +10 -0
  29. package/src/business/acquisition/types.ts +400 -366
  30. package/src/business/crm/api-schemas.ts +40 -0
  31. package/src/business/crm/index.ts +1 -0
  32. package/src/business/deals/api-schemas.ts +79 -0
  33. package/src/business/deals/index.ts +1 -0
  34. package/src/business/projects/types.ts +124 -88
  35. package/src/execution/core/runner-types.ts +61 -80
  36. package/src/execution/engine/index.ts +4 -3
  37. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -104
  38. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1473
  39. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -102
  40. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -179
  41. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -309
  42. package/src/execution/engine/tools/integration/tool.ts +255 -253
  43. package/src/execution/engine/tools/lead-service-types.ts +939 -924
  44. package/src/execution/engine/tools/messages.ts +43 -0
  45. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +6 -5
  46. package/src/execution/engine/tools/platform/acquisition/types.ts +5 -2
  47. package/src/execution/engine/tools/platform/email/types.ts +97 -96
  48. package/src/execution/engine/tools/registry.ts +4 -3
  49. package/src/execution/engine/tools/tool-maps.ts +3 -1
  50. package/src/execution/engine/tools/types.ts +234 -233
  51. package/src/execution/engine/workflow/types.ts +195 -193
  52. package/src/execution/external/api-schemas.ts +40 -0
  53. package/src/execution/external/index.ts +1 -0
  54. package/src/knowledge/README.md +32 -0
  55. package/src/knowledge/__tests__/queries.test.ts +504 -0
  56. package/src/knowledge/format.ts +99 -0
  57. package/src/knowledge/index.ts +5 -0
  58. package/src/knowledge/queries.ts +256 -0
  59. package/src/organization-model/__tests__/defaults.test.ts +172 -172
  60. package/src/organization-model/__tests__/foundation.test.ts +7 -7
  61. package/src/organization-model/__tests__/icons.test.ts +27 -0
  62. package/src/organization-model/__tests__/knowledge.test.ts +214 -0
  63. package/src/organization-model/contracts.ts +17 -15
  64. package/src/organization-model/defaults.ts +74 -19
  65. package/src/organization-model/domains/knowledge.ts +53 -0
  66. package/src/organization-model/domains/navigation.ts +416 -399
  67. package/src/organization-model/domains/prospecting.ts +204 -1
  68. package/src/organization-model/domains/sales.test.ts +29 -0
  69. package/src/organization-model/domains/sales.ts +102 -0
  70. package/src/organization-model/domains/shared.ts +6 -5
  71. package/src/organization-model/foundation.ts +10 -6
  72. package/src/organization-model/graph/build.ts +209 -182
  73. package/src/organization-model/graph/schema.ts +37 -34
  74. package/src/organization-model/graph/types.ts +47 -31
  75. package/src/organization-model/icons.ts +81 -0
  76. package/src/organization-model/index.ts +8 -3
  77. package/src/organization-model/organization-model.mdx +1 -1
  78. package/src/organization-model/published.ts +103 -86
  79. package/src/organization-model/schema.ts +90 -85
  80. package/src/organization-model/types.ts +42 -35
  81. package/src/platform/constants/versions.ts +1 -1
  82. package/src/platform/index.ts +23 -27
  83. package/src/platform/registry/index.ts +0 -4
  84. package/src/platform/registry/resource-registry.ts +0 -77
  85. package/src/platform/registry/serialized-types.ts +148 -219
  86. package/src/platform/registry/stats-types.ts +60 -60
  87. package/src/reference/_generated/contracts.md +829 -595
  88. package/src/supabase/database.types.ts +2978 -2958
@@ -177,15 +177,53 @@ export type OrganizationModelObjective = z.infer<typeof ObjectiveSchema>
177
177
  export type OrganizationModelKeyResult = z.infer<typeof KeyResultSchema>
178
178
  ```
179
179
 
180
+ ### `OrganizationModelKnowledge`
181
+
182
+ ```typescript
183
+ export type OrganizationModelKnowledge = z.infer<typeof KnowledgeDomainSchema>
184
+ ```
185
+
186
+ ### `OrgKnowledgeNode`
187
+
188
+ ```typescript
189
+ export type OrgKnowledgeNode = z.infer<typeof OrgKnowledgeNodeSchema>
190
+ ```
191
+
192
+ ### `OrgKnowledgeKind`
193
+
194
+ ```typescript
195
+ export type OrgKnowledgeKind = z.infer<typeof OrgKnowledgeKindSchema>
196
+ ```
197
+
198
+ ### `OrganizationModelIconToken`
199
+
200
+ ```typescript
201
+ export type OrganizationModelIconToken = z.infer<typeof OrganizationModelIconTokenSchema>
202
+ ```
203
+
204
+ ### `OrganizationModelBuiltinIconToken`
205
+
206
+ ```typescript
207
+ export type OrganizationModelBuiltinIconToken = z.infer<typeof OrganizationModelBuiltinIconTokenSchema>
208
+ ```
209
+
180
210
  ### `DeepPartial`
181
211
 
182
212
  ```typescript
183
- export type DeepPartial<T> =
213
+ export type DeepPartial<T> =
184
214
  T extends Array<infer U> ? Array<DeepPartial<U>> : T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T
185
215
  ```
186
216
 
187
217
  ## Feature System
188
218
 
219
+ ### `ElevasisOrganizationModel`
220
+
221
+ ```typescript
222
+ export type ElevasisOrganizationModel = Omit<OrganizationModel, 'knowledge'> & {
223
+ knowledge?: OrganizationModel['knowledge']
224
+ }
225
+ ```
226
+
189
227
  ### `FeatureSidebarComponent`
190
228
 
191
229
  ```typescript
@@ -324,7 +362,7 @@ export interface OrganizationGraphContextValue {
324
362
  ```typescript
325
363
  export interface ElevasisFeaturesProviderProps {
326
364
  features: FeatureModule[]
327
- organizationModel?: OrganizationModel
365
+ organizationModel?: ElevasisOrganizationModel
328
366
  timeRange?: TimeRange
329
367
  operationsApiUrl?: string
330
368
  operationsSSEManager?: SSEConnectionManagerLike
@@ -809,73 +847,73 @@ export interface DeploymentSpec {
809
847
  ### `AcqCompany`
810
848
 
811
849
  ```typescript
812
- /**
813
- * Company record in the acquisition database.
814
- * Contains enriched company data from various sources.
815
- * Transformed from AcqCompanyRow with camelCase properties.
816
- */
817
- export interface AcqCompany {
818
- id: string
819
- organizationId: string
820
- name: string
821
- domain: string | null
822
- linkedinUrl: string | null
823
- website: string | null
824
- numEmployees: number | null
825
- foundedYear: number | null
826
- locationCity: string | null
827
- locationState: string | null
828
- category: string | null
829
- categoryPain: string | null
830
- segment: string | null
831
- pipelineStatus: CompanyPipelineStatus | null
832
- enrichmentData: CompanyEnrichmentData | null
833
- source: string | null
834
- batchId: string | null
835
- status: 'active' | 'invalid'
836
- verticalResearch: string | null
837
- /** Track A: flat qualification score (null until a scoring rubric is defined). Added by W1 migration. */
838
- qualificationScore: number | null
839
- /** Track A: flat qualification signals jsonb preserving the result payload shape. Added by W1 migration. */
840
- qualificationSignals: Record<string, unknown> | null
841
- /** Track A: key identifying the rubric used for qualification. Added by W1 migration. */
842
- qualificationRubricKey: string | null
843
- createdAt: Date
844
- updatedAt: Date
850
+ /**
851
+ * Company record in the acquisition database.
852
+ * Contains enriched company data from various sources.
853
+ * Transformed from AcqCompanyRow with camelCase properties.
854
+ */
855
+ export interface AcqCompany {
856
+ id: string
857
+ organizationId: string
858
+ name: string
859
+ domain: string | null
860
+ linkedinUrl: string | null
861
+ website: string | null
862
+ numEmployees: number | null
863
+ foundedYear: number | null
864
+ locationCity: string | null
865
+ locationState: string | null
866
+ category: string | null
867
+ categoryPain: string | null
868
+ segment: string | null
869
+ pipelineStatus: CompanyPipelineStatus | null
870
+ enrichmentData: CompanyEnrichmentData | null
871
+ source: string | null
872
+ batchId: string | null
873
+ status: 'active' | 'invalid'
874
+ verticalResearch: string | null
875
+ /** Track A: flat qualification score (null until a scoring rubric is defined). Added by W1 migration. */
876
+ qualificationScore: number | null
877
+ /** Track A: flat qualification signals jsonb preserving the result payload shape. Added by W1 migration. */
878
+ qualificationSignals: Record<string, unknown> | null
879
+ /** Track A: key identifying the rubric used for qualification. Added by W1 migration. */
880
+ qualificationRubricKey: string | null
881
+ createdAt: Date
882
+ updatedAt: Date
845
883
  }
846
884
  ```
847
885
 
848
886
  ### `AcqContact`
849
887
 
850
888
  ```typescript
851
- /**
852
- * Contact record in the acquisition database.
853
- * Contains enriched contact data and personalization content.
854
- * Transformed from AcqContactRow with camelCase properties.
855
- */
856
- export interface AcqContact {
857
- id: string
858
- organizationId: string
859
- companyId: string | null
860
- email: string
861
- emailValid: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN' | null
862
- firstName: string | null
863
- lastName: string | null
864
- linkedinUrl: string | null
865
- title: string | null
866
- headline: string | null
867
- filterReason: string | null
868
- openingLine: string | null
869
- source: string | null
870
- sourceId: string | null
871
- pipelineStatus: ContactPipelineStatus | null
872
- enrichmentData: ContactEnrichmentData | null
873
- /** Attio Person record ID - set when contact responds and is added to CRM */
874
- attioPersonId: string | null
875
- batchId: string | null
876
- status: 'active' | 'invalid'
877
- createdAt: Date
878
- updatedAt: Date
889
+ /**
890
+ * Contact record in the acquisition database.
891
+ * Contains enriched contact data and personalization content.
892
+ * Transformed from AcqContactRow with camelCase properties.
893
+ */
894
+ export interface AcqContact {
895
+ id: string
896
+ organizationId: string
897
+ companyId: string | null
898
+ email: string
899
+ emailValid: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN' | null
900
+ firstName: string | null
901
+ lastName: string | null
902
+ linkedinUrl: string | null
903
+ title: string | null
904
+ headline: string | null
905
+ filterReason: string | null
906
+ openingLine: string | null
907
+ source: string | null
908
+ sourceId: string | null
909
+ pipelineStatus: ContactPipelineStatus | null
910
+ enrichmentData: ContactEnrichmentData | null
911
+ /** Attio Person record ID - set when contact responds and is added to CRM */
912
+ attioPersonId: string | null
913
+ batchId: string | null
914
+ status: 'active' | 'invalid'
915
+ createdAt: Date
916
+ updatedAt: Date
879
917
  }
880
918
  ```
881
919
 
@@ -885,12 +923,32 @@ export interface AcqContact {
885
923
  export type DealStage = 'interested' | 'proposal' | 'closing' | 'closed_won' | 'closed_lost' | 'nurturing'
886
924
  ```
887
925
 
926
+ ### `DealPriorityBucketKey`
927
+
928
+ ```typescript
929
+ export type DealPriorityBucketKey = 'needs_response' | 'follow_up_due' | 'waiting' | 'stale' | 'closed_low'
930
+ ```
931
+
932
+ ### `DealPriority`
933
+
934
+ ```typescript
935
+ export interface DealPriority {
936
+ bucketKey: DealPriorityBucketKey
937
+ rank: number
938
+ label: string
939
+ color: string
940
+ reason: string
941
+ latestActivityAt: string | null
942
+ nextActionAt: string | null
943
+ }
944
+ ```
945
+
888
946
  ### `KanbanStageConfig`
889
947
 
890
948
  ```typescript
891
- export interface KanbanStageConfig {
892
- color: string // Mantine color token (e.g. 'blue', 'teal')
893
- label?: string // Optional display label override
949
+ export interface KanbanStageConfig {
950
+ color: string // Mantine color token (e.g. 'blue', 'teal')
951
+ label?: string // Optional display label override
894
952
  }
895
953
  ```
896
954
 
@@ -903,46 +961,49 @@ export type KanbanBoardConfig = Partial<Record<DealStage, KanbanStageConfig>>
903
961
  ### `DealContact`
904
962
 
905
963
  ```typescript
906
- export interface DealContact {
907
- id: string
908
- first_name: string | null
909
- last_name: string | null
910
- email: string
911
- title: string | null
912
- headline: string | null
913
- linkedin_url: string | null
914
- pipeline_status: Record<string, unknown> | null
915
- enrichment_data: Record<string, unknown> | null
916
- company: {
917
- id: string
918
- name: string
919
- domain: string | null
920
- website: string | null
921
- linkedin_url: string | null
922
- segment: string | null
923
- category: string | null
924
- num_employees: number | null
925
- } | null
964
+ export interface DealContact {
965
+ id: string
966
+ first_name: string | null
967
+ last_name: string | null
968
+ email: string
969
+ title: string | null
970
+ headline: string | null
971
+ linkedin_url: string | null
972
+ pipeline_status: Record<string, unknown> | null
973
+ enrichment_data: Record<string, unknown> | null
974
+ company: {
975
+ id: string
976
+ name: string
977
+ domain: string | null
978
+ website: string | null
979
+ linkedin_url: string | null
980
+ segment: string | null
981
+ category: string | null
982
+ num_employees: number | null
983
+ } | null
926
984
  }
927
985
  ```
928
986
 
929
987
  ### `DealFilters`
930
988
 
931
989
  ```typescript
932
- export interface DealFilters {
933
- stage?: DealStage
934
- search?: string
935
- limit?: number
936
- offset?: number
990
+ export interface DealFilters {
991
+ stage?: DealStage
992
+ search?: string
993
+ limit?: number
994
+ offset?: number
937
995
  }
938
996
  ```
939
997
 
940
998
  ### `DealListItem`
941
999
 
942
1000
  ```typescript
943
- /** Deal list item with joined contact and company data */
944
- export interface DealListItem extends AcqDealRow {
945
- contact: DealContact | null
1001
+ /** Deal list item with joined contact and company data */
1002
+ export interface DealListItem extends AcqDealRow {
1003
+ priority: DealPriority
1004
+ ownership: 'us' | 'them' | null
1005
+ nextAction: string | null
1006
+ contact: DealContact | null
946
1007
  }
947
1008
  ```
948
1009
 
@@ -955,31 +1016,91 @@ export type DealDetail = DealListItem
955
1016
  ### `AcqDealTaskKind`
956
1017
 
957
1018
  ```typescript
958
- /** Task kind options for a deal task (human follow-up action type) */
1019
+ /** Task kind options for a deal task (human follow-up action type) */
959
1020
  export type AcqDealTaskKind = 'call' | 'email' | 'meeting' | 'other'
960
1021
  ```
961
1022
 
962
1023
  ### `AcqDealTask`
963
1024
 
964
1025
  ```typescript
965
- /**
966
- * A CRM to-do item attached to a deal representing a human follow-up action.
967
- * Transformed from AcqDealTaskRow with camelCase properties.
968
- */
969
- export interface AcqDealTask {
970
- id: string
971
- organizationId: string
972
- dealId: string
973
- title: string
974
- description: string | null
975
- kind: AcqDealTaskKind
976
- dueAt: string | null
977
- assigneeUserId: string | null
978
- completedAt: string | null
979
- completedByUserId: string | null
980
- createdAt: string
981
- updatedAt: string
982
- createdByUserId: string | null
1026
+ /**
1027
+ * A CRM to-do item attached to a deal representing a human follow-up action.
1028
+ * Transformed from AcqDealTaskRow with camelCase properties.
1029
+ */
1030
+ export interface AcqDealTask {
1031
+ id: string
1032
+ organizationId: string
1033
+ dealId: string
1034
+ title: string
1035
+ description: string | null
1036
+ kind: AcqDealTaskKind
1037
+ dueAt: string | null
1038
+ assigneeUserId: string | null
1039
+ completedAt: string | null
1040
+ completedByUserId: string | null
1041
+ createdAt: string
1042
+ updatedAt: string
1043
+ createdByUserId: string | null
1044
+ }
1045
+ ```
1046
+
1047
+ ### `CrmPriorityBucketKey`
1048
+
1049
+ ```typescript
1050
+ export type CrmPriorityBucketKey = 'needs_response' | 'follow_up_due' | 'waiting' | 'stale' | 'closed_low'
1051
+ ```
1052
+
1053
+ ### `CrmPriorityBucketDefinition`
1054
+
1055
+ ```typescript
1056
+ export interface CrmPriorityBucketDefinition {
1057
+ bucketKey: CrmPriorityBucketKey
1058
+ label: string
1059
+ /** Lower ranks sort first in deal lists and pipeline columns. */
1060
+ rank: number
1061
+ /** UI color token. Consumers may map this to their design system. */
1062
+ color: string
1063
+ }
1064
+ ```
1065
+
1066
+ ### `CrmPriorityRuleConfig`
1067
+
1068
+ ```typescript
1069
+ export interface CrmPriorityRuleConfig {
1070
+ buckets: CrmPriorityBucketDefinition[]
1071
+ closedStageKeys: string[]
1072
+ followUpAfterDaysByStateKey: Record<string, number>
1073
+ staleAfterDays: number
1074
+ }
1075
+ ```
1076
+
1077
+ ### `CRM_PRIORITY_BUCKETS`
1078
+
1079
+ ```typescript
1080
+ export const CRM_PRIORITY_BUCKETS: CrmPriorityBucketDefinition[] = [
1081
+ { bucketKey: 'needs_response', label: 'Needs Response', rank: 10, color: 'red' },
1082
+ { bucketKey: 'follow_up_due', label: 'Follow-up Due', rank: 20, color: 'orange' },
1083
+ { bucketKey: 'waiting', label: 'Waiting', rank: 30, color: 'blue' },
1084
+ { bucketKey: 'stale', label: 'Stale', rank: 40, color: 'gray' },
1085
+ { bucketKey: 'closed_low', label: 'Closed', rank: 50, color: 'dark' }
1086
+ ]
1087
+ ```
1088
+
1089
+ ### `DEFAULT_CRM_PRIORITY_RULE_CONFIG`
1090
+
1091
+ ```typescript
1092
+ export const DEFAULT_CRM_PRIORITY_RULE_CONFIG: CrmPriorityRuleConfig = {
1093
+ buckets: CRM_PRIORITY_BUCKETS,
1094
+ closedStageKeys: ['closed_won', 'closed_lost'],
1095
+ followUpAfterDaysByStateKey: {
1096
+ discovery_link_sent: 3,
1097
+ discovery_nudging: 2,
1098
+ reply_sent: 3,
1099
+ followup_1_sent: 3,
1100
+ followup_2_sent: 5,
1101
+ followup_3_sent: 7
1102
+ },
1103
+ staleAfterDays: 14
983
1104
  }
984
1105
  ```
985
1106
 
@@ -1138,6 +1259,20 @@ export const DealContactSummarySchema = z.object({
1138
1259
  })
1139
1260
  ```
1140
1261
 
1262
+ ### `DealPrioritySchema`
1263
+
1264
+ ```typescript
1265
+ export const DealPrioritySchema = z.object({
1266
+ bucketKey: z.enum(['needs_response', 'follow_up_due', 'waiting', 'stale', 'closed_low']),
1267
+ rank: z.number().int(),
1268
+ label: z.string(),
1269
+ color: z.string(),
1270
+ reason: z.string(),
1271
+ latestActivityAt: z.string().nullable(),
1272
+ nextActionAt: z.string().nullable()
1273
+ })
1274
+ ```
1275
+
1141
1276
  ### `DealListItemSchema`
1142
1277
 
1143
1278
  ```typescript
@@ -1170,6 +1305,9 @@ export const DealListItemSchema = z.object({
1170
1305
  closed_lost_reason: z.string().nullable(),
1171
1306
  created_at: z.string(),
1172
1307
  updated_at: z.string(),
1308
+ priority: DealPrioritySchema,
1309
+ ownership: z.enum(['us', 'them']).nullable(),
1310
+ nextAction: z.string().nullable(),
1173
1311
  // joined relation
1174
1312
  contact: DealContactSummarySchema.nullable()
1175
1313
  })
@@ -1191,9 +1329,11 @@ export const DealListResponseSchema = z.object({
1191
1329
  ```typescript
1192
1330
  /**
1193
1331
  * Deal detail shape — currently the same as a list item (full joined record).
1194
- * useDealDetail returns DealDetail which is typed as DealListItem.
1332
+ * Additive fields keep existing DealListItem callers compatible.
1195
1333
  */
1196
- export const DealDetailResponseSchema = DealListItemSchema
1334
+ export const DealDetailResponseSchema = DealListItemSchema.extend({
1335
+ conversation: DealConversationSchema
1336
+ })
1197
1337
  ```
1198
1338
 
1199
1339
  ### `DealNoteResponseSchema`
@@ -1271,9 +1411,11 @@ export const DealSchemas = {
1271
1411
  ExecuteActionRequest: ExecuteActionRequestSchema,
1272
1412
 
1273
1413
  // Responses
1414
+ DealPriority: DealPrioritySchema,
1274
1415
  DealListResponse: DealListResponseSchema,
1275
1416
  DealSummaryResponse: DealSummaryResponseSchema,
1276
1417
  DealLookupResponse: DealLookupResponseSchema,
1418
+ ConversationMessage: ConversationMessageSchema,
1277
1419
  DealDetailResponse: DealDetailResponseSchema,
1278
1420
  DealNoteResponse: DealNoteResponseSchema,
1279
1421
  DealNoteListResponse: DealNoteListResponseSchema,
@@ -1285,10 +1427,10 @@ export const DealSchemas = {
1285
1427
  ### `Action`
1286
1428
 
1287
1429
  ```typescript
1288
- export interface Action {
1289
- key: string
1290
- label: string
1291
- payloadSchema?: z.ZodTypeAny
1430
+ export interface Action {
1431
+ key: string
1432
+ label: string
1433
+ payloadSchema?: z.ZodTypeAny
1292
1434
  }
1293
1435
  ```
1294
1436
 
@@ -1307,83 +1449,84 @@ export interface ActionDef {
1307
1449
  ### `DEFAULT_CRM_ACTIONS`
1308
1450
 
1309
1451
  ```typescript
1310
- export const DEFAULT_CRM_ACTIONS: ActionDef[] = [
1311
- {
1312
- key: 'move_to_proposal',
1313
- label: 'Move to Proposal',
1314
- isAvailableFor: (deal) => deal.stage_key === 'interested',
1315
- workflowId: 'move_to_proposal-workflow'
1316
- },
1317
- {
1318
- key: 'move_to_closing',
1319
- label: 'Move to Closing',
1320
- isAvailableFor: (deal) => deal.stage_key === 'proposal',
1321
- workflowId: 'move_to_closing-workflow'
1322
- },
1323
- {
1324
- key: 'move_to_closed_won',
1325
- label: 'Close Won',
1326
- isAvailableFor: (deal) => deal.stage_key === 'closing',
1327
- workflowId: 'move_to_closed_won-workflow'
1328
- },
1329
- {
1330
- key: 'move_to_closed_lost',
1331
- label: 'Close Lost',
1332
- isAvailableFor: (deal) =>
1333
- deal.stage_key === 'interested' || deal.stage_key === 'proposal' || deal.stage_key === 'closing',
1334
- workflowId: 'move_to_closed_lost-workflow'
1335
- },
1336
- {
1337
- key: 'move_to_nurturing',
1338
- label: 'Move to Nurturing',
1339
- isAvailableFor: (deal) =>
1340
- deal.stage_key === 'interested' || deal.stage_key === 'proposal' || deal.stage_key === 'closing',
1341
- workflowId: 'move_to_nurturing-workflow'
1342
- },
1343
- {
1452
+ export const DEFAULT_CRM_ACTIONS: ActionDef[] = [
1453
+ {
1454
+ key: 'move_to_proposal',
1455
+ label: 'Move to Proposal',
1456
+ isAvailableFor: (deal) => deal.stage_key === 'interested',
1457
+ workflowId: 'move_to_proposal-workflow'
1458
+ },
1459
+ {
1460
+ key: 'move_to_closing',
1461
+ label: 'Move to Closing',
1462
+ isAvailableFor: (deal) => deal.stage_key === 'proposal',
1463
+ workflowId: 'move_to_closing-workflow'
1464
+ },
1465
+ {
1466
+ key: 'move_to_closed_won',
1467
+ label: 'Close Won',
1468
+ isAvailableFor: (deal) => deal.stage_key === 'closing',
1469
+ workflowId: 'move_to_closed_won-workflow'
1470
+ },
1471
+ {
1472
+ key: 'move_to_closed_lost',
1473
+ label: 'Close Lost',
1474
+ isAvailableFor: (deal) =>
1475
+ deal.stage_key === 'interested' || deal.stage_key === 'proposal' || deal.stage_key === 'closing',
1476
+ workflowId: 'move_to_closed_lost-workflow'
1477
+ },
1478
+ {
1479
+ key: 'move_to_nurturing',
1480
+ label: 'Move to Nurturing',
1481
+ isAvailableFor: (deal) =>
1482
+ deal.stage_key === 'interested' || deal.stage_key === 'proposal' || deal.stage_key === 'closing',
1483
+ workflowId: 'move_to_nurturing-workflow'
1484
+ },
1485
+ {
1344
1486
  key: 'send_reply',
1345
1487
  label: 'Send Reply',
1346
1488
  isAvailableFor: (deal) =>
1347
1489
  deal.stage_key === 'interested' &&
1490
+ isOurReplyAction(deal) &&
1348
1491
  (deal.state_key === CRM_DISCOVERY_REPLIED_STATE.stateKey ||
1349
1492
  deal.state_key === CRM_DISCOVERY_LINK_SENT_STATE.stateKey ||
1350
1493
  deal.state_key === CRM_DISCOVERY_NUDGING_STATE.stateKey),
1351
- workflowId: 'crm-send-reply-workflow',
1352
- payloadSchema: SendReplyActionPayloadSchema
1353
- },
1354
- {
1355
- key: 'send_link',
1356
- label: 'Send Booking Link',
1357
- isAvailableFor: (deal) =>
1358
- deal.stage_key === 'interested' && deal.state_key === CRM_DISCOVERY_REPLIED_STATE.stateKey,
1359
- workflowId: 'crm-send-booking-link-workflow'
1360
- },
1361
- {
1362
- key: 'send_nudge',
1363
- label: 'Send Nudge',
1364
- isAvailableFor: (deal) =>
1365
- deal.stage_key === 'interested' &&
1366
- (deal.state_key === CRM_DISCOVERY_LINK_SENT_STATE.stateKey ||
1367
- deal.state_key === CRM_DISCOVERY_NUDGING_STATE.stateKey),
1368
- workflowId: 'crm-send-nudge-workflow'
1369
- },
1370
- {
1371
- key: 'mark_no_show',
1372
- label: 'Mark No-Show',
1373
- isAvailableFor: (deal) =>
1374
- deal.stage_key === 'interested' && deal.state_key === CRM_DISCOVERY_NUDGING_STATE.stateKey,
1375
- // Mirrors the auto-timeout precedent in operations/sales/crm/pipeline/timeout-actions.ts:
1376
- // both manual-click and timeout move the deal to closed_lost. The action_taken activity
1377
- // event captures operator intent and distinguishes the manual variant from the timed one.
1378
- workflowId: 'mark_no_show-workflow'
1379
- },
1380
- {
1381
- key: 'rebook',
1382
- label: 'Rebook',
1383
- isAvailableFor: (deal) =>
1384
- deal.stage_key === 'interested' && deal.state_key === CRM_DISCOVERY_BOOKING_CANCELLED_STATE.stateKey,
1385
- workflowId: 'crm-rebook-workflow'
1386
- }
1494
+ workflowId: 'crm-send-reply-workflow',
1495
+ payloadSchema: SendReplyActionPayloadSchema
1496
+ },
1497
+ {
1498
+ key: 'send_link',
1499
+ label: 'Send Booking Link',
1500
+ isAvailableFor: (deal) =>
1501
+ deal.stage_key === 'interested' && deal.state_key === CRM_DISCOVERY_REPLIED_STATE.stateKey,
1502
+ workflowId: 'crm-send-booking-link-workflow'
1503
+ },
1504
+ {
1505
+ key: 'send_nudge',
1506
+ label: 'Send Nudge',
1507
+ isAvailableFor: (deal) =>
1508
+ deal.stage_key === 'interested' &&
1509
+ (deal.state_key === CRM_DISCOVERY_LINK_SENT_STATE.stateKey ||
1510
+ deal.state_key === CRM_DISCOVERY_NUDGING_STATE.stateKey),
1511
+ workflowId: 'crm-send-nudge-workflow'
1512
+ },
1513
+ {
1514
+ key: 'mark_no_show',
1515
+ label: 'Mark No-Show',
1516
+ isAvailableFor: (deal) =>
1517
+ deal.stage_key === 'interested' && deal.state_key === CRM_DISCOVERY_NUDGING_STATE.stateKey,
1518
+ // Mirrors the auto-timeout precedent in operations/sales/crm/pipeline/timeout-actions.ts:
1519
+ // both manual-click and timeout move the deal to closed_lost. The action_taken activity
1520
+ // event captures operator intent and distinguishes the manual variant from the timed one.
1521
+ workflowId: 'mark_no_show-workflow'
1522
+ },
1523
+ {
1524
+ key: 'rebook',
1525
+ label: 'Rebook',
1526
+ isAvailableFor: (deal) =>
1527
+ deal.stage_key === 'interested' && deal.state_key === CRM_DISCOVERY_BOOKING_CANCELLED_STATE.stateKey,
1528
+ workflowId: 'crm-rebook-workflow'
1529
+ }
1387
1530
  ]
1388
1531
  ```
1389
1532
 
@@ -1411,263 +1554,263 @@ export type CrmToolMap = {
1411
1554
  ### `WebPost`
1412
1555
 
1413
1556
  ```typescript
1414
- /**
1415
- * Represents a web post from company website scraping.
1416
- * Used for recent blog posts, news, or announcements.
1417
- */
1418
- export interface WebPost {
1419
- /** ISO date string of when the post was published */
1420
- date: string
1421
- /** Title of the web post */
1422
- title: string
1423
- /** Brief summary of the post content */
1424
- summary: string
1425
- /** AI-generated insight about the post's relevance */
1426
- aiInsight?: string
1557
+ /**
1558
+ * Represents a web post from company website scraping.
1559
+ * Used for recent blog posts, news, or announcements.
1560
+ */
1561
+ export interface WebPost {
1562
+ /** ISO date string of when the post was published */
1563
+ date: string
1564
+ /** Title of the web post */
1565
+ title: string
1566
+ /** Brief summary of the post content */
1567
+ summary: string
1568
+ /** AI-generated insight about the post's relevance */
1569
+ aiInsight?: string
1427
1570
  }
1428
1571
  ```
1429
1572
 
1430
1573
  ### `CompanyPipelineStatus`
1431
1574
 
1432
1575
  ```typescript
1433
- /**
1434
- * Tracks pipeline status for a company across all processing stages.
1435
- */
1436
- export interface CompanyPipelineStatus {
1437
- acquired: boolean
1438
- enrichment: {
1439
- [source: string]: {
1440
- status: 'pending' | 'complete' | 'failed' | 'skipped'
1441
- completedAt?: string
1442
- error?: string
1443
- }
1444
- }
1576
+ /**
1577
+ * Tracks pipeline status for a company across all processing stages.
1578
+ */
1579
+ export interface CompanyPipelineStatus {
1580
+ acquired: boolean
1581
+ enrichment: {
1582
+ [source: string]: {
1583
+ status: 'pending' | 'complete' | 'failed' | 'skipped'
1584
+ completedAt?: string
1585
+ error?: string
1586
+ }
1587
+ }
1445
1588
  }
1446
1589
  ```
1447
1590
 
1448
1591
  ### `ContactPipelineStatus`
1449
1592
 
1450
1593
  ```typescript
1451
- /**
1452
- * Tracks pipeline status for a contact across all processing stages.
1453
- */
1454
- export interface ContactPipelineStatus {
1455
- enrichment: {
1456
- [source: string]: {
1457
- status: 'pending' | 'complete' | 'failed' | 'skipped'
1458
- completedAt?: string
1459
- error?: string
1460
- }
1461
- }
1462
- personalization: {
1463
- status: 'pending' | 'complete' | 'failed' | 'skipped'
1464
- completedAt?: string
1465
- }
1466
- outreach: {
1467
- status: 'pending' | 'sent' | 'replied' | 'bounced' | 'opted-out'
1468
- sentAt?: string
1469
- channel?: string
1470
- campaignId?: string
1471
- }
1594
+ /**
1595
+ * Tracks pipeline status for a contact across all processing stages.
1596
+ */
1597
+ export interface ContactPipelineStatus {
1598
+ enrichment: {
1599
+ [source: string]: {
1600
+ status: 'pending' | 'complete' | 'failed' | 'skipped'
1601
+ completedAt?: string
1602
+ error?: string
1603
+ }
1604
+ }
1605
+ personalization: {
1606
+ status: 'pending' | 'complete' | 'failed' | 'skipped'
1607
+ completedAt?: string
1608
+ }
1609
+ outreach: {
1610
+ status: 'pending' | 'sent' | 'replied' | 'bounced' | 'opted-out'
1611
+ sentAt?: string
1612
+ channel?: string
1613
+ campaignId?: string
1614
+ }
1472
1615
  }
1473
1616
  ```
1474
1617
 
1475
1618
  ### `CompanyEnrichmentData`
1476
1619
 
1477
1620
  ```typescript
1478
- /**
1479
- * Enrichment data collected for a company from various sources.
1480
- */
1481
- export interface CompanyEnrichmentData {
1482
- googleMaps?: {
1483
- placeId?: string
1484
- totalScore?: number
1485
- reviewsCount?: number
1486
- address?: string
1487
- phone?: string
1488
- categoryName?: string
1489
- googleMapsUrl?: string
1490
- scrapedAt?: string
1491
- }
1492
- websiteCrawl?: {
1493
- companyDescription?: string
1494
- services?: string[]
1495
- specialties?: string[]
1496
- staff?: Array<{ name: string; title?: string; email?: string }>
1497
- automationGaps?: string[]
1498
- targetAudience?: string
1499
- category?: string
1500
- segment?: string
1501
- recentWin?: string
1502
- emailCount?: number
1503
- pageCount?: number
1504
- totalChars?: number
1505
- crawledAt?: string
1506
- extractedAt?: string
1507
- }
1508
- website?: {
1509
- missionVision?: string
1510
- uniqueAttributes?: string
1511
- coreOfferings?: string
1512
- targetAudience?: string
1513
- companyValues?: string
1514
- businessDescription?: string
1515
- recentPosts?: Array<{ date?: string; title?: string; summary?: string; aiInsight?: string }>
1516
- }
1517
- tomba?: {
1518
- waterfallEmail?: {
1519
- email: string
1520
- name?: string
1521
- title?: string
1522
- department?: string
1523
- } | null
1524
- genericEmail?: string | null
1525
- totalFound?: number
1526
- searchedAt?: string
1527
- }
1621
+ /**
1622
+ * Enrichment data collected for a company from various sources.
1623
+ */
1624
+ export interface CompanyEnrichmentData {
1625
+ googleMaps?: {
1626
+ placeId?: string
1627
+ totalScore?: number
1628
+ reviewsCount?: number
1629
+ address?: string
1630
+ phone?: string
1631
+ categoryName?: string
1632
+ googleMapsUrl?: string
1633
+ scrapedAt?: string
1634
+ }
1635
+ websiteCrawl?: {
1636
+ companyDescription?: string
1637
+ services?: string[]
1638
+ specialties?: string[]
1639
+ staff?: Array<{ name: string; title?: string; email?: string }>
1640
+ automationGaps?: string[]
1641
+ targetAudience?: string
1642
+ category?: string
1643
+ segment?: string
1644
+ recentWin?: string
1645
+ emailCount?: number
1646
+ pageCount?: number
1647
+ totalChars?: number
1648
+ crawledAt?: string
1649
+ extractedAt?: string
1650
+ }
1651
+ website?: {
1652
+ missionVision?: string
1653
+ uniqueAttributes?: string
1654
+ coreOfferings?: string
1655
+ targetAudience?: string
1656
+ companyValues?: string
1657
+ businessDescription?: string
1658
+ recentPosts?: Array<{ date?: string; title?: string; summary?: string; aiInsight?: string }>
1659
+ }
1660
+ tomba?: {
1661
+ waterfallEmail?: {
1662
+ email: string
1663
+ name?: string
1664
+ title?: string
1665
+ department?: string
1666
+ } | null
1667
+ genericEmail?: string | null
1668
+ totalFound?: number
1669
+ searchedAt?: string
1670
+ }
1528
1671
  }
1529
1672
  ```
1530
1673
 
1531
1674
  ### `ContactEnrichmentData`
1532
1675
 
1533
1676
  ```typescript
1534
- /**
1535
- * Enrichment data collected for a contact from various sources.
1536
- */
1537
- export interface ContactEnrichmentData {
1538
- linkedin?: {
1539
- summary?: string
1540
- pastExperience?: string
1541
- education?: string
1542
- activity?: Array<{ date?: string; content?: string }>
1543
- }
1677
+ /**
1678
+ * Enrichment data collected for a contact from various sources.
1679
+ */
1680
+ export interface ContactEnrichmentData {
1681
+ linkedin?: {
1682
+ summary?: string
1683
+ pastExperience?: string
1684
+ education?: string
1685
+ activity?: Array<{ date?: string; content?: string }>
1686
+ }
1544
1687
  }
1545
1688
  ```
1546
1689
 
1547
1690
  ### `AcqList`
1548
1691
 
1549
1692
  ```typescript
1550
- export interface AcqList {
1551
- id: string
1552
- organizationId: string
1553
- name: string
1554
- description: string | null
1555
- batchIds: string[]
1556
- instantlyCampaignId: string | null
1557
- status: ListStatus
1558
- scrapingConfig: ScrapingConfig
1559
- icp: IcpRubric
1560
- pipelineConfig: PipelineConfig
1561
- metadata: Record<string, unknown>
1562
- launchedAt: Date | null
1563
- completedAt: Date | null
1564
- createdAt: Date
1693
+ export interface AcqList {
1694
+ id: string
1695
+ organizationId: string
1696
+ name: string
1697
+ description: string | null
1698
+ batchIds: string[]
1699
+ instantlyCampaignId: string | null
1700
+ status: ListStatus
1701
+ scrapingConfig: ScrapingConfig
1702
+ icp: IcpRubric
1703
+ pipelineConfig: PipelineConfig
1704
+ metadata: AcqListMetadata
1705
+ launchedAt: Date | null
1706
+ completedAt: Date | null
1707
+ createdAt: Date
1565
1708
  }
1566
1709
  ```
1567
1710
 
1568
1711
  ### `AcqCompany`
1569
1712
 
1570
1713
  ```typescript
1571
- /**
1572
- * Company record in the acquisition database.
1573
- * Contains enriched company data from various sources.
1574
- * Transformed from AcqCompanyRow with camelCase properties.
1575
- */
1576
- export interface AcqCompany {
1577
- id: string
1578
- organizationId: string
1579
- name: string
1580
- domain: string | null
1581
- linkedinUrl: string | null
1582
- website: string | null
1583
- numEmployees: number | null
1584
- foundedYear: number | null
1585
- locationCity: string | null
1586
- locationState: string | null
1587
- category: string | null
1588
- categoryPain: string | null
1589
- segment: string | null
1590
- pipelineStatus: CompanyPipelineStatus | null
1591
- enrichmentData: CompanyEnrichmentData | null
1592
- source: string | null
1593
- batchId: string | null
1594
- status: 'active' | 'invalid'
1595
- verticalResearch: string | null
1596
- /** Track A: flat qualification score (null until a scoring rubric is defined). Added by W1 migration. */
1597
- qualificationScore: number | null
1598
- /** Track A: flat qualification signals jsonb preserving the result payload shape. Added by W1 migration. */
1599
- qualificationSignals: Record<string, unknown> | null
1600
- /** Track A: key identifying the rubric used for qualification. Added by W1 migration. */
1601
- qualificationRubricKey: string | null
1602
- createdAt: Date
1603
- updatedAt: Date
1714
+ /**
1715
+ * Company record in the acquisition database.
1716
+ * Contains enriched company data from various sources.
1717
+ * Transformed from AcqCompanyRow with camelCase properties.
1718
+ */
1719
+ export interface AcqCompany {
1720
+ id: string
1721
+ organizationId: string
1722
+ name: string
1723
+ domain: string | null
1724
+ linkedinUrl: string | null
1725
+ website: string | null
1726
+ numEmployees: number | null
1727
+ foundedYear: number | null
1728
+ locationCity: string | null
1729
+ locationState: string | null
1730
+ category: string | null
1731
+ categoryPain: string | null
1732
+ segment: string | null
1733
+ pipelineStatus: CompanyPipelineStatus | null
1734
+ enrichmentData: CompanyEnrichmentData | null
1735
+ source: string | null
1736
+ batchId: string | null
1737
+ status: 'active' | 'invalid'
1738
+ verticalResearch: string | null
1739
+ /** Track A: flat qualification score (null until a scoring rubric is defined). Added by W1 migration. */
1740
+ qualificationScore: number | null
1741
+ /** Track A: flat qualification signals jsonb preserving the result payload shape. Added by W1 migration. */
1742
+ qualificationSignals: Record<string, unknown> | null
1743
+ /** Track A: key identifying the rubric used for qualification. Added by W1 migration. */
1744
+ qualificationRubricKey: string | null
1745
+ createdAt: Date
1746
+ updatedAt: Date
1604
1747
  }
1605
1748
  ```
1606
1749
 
1607
1750
  ### `AcqContact`
1608
1751
 
1609
1752
  ```typescript
1610
- /**
1611
- * Contact record in the acquisition database.
1612
- * Contains enriched contact data and personalization content.
1613
- * Transformed from AcqContactRow with camelCase properties.
1614
- */
1615
- export interface AcqContact {
1616
- id: string
1617
- organizationId: string
1618
- companyId: string | null
1619
- email: string
1620
- emailValid: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN' | null
1621
- firstName: string | null
1622
- lastName: string | null
1623
- linkedinUrl: string | null
1624
- title: string | null
1625
- headline: string | null
1626
- filterReason: string | null
1627
- openingLine: string | null
1628
- source: string | null
1629
- sourceId: string | null
1630
- pipelineStatus: ContactPipelineStatus | null
1631
- enrichmentData: ContactEnrichmentData | null
1632
- /** Attio Person record ID - set when contact responds and is added to CRM */
1633
- attioPersonId: string | null
1634
- batchId: string | null
1635
- status: 'active' | 'invalid'
1636
- createdAt: Date
1637
- updatedAt: Date
1753
+ /**
1754
+ * Contact record in the acquisition database.
1755
+ * Contains enriched contact data and personalization content.
1756
+ * Transformed from AcqContactRow with camelCase properties.
1757
+ */
1758
+ export interface AcqContact {
1759
+ id: string
1760
+ organizationId: string
1761
+ companyId: string | null
1762
+ email: string
1763
+ emailValid: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN' | null
1764
+ firstName: string | null
1765
+ lastName: string | null
1766
+ linkedinUrl: string | null
1767
+ title: string | null
1768
+ headline: string | null
1769
+ filterReason: string | null
1770
+ openingLine: string | null
1771
+ source: string | null
1772
+ sourceId: string | null
1773
+ pipelineStatus: ContactPipelineStatus | null
1774
+ enrichmentData: ContactEnrichmentData | null
1775
+ /** Attio Person record ID - set when contact responds and is added to CRM */
1776
+ attioPersonId: string | null
1777
+ batchId: string | null
1778
+ status: 'active' | 'invalid'
1779
+ createdAt: Date
1780
+ updatedAt: Date
1638
1781
  }
1639
1782
  ```
1640
1783
 
1641
1784
  ### `ListTelemetry`
1642
1785
 
1643
1786
  ```typescript
1644
- /**
1787
+ /**
1645
1788
  * Live-scan aggregate telemetry for a single list, computed on demand from
1646
1789
  * the list junction tables and current contact deliverability state.
1647
1790
  * `stageCounts` are attempted counts from list-row processing_state.
1648
1791
  */
1649
- export interface ListTelemetry {
1650
- listId: string
1651
- totalCompanies: number
1652
- totalContacts: number
1653
- stageCounts: {
1654
- populated: number
1655
- extracted: number
1656
- qualified: number
1657
- discovered: number
1658
- verified: number
1659
- personalized: number
1660
- uploaded: number
1661
- }
1662
- deliverability: {
1663
- valid: number
1664
- risky: number
1665
- invalid: number
1666
- unknown: number
1667
- bounced: number
1668
- }
1669
- /** Reserved -- active workflow IDs associated with this list. */
1670
- activeWorkflows?: string[]
1792
+ export interface ListTelemetry {
1793
+ listId: string
1794
+ totalCompanies: number
1795
+ totalContacts: number
1796
+ stageCounts: {
1797
+ populated: number
1798
+ extracted: number
1799
+ qualified: number
1800
+ discovered: number
1801
+ verified: number
1802
+ personalized: number
1803
+ uploaded: number
1804
+ }
1805
+ deliverability: {
1806
+ valid: number
1807
+ risky: number
1808
+ invalid: number
1809
+ unknown: number
1810
+ bounced: number
1811
+ }
1812
+ /** Reserved -- active workflow IDs associated with this list. */
1813
+ activeWorkflows?: string[]
1671
1814
  }
1672
1815
  ```
1673
1816
 
@@ -1725,6 +1868,7 @@ export const CreateListRequestSchema = z
1725
1868
  name: z.string().trim().min(1).max(255),
1726
1869
  description: z.string().trim().nullable().optional(),
1727
1870
  status: ListStatusSchema.optional(),
1871
+ buildTemplateId: ProspectingBuildTemplateIdSchema.optional(),
1728
1872
  scrapingConfig: ScrapingConfigSchema.optional(),
1729
1873
  icp: IcpRubricSchema.optional(),
1730
1874
  pipelineConfig: PipelineConfigSchema.optional()
@@ -1739,11 +1883,24 @@ export const UpdateListRequestSchema = z
1739
1883
  .object({
1740
1884
  name: z.string().trim().min(1).max(255).optional(),
1741
1885
  description: z.string().trim().nullable().optional(),
1742
- batchIds: z.array(z.string()).optional()
1886
+ batchIds: z.array(z.string()).optional(),
1887
+ buildTemplateId: ProspectingBuildTemplateIdSchema.optional(),
1888
+ confirmBuildTemplateChange: z.literal(true).optional()
1743
1889
  })
1744
1890
  .strict()
1745
- .refine((data) => data.name !== undefined || data.description !== undefined || data.batchIds !== undefined, {
1746
- message: 'At least one field (name, description, or batchIds) must be provided'
1891
+ .refine(
1892
+ (data) =>
1893
+ data.name !== undefined ||
1894
+ data.description !== undefined ||
1895
+ data.batchIds !== undefined ||
1896
+ data.buildTemplateId !== undefined,
1897
+ {
1898
+ message: 'At least one field (name, description, batchIds, or buildTemplateId) must be provided'
1899
+ }
1900
+ )
1901
+ .refine((data) => data.buildTemplateId === undefined || data.confirmBuildTemplateChange === true, {
1902
+ message: 'confirmBuildTemplateChange must be true when changing buildTemplateId',
1903
+ path: ['confirmBuildTemplateChange']
1747
1904
  })
1748
1905
  ```
1749
1906
 
@@ -1820,12 +1977,11 @@ export const AcqListResponseSchema = z.object({
1820
1977
  organizationId: z.string(),
1821
1978
  name: z.string(),
1822
1979
  description: z.string().nullable(),
1823
- type: z.string(),
1824
1980
  batchIds: z.array(z.string()),
1825
1981
  instantlyCampaignId: z.string().nullable(),
1826
1982
  /** Lifecycle status (draft | enriching | launched | closing | archived). */
1827
1983
  status: ListStatusSchema,
1828
- metadata: z.record(z.string(), z.unknown()),
1984
+ metadata: AcqListMetadataSchema,
1829
1985
  launchedAt: z.string().nullable(),
1830
1986
  completedAt: z.string().nullable(),
1831
1987
  createdAt: z.string(),
@@ -1869,7 +2025,8 @@ export const ListExecutionSummarySchema = z.object({
1869
2025
  status: z.string(),
1870
2026
  createdAt: z.string(),
1871
2027
  completedAt: z.string().nullable(),
1872
- durationMs: z.number().int().nullable()
2028
+ durationMs: z.number().int().nullable(),
2029
+ input: z.unknown().nullable().optional()
1873
2030
  })
1874
2031
  ```
1875
2032
 
@@ -2359,6 +2516,9 @@ export const AcqListSchemas = {
2359
2516
  IcpRubric: IcpRubricSchema,
2360
2517
  PipelineConfig: PipelineConfigSchema,
2361
2518
  PipelineStage: PipelineStageSchema,
2519
+ BuildPlanSnapshot: BuildPlanSnapshotSchema,
2520
+ BuildPlanSnapshotStep: BuildPlanSnapshotStepSchema,
2521
+ AcqListMetadata: AcqListMetadataSchema,
2362
2522
  ProcessingStageStatus: ProcessingStageStatusSchema,
2363
2523
  ListStageCounts: ListStageCountsSchema,
2364
2524
  ListTelemetry: ListTelemetrySchema,
@@ -2589,97 +2749,98 @@ export const LEAD_GEN_PIPELINE_DEFINITIONS: Record<string, StatefulPipelineDefin
2589
2749
  ### `PaginationParams`
2590
2750
 
2591
2751
  ```typescript
2592
- export interface PaginationParams {
2593
- limit: number
2594
- offset: number
2752
+ export interface PaginationParams {
2753
+ limit: number
2754
+ offset: number
2595
2755
  }
2596
2756
  ```
2597
2757
 
2598
2758
  ### `PaginatedResult`
2599
2759
 
2600
2760
  ```typescript
2601
- export interface PaginatedResult<T> {
2602
- data: T[]
2603
- total: number
2604
- limit: number
2605
- offset: number
2761
+ export interface PaginatedResult<T> {
2762
+ data: T[]
2763
+ total: number
2764
+ limit: number
2765
+ offset: number
2606
2766
  }
2607
2767
  ```
2608
2768
 
2609
2769
  ### `CreateListParams`
2610
2770
 
2611
2771
  ```typescript
2612
- export interface CreateListParams {
2613
- organizationId: string
2614
- name: string
2615
- description?: string
2616
- type?: string
2617
- batchIds?: string[]
2618
- instantlyCampaignId?: string
2619
- status?: ListStatus
2620
- metadata?: Record<string, unknown>
2621
- scrapingConfig?: ScrapingConfig
2622
- icp?: IcpRubric
2623
- pipelineConfig?: PipelineConfig
2772
+ export interface CreateListParams {
2773
+ organizationId: string
2774
+ name: string
2775
+ description?: string
2776
+ type?: string
2777
+ batchIds?: string[]
2778
+ instantlyCampaignId?: string
2779
+ status?: ListStatus
2780
+ buildTemplateId?: string
2781
+ metadata?: Record<string, unknown>
2782
+ scrapingConfig?: ScrapingConfig
2783
+ icp?: IcpRubric
2784
+ pipelineConfig?: PipelineConfig
2624
2785
  }
2625
2786
  ```
2626
2787
 
2627
2788
  ### `UpdateListParams`
2628
2789
 
2629
2790
  ```typescript
2630
- export interface UpdateListParams {
2631
- name?: string
2632
- description?: string
2633
- batchIds?: string[]
2791
+ export interface UpdateListParams {
2792
+ name?: string
2793
+ description?: string
2794
+ batchIds?: string[]
2634
2795
  }
2635
2796
  ```
2636
2797
 
2637
2798
  ### `CreateCompanyParams`
2638
2799
 
2639
2800
  ```typescript
2640
- export interface CreateCompanyParams {
2641
- organizationId: string
2642
- name: string
2643
- domain?: string
2644
- linkedinUrl?: string
2645
- website?: string
2646
- numEmployees?: number
2647
- foundedYear?: number
2648
- locationCity?: string
2649
- locationState?: string
2650
- category?: string
2651
- source?: string
2652
- batchId?: string
2653
- verticalResearch?: string
2801
+ export interface CreateCompanyParams {
2802
+ organizationId: string
2803
+ name: string
2804
+ domain?: string
2805
+ linkedinUrl?: string
2806
+ website?: string
2807
+ numEmployees?: number
2808
+ foundedYear?: number
2809
+ locationCity?: string
2810
+ locationState?: string
2811
+ category?: string
2812
+ source?: string
2813
+ batchId?: string
2814
+ verticalResearch?: string
2654
2815
  }
2655
2816
  ```
2656
2817
 
2657
2818
  ### `UpdateCompanyParams`
2658
2819
 
2659
2820
  ```typescript
2660
- export interface UpdateCompanyParams {
2661
- name?: string
2662
- domain?: string
2663
- linkedinUrl?: string
2664
- website?: string
2665
- numEmployees?: number
2666
- foundedYear?: number
2667
- locationCity?: string
2668
- locationState?: string
2669
- category?: string
2670
- segment?: string
2671
- pipelineStatus?: Record<string, unknown>
2672
- enrichmentData?: Record<string, unknown>
2673
- source?: string
2674
- batchId?: string
2675
- status?: 'active' | 'invalid'
2676
- verticalResearch?: string | null
2677
- /** Track A: flat qualification score column (null until a scoring rubric is defined) */
2678
- qualificationScore?: number | null
2679
- /** Track A: flat qualification signals jsonb — mirrors the former pipeline_status.qualification shape */
2680
- qualificationSignals?: Record<string, unknown> | null
2681
- /** Track A: key identifying the rubric used for qualification */
2682
- qualificationRubricKey?: string | null
2821
+ export interface UpdateCompanyParams {
2822
+ name?: string
2823
+ domain?: string
2824
+ linkedinUrl?: string
2825
+ website?: string
2826
+ numEmployees?: number
2827
+ foundedYear?: number
2828
+ locationCity?: string
2829
+ locationState?: string
2830
+ category?: string
2831
+ segment?: string
2832
+ pipelineStatus?: Record<string, unknown>
2833
+ enrichmentData?: Record<string, unknown>
2834
+ source?: string
2835
+ batchId?: string
2836
+ status?: 'active' | 'invalid'
2837
+ verticalResearch?: string | null
2838
+ /** Track A: flat qualification score column (null until a scoring rubric is defined) */
2839
+ qualificationScore?: number | null
2840
+ /** Track A: flat qualification signals jsonb — mirrors the former pipeline_status.qualification shape */
2841
+ qualificationSignals?: Record<string, unknown> | null
2842
+ /** Track A: key identifying the rubric used for qualification */
2843
+ qualificationRubricKey?: string | null
2683
2844
  }
2684
2845
  ```
2685
2846
 
@@ -2692,56 +2853,57 @@ export type UpsertCompanyParams = CreateCompanyParams
2692
2853
  ### `CompanyFilters`
2693
2854
 
2694
2855
  ```typescript
2695
- export interface CompanyFilters {
2696
- listId?: string // Filter to companies in a specific list (via acq_list_companies)
2697
- search?: string
2698
- domain?: string
2699
- website?: string
2700
- segment?: string
2701
- category?: string
2702
- pipelineStatus?: Record<string, unknown>
2703
- /** Exclude companies whose pipeline_status contains this value (PostgREST NOT contains) */
2704
- pipelineStatusNot?: Record<string, unknown>
2705
- batchId?: string
2706
- status?: 'active' | 'invalid'
2707
- includeAll?: boolean
2708
- excludeColumns?: Array<'enrichmentData' | 'pipelineStatus'>
2856
+ export interface CompanyFilters {
2857
+ listId?: string // Filter to companies in a specific list (via acq_list_companies)
2858
+ search?: string
2859
+ domain?: string
2860
+ website?: string
2861
+ segment?: string
2862
+ category?: string
2863
+ pipelineStatus?: Record<string, unknown>
2864
+ /** Exclude companies whose pipeline_status contains this value (PostgREST NOT contains) */
2865
+ pipelineStatusNot?: Record<string, unknown>
2866
+ batchId?: string
2867
+ status?: 'active' | 'invalid'
2868
+ includeAll?: boolean
2869
+ excludeColumns?: Array<'enrichmentData' | 'pipelineStatus'>
2870
+ limit?: number
2709
2871
  }
2710
2872
  ```
2711
2873
 
2712
2874
  ### `CreateContactParams`
2713
2875
 
2714
2876
  ```typescript
2715
- export interface CreateContactParams {
2716
- organizationId: string
2717
- email: string
2718
- companyId?: string
2719
- firstName?: string
2720
- lastName?: string
2721
- linkedinUrl?: string
2722
- title?: string
2723
- source?: string
2724
- sourceId?: string
2725
- batchId?: string
2877
+ export interface CreateContactParams {
2878
+ organizationId: string
2879
+ email: string
2880
+ companyId?: string
2881
+ firstName?: string
2882
+ lastName?: string
2883
+ linkedinUrl?: string
2884
+ title?: string
2885
+ source?: string
2886
+ sourceId?: string
2887
+ batchId?: string
2726
2888
  }
2727
2889
  ```
2728
2890
 
2729
2891
  ### `UpdateContactParams`
2730
2892
 
2731
2893
  ```typescript
2732
- export interface UpdateContactParams {
2733
- companyId?: string
2734
- emailValid?: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN'
2735
- firstName?: string
2736
- lastName?: string
2737
- linkedinUrl?: string
2738
- title?: string
2739
- headline?: string
2740
- filterReason?: string
2741
- openingLine?: string
2742
- pipelineStatus?: Record<string, unknown>
2743
- enrichmentData?: Record<string, unknown>
2744
- status?: 'active' | 'invalid'
2894
+ export interface UpdateContactParams {
2895
+ companyId?: string
2896
+ emailValid?: 'VALID' | 'INVALID' | 'RISKY' | 'UNKNOWN'
2897
+ firstName?: string
2898
+ lastName?: string
2899
+ linkedinUrl?: string
2900
+ title?: string
2901
+ headline?: string
2902
+ filterReason?: string
2903
+ openingLine?: string
2904
+ pipelineStatus?: Record<string, unknown>
2905
+ enrichmentData?: Record<string, unknown>
2906
+ status?: 'active' | 'invalid'
2745
2907
  }
2746
2908
  ```
2747
2909
 
@@ -2754,87 +2916,87 @@ export type UpsertContactParams = CreateContactParams
2754
2916
  ### `ContactFilters`
2755
2917
 
2756
2918
  ```typescript
2757
- export interface ContactFilters {
2758
- listId?: string // Filter to contacts in a specific list (via acq_list_members)
2759
- search?: string
2760
- openingLineIsNull?: boolean // Filter to contacts without personalization
2761
- pipelineStatus?: Record<string, unknown>
2762
- batchId?: string
2763
- contactStatus?: 'active' | 'invalid' // Filter by contact status (soft-delete flag)
2919
+ export interface ContactFilters {
2920
+ listId?: string // Filter to contacts in a specific list (via acq_list_members)
2921
+ search?: string
2922
+ openingLineIsNull?: boolean // Filter to contacts without personalization
2923
+ pipelineStatus?: Record<string, unknown>
2924
+ batchId?: string
2925
+ contactStatus?: 'active' | 'invalid' // Filter by contact status (soft-delete flag)
2764
2926
  }
2765
2927
  ```
2766
2928
 
2767
2929
  ### `UpsertSocialPostParams`
2768
2930
 
2769
2931
  ```typescript
2770
- export interface UpsertSocialPostParams {
2771
- organizationId: string
2772
- platform: string
2773
- platformPostId: string
2774
- authorName: string
2775
- authorUrl?: string | null
2776
- postTitle: string
2777
- postText: string
2778
- postUrl: string
2779
- engagementCount?: number
2780
- commentsCount?: number
2781
- postedAt: string
2782
- metadata?: Record<string, unknown>
2783
- relevanceScore?: number
2784
- matchedKeywords?: string[]
2785
- matchedQuery?: string | null
2786
- initialDraft?: string | null
2787
- finalResponse?: string | null
2788
- sourceCategory?: string | null
2932
+ export interface UpsertSocialPostParams {
2933
+ organizationId: string
2934
+ platform: string
2935
+ platformPostId: string
2936
+ authorName: string
2937
+ authorUrl?: string | null
2938
+ postTitle: string
2939
+ postText: string
2940
+ postUrl: string
2941
+ engagementCount?: number
2942
+ commentsCount?: number
2943
+ postedAt: string
2944
+ metadata?: Record<string, unknown>
2945
+ relevanceScore?: number
2946
+ matchedKeywords?: string[]
2947
+ matchedQuery?: string | null
2948
+ initialDraft?: string | null
2949
+ finalResponse?: string | null
2950
+ sourceCategory?: string | null
2789
2951
  }
2790
2952
  ```
2791
2953
 
2792
2954
  ### `UpsertSocialPostsParams`
2793
2955
 
2794
2956
  ```typescript
2795
- export interface UpsertSocialPostsParams {
2796
- organizationId: string
2797
- posts: Omit<UpsertSocialPostParams, 'organizationId'>[]
2957
+ export interface UpsertSocialPostsParams {
2958
+ organizationId: string
2959
+ posts: Omit<UpsertSocialPostParams, 'organizationId'>[]
2798
2960
  }
2799
2961
  ```
2800
2962
 
2801
2963
  ### `UpsertSocialPostsResult`
2802
2964
 
2803
2965
  ```typescript
2804
- export interface UpsertSocialPostsResult {
2805
- inserted: number
2806
- duplicatesSkipped: number
2966
+ export interface UpsertSocialPostsResult {
2967
+ inserted: number
2968
+ duplicatesSkipped: number
2807
2969
  }
2808
2970
  ```
2809
2971
 
2810
2972
  ### `AddContactsToListParams`
2811
2973
 
2812
2974
  ```typescript
2813
- export interface AddContactsToListParams {
2814
- organizationId: string
2815
- listId: string
2816
- contactIds: string[]
2975
+ export interface AddContactsToListParams {
2976
+ organizationId: string
2977
+ listId: string
2978
+ contactIds: string[]
2817
2979
  }
2818
2980
  ```
2819
2981
 
2820
2982
  ### `AddContactsToListResult`
2821
2983
 
2822
2984
  ```typescript
2823
- export interface AddContactsToListResult {
2824
- added: number
2825
- alreadyExisted: number
2985
+ export interface AddContactsToListResult {
2986
+ added: number
2987
+ alreadyExisted: number
2826
2988
  }
2827
2989
  ```
2828
2990
 
2829
2991
  ### `UpdateListConfigParams`
2830
2992
 
2831
2993
  ```typescript
2832
- export interface UpdateListConfigParams {
2833
- organizationId: string
2834
- listId: string
2835
- scrapingConfig?: ScrapingConfig
2836
- icp?: IcpRubric
2837
- pipelineConfig?: PipelineConfig
2994
+ export interface UpdateListConfigParams {
2995
+ organizationId: string
2996
+ listId: string
2997
+ scrapingConfig?: ScrapingConfig
2998
+ icp?: IcpRubric
2999
+ pipelineConfig?: PipelineConfig
2838
3000
  }
2839
3001
  ```
2840
3002
 
@@ -2867,117 +3029,117 @@ export interface UpdateContactStageParams {
2867
3029
  ### `AddCompaniesToListParams`
2868
3030
 
2869
3031
  ```typescript
2870
- export interface AddCompaniesToListParams {
2871
- organizationId: string
2872
- listId: string
2873
- companyIds: string[]
3032
+ export interface AddCompaniesToListParams {
3033
+ organizationId: string
3034
+ listId: string
3035
+ companyIds: string[]
2874
3036
  }
2875
3037
  ```
2876
3038
 
2877
3039
  ### `AddCompaniesToListResult`
2878
3040
 
2879
3041
  ```typescript
2880
- export interface AddCompaniesToListResult {
2881
- added: number
2882
- alreadyExisted: number
3042
+ export interface AddCompaniesToListResult {
3043
+ added: number
3044
+ alreadyExisted: number
2883
3045
  }
2884
3046
  ```
2885
3047
 
2886
3048
  ### `RemoveCompaniesFromListParams`
2887
3049
 
2888
3050
  ```typescript
2889
- export interface RemoveCompaniesFromListParams {
2890
- organizationId: string
2891
- listId: string
2892
- companyIds: string[]
3051
+ export interface RemoveCompaniesFromListParams {
3052
+ organizationId: string
3053
+ listId: string
3054
+ companyIds: string[]
2893
3055
  }
2894
3056
  ```
2895
3057
 
2896
3058
  ### `RemoveCompaniesFromListResult`
2897
3059
 
2898
3060
  ```typescript
2899
- export interface RemoveCompaniesFromListResult {
2900
- removed: number
3061
+ export interface RemoveCompaniesFromListResult {
3062
+ removed: number
2901
3063
  }
2902
3064
  ```
2903
3065
 
2904
3066
  ### `RecordListExecutionParams`
2905
3067
 
2906
3068
  ```typescript
2907
- export interface RecordListExecutionParams {
2908
- organizationId: string
2909
- listId: string
2910
- executionId: string
2911
- configSnapshot?: Record<string, unknown>
3069
+ export interface RecordListExecutionParams {
3070
+ organizationId: string
3071
+ listId: string
3072
+ executionId: string
3073
+ configSnapshot?: Record<string, unknown>
2912
3074
  }
2913
3075
  ```
2914
3076
 
2915
3077
  ### `ListExecutionSummary`
2916
3078
 
2917
3079
  ```typescript
2918
- export interface ListExecutionSummary {
2919
- executionId: string
2920
- resourceId: string
2921
- status: string
2922
- createdAt: string
2923
- completedAt: string | null
2924
- durationMs: number | null
3080
+ export interface ListExecutionSummary {
3081
+ executionId: string
3082
+ resourceId: string
3083
+ status: string
3084
+ createdAt: string
3085
+ completedAt: string | null
3086
+ durationMs: number | null
2925
3087
  }
2926
3088
  ```
2927
3089
 
2928
3090
  ### `BulkImportParams`
2929
3091
 
2930
3092
  ```typescript
2931
- export interface BulkImportParams {
2932
- organizationId: string
2933
- contacts: CreateContactParams[]
2934
- listId?: string
3093
+ export interface BulkImportParams {
3094
+ organizationId: string
3095
+ contacts: CreateContactParams[]
3096
+ listId?: string
2935
3097
  }
2936
3098
  ```
2937
3099
 
2938
3100
  ### `BulkImportResult`
2939
3101
 
2940
3102
  ```typescript
2941
- export interface BulkImportResult {
2942
- created: number
2943
- updated: number
2944
- errors: Array<{ email: string; error: string }>
3103
+ export interface BulkImportResult {
3104
+ created: number
3105
+ updated: number
3106
+ errors: Array<{ email: string; error: string }>
2945
3107
  }
2946
3108
  ```
2947
3109
 
2948
3110
  ### `BulkImportCompanyEntry`
2949
3111
 
2950
3112
  ```typescript
2951
- export interface BulkImportCompanyEntry {
2952
- name: string
2953
- domain: string
2954
- website?: string
2955
- locationCity?: string
2956
- locationState?: string
2957
- category?: string
2958
- source?: string
2959
- enrichmentData?: Record<string, unknown>
2960
- pipelineStatus?: Record<string, unknown>
3113
+ export interface BulkImportCompanyEntry {
3114
+ name: string
3115
+ domain: string
3116
+ website?: string
3117
+ locationCity?: string
3118
+ locationState?: string
3119
+ category?: string
3120
+ source?: string
3121
+ enrichmentData?: Record<string, unknown>
3122
+ pipelineStatus?: Record<string, unknown>
2961
3123
  }
2962
3124
  ```
2963
3125
 
2964
3126
  ### `BulkImportCompaniesParams`
2965
3127
 
2966
3128
  ```typescript
2967
- export interface BulkImportCompaniesParams {
2968
- organizationId: string
2969
- batchId: string
2970
- companies: BulkImportCompanyEntry[]
3129
+ export interface BulkImportCompaniesParams {
3130
+ organizationId: string
3131
+ batchId: string
3132
+ companies: BulkImportCompanyEntry[]
2971
3133
  }
2972
3134
  ```
2973
3135
 
2974
3136
  ### `BulkImportCompaniesResult`
2975
3137
 
2976
3138
  ```typescript
2977
- export interface BulkImportCompaniesResult {
2978
- created: number
2979
- skipped: number
2980
- errors: Array<{ companyName: string; error: string }>
3139
+ export interface BulkImportCompaniesResult {
3140
+ created: number
3141
+ skipped: number
3142
+ errors: Array<{ companyName: string; error: string }>
2981
3143
  }
2982
3144
  ```
2983
3145
 
@@ -3042,6 +3204,7 @@ export type LeadToolMap = {
3042
3204
  markProposalReviewed: { params: Omit<MarkProposalReviewedParams, 'organizationId'>; result: void }
3043
3205
  updateCloseLostReason: { params: Omit<UpdateCloseLostReasonParams, 'organizationId'>; result: void }
3044
3206
  updateFees: { params: Omit<UpdateFeesParams, 'organizationId'>; result: void }
3207
+ cacheInstantlyThreadIds: { params: Omit<CacheInstantlyThreadIdsParams, 'organizationId'>; result: void }
3045
3208
  transitionItem: { params: Omit<TransitionItemParams, 'organizationId'>; result: void }
3046
3209
  setContactNurture: { params: Omit<SetContactNurtureParams, 'organizationId'>; result: void }
3047
3210
  cancelSchedulesAndHitlByEmail: {
@@ -3139,3 +3302,74 @@ export type ListToolMap = {
3139
3302
  }
3140
3303
  }
3141
3304
  ```
3305
+
3306
+ ## Knowledge Platform Primitives
3307
+
3308
+ ### `KnowledgeLinkSchema`
3309
+
3310
+ ```typescript
3311
+ export const KnowledgeLinkSchema = z.object({
3312
+ nodeId: NodeIdStringSchema
3313
+ })
3314
+ ```
3315
+
3316
+ ### `OrgKnowledgeKindSchema`
3317
+
3318
+ ```typescript
3319
+ export const OrgKnowledgeKindSchema = z.enum(['playbook', 'strategy', 'reference'])
3320
+ ```
3321
+
3322
+ ### `OrgKnowledgeNodeSchema`
3323
+
3324
+ ```typescript
3325
+ export const OrgKnowledgeNodeSchema = z.object({
3326
+ id: ModelIdSchema,
3327
+ kind: OrgKnowledgeKindSchema,
3328
+ title: z.string().trim().min(1).max(200),
3329
+ summary: z.string().trim().min(1).max(1000),
3330
+ icon: IconNameSchema.optional(),
3331
+ /** Raw MDX string. Phase 2 will introduce a structured block format. */
3332
+ body: z.string().trim().min(1),
3333
+ /**
3334
+ * Graph links to other OM nodes this knowledge node governs.
3335
+ * Each link emits a `governs` edge: knowledge-node -> target node.
3336
+ */
3337
+ links: z.array(KnowledgeLinkSchema).default([]),
3338
+ /** Identifiers of the roles or members who own this knowledge node. */
3339
+ ownerIds: z.array(ModelIdSchema).default([]),
3340
+ /** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
3341
+ updatedAt: z.string().trim().min(1).max(50)
3342
+ })
3343
+ ```
3344
+
3345
+ ### `KnowledgeDomainSchema`
3346
+
3347
+ ```typescript
3348
+ export const KnowledgeDomainSchema = z.object({
3349
+ nodes: z.array(OrgKnowledgeNodeSchema).default([])
3350
+ })
3351
+ ```
3352
+
3353
+ ### `OrgKnowledgeNode`
3354
+
3355
+ ```typescript
3356
+ export type OrgKnowledgeNode = z.infer<typeof OrgKnowledgeNodeSchema>
3357
+ ```
3358
+
3359
+ ### `OrgKnowledgeKind`
3360
+
3361
+ ```typescript
3362
+ export type OrgKnowledgeKind = z.infer<typeof OrgKnowledgeKindSchema>
3363
+ ```
3364
+
3365
+ ### `KnowledgeLink`
3366
+
3367
+ ```typescript
3368
+ export type KnowledgeLink = z.infer<typeof KnowledgeLinkSchema>
3369
+ ```
3370
+
3371
+ ### `KnowledgeDomain`
3372
+
3373
+ ```typescript
3374
+ export type KnowledgeDomain = z.infer<typeof KnowledgeDomainSchema>
3375
+ ```