@elevasis/sdk 1.20.2 → 1.21.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 (58) hide show
  1. package/dist/cli.cjs +3386 -1529
  2. package/dist/index.d.ts +412 -149
  3. package/dist/index.js +955 -721
  4. package/dist/node/index.d.ts +0 -3
  5. package/dist/node/index.js +21 -48
  6. package/dist/test-utils/index.d.ts +395 -128
  7. package/dist/test-utils/index.js +599 -368
  8. package/dist/worker/index.js +536 -323
  9. package/package.json +2 -2
  10. package/reference/_navigation.md +9 -7
  11. package/reference/_reference-manifest.json +1 -1
  12. package/reference/claude-config/rules/agent-start-here.md +4 -0
  13. package/reference/claude-config/rules/frontend.md +2 -2
  14. package/reference/claude-config/rules/organization-model.md +44 -2
  15. package/reference/claude-config/rules/organization-os.md +12 -12
  16. package/reference/claude-config/rules/ui.md +14 -14
  17. package/reference/claude-config/rules/vibe.md +37 -33
  18. package/reference/claude-config/skills/explore/SKILL.md +6 -6
  19. package/reference/claude-config/skills/knowledge/SKILL.md +73 -29
  20. package/reference/claude-config/skills/knowledge/operations/codify-level-a.md +1 -1
  21. package/reference/claude-config/skills/knowledge/operations/codify-level-b.md +25 -24
  22. package/reference/claude-config/skills/knowledge/operations/features.md +56 -93
  23. package/reference/claude-config/skills/knowledge/operations/labels.md +19 -14
  24. package/reference/claude-config/skills/knowledge/operations/offerings.md +6 -6
  25. package/reference/claude-config/skills/save/SKILL.md +2 -2
  26. package/reference/claude-config/skills/setup/SKILL.md +1 -1
  27. package/reference/claude-config/skills/tutorial/technical.md +23 -26
  28. package/reference/claude-config/skills/tutorial/vibe-coder.md +9 -9
  29. package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +30 -0
  30. package/reference/cli.mdx +140 -0
  31. package/reference/deployment/provided-features.mdx +29 -15
  32. package/reference/examples/organization-model.ts +1 -1
  33. package/reference/packages/core/src/knowledge/README.md +8 -7
  34. package/reference/packages/core/src/organization-model/README.md +66 -26
  35. package/reference/packages/ui/src/provider/README.md +5 -5
  36. package/reference/scaffold/core/organization-graph.mdx +16 -15
  37. package/reference/scaffold/core/organization-model.mdx +89 -41
  38. package/reference/scaffold/index.mdx +9 -9
  39. package/reference/scaffold/operations/propagation-pipeline.md +3 -3
  40. package/reference/scaffold/operations/scaffold-maintenance.md +11 -11
  41. package/reference/scaffold/recipes/add-a-feature.md +26 -24
  42. package/reference/scaffold/recipes/add-a-resource.md +10 -14
  43. package/reference/scaffold/recipes/customize-crm-actions.md +439 -439
  44. package/reference/scaffold/recipes/customize-knowledge-browser.md +384 -0
  45. package/reference/scaffold/recipes/customize-organization-model.md +72 -44
  46. package/reference/scaffold/recipes/extend-crm.md +40 -39
  47. package/reference/scaffold/recipes/extend-lead-gen.md +15 -16
  48. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +34 -30
  49. package/reference/scaffold/recipes/index.md +13 -12
  50. package/reference/scaffold/recipes/query-the-knowledge-graph.md +200 -0
  51. package/reference/scaffold/reference/contracts.md +362 -99
  52. package/reference/scaffold/reference/feature-registry.md +9 -20
  53. package/reference/scaffold/reference/glossary.md +18 -18
  54. package/reference/scaffold/ui/composition-extensibility.mdx +23 -23
  55. package/reference/scaffold/ui/customization.md +11 -11
  56. package/reference/scaffold/ui/feature-flags-and-gating.md +8 -8
  57. package/reference/scaffold/ui/feature-shell.mdx +19 -19
  58. package/reference/scaffold/ui/recipes.md +29 -28
@@ -4714,188 +4714,327 @@ DisplayMetadataSchema.extend({
4714
4714
  id: ModelIdSchema,
4715
4715
  resourceId: z.string().trim().min(1).max(255),
4716
4716
  resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
4717
- featureIds: ReferenceIdsSchema,
4717
+ systemIds: ReferenceIdsSchema,
4718
4718
  entityIds: ReferenceIdsSchema,
4719
4719
  surfaceIds: ReferenceIdsSchema,
4720
- capabilityIds: ReferenceIdsSchema,
4720
+ actionIds: ReferenceIdsSchema,
4721
4721
  /** Optional tech-stack metadata for external-SaaS integrations. */
4722
4722
  techStack: TechStackEntrySchema.optional()
4723
4723
  });
4724
4724
 
4725
- // ../core/src/organization-model/domains/sales.ts
4726
- var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
4727
- var SalesStageSchema = DisplayMetadataSchema.extend({
4728
- id: ModelIdSchema,
4729
- order: z.number().int().min(0),
4730
- semanticClass: SalesStageSemanticClassSchema,
4731
- surfaceIds: ReferenceIdsSchema,
4732
- resourceIds: ReferenceIdsSchema
4725
+ // ../core/src/organization-model/domains/entities.ts
4726
+ var EntityIdSchema = ModelIdSchema;
4727
+ var EntityLinkKindSchema = z.enum(["belongs-to", "has-many", "has-one", "many-to-many"]).meta({ label: "Link kind" });
4728
+ var EntityLinkSchema = z.object({
4729
+ toEntity: EntityIdSchema.meta({ ref: "entity" }),
4730
+ kind: EntityLinkKindSchema,
4731
+ via: z.string().trim().min(1).max(255).optional(),
4732
+ label: LabelSchema.optional()
4733
4733
  });
4734
- var SalesPipelineSchema = z.object({
4735
- id: ModelIdSchema,
4736
- label: z.string().trim().min(1).max(120),
4734
+ var EntitySchema = z.object({
4735
+ id: EntityIdSchema,
4736
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
4737
+ order: z.number(),
4738
+ label: LabelSchema,
4737
4739
  description: DescriptionSchema.optional(),
4738
- entityId: ModelIdSchema,
4739
- stages: z.array(SalesStageSchema).min(1)
4740
+ ownedBySystemId: ModelIdSchema.meta({ ref: "system" }),
4741
+ table: z.string().trim().min(1).max(255).optional(),
4742
+ rowSchema: ModelIdSchema.optional(),
4743
+ stateCatalogId: ModelIdSchema.optional(),
4744
+ links: z.array(EntityLinkSchema).optional()
4740
4745
  });
4746
+ z.record(z.string(), EntitySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
4747
+ message: "Each entity entry id must match its map key"
4748
+ }).default({});
4749
+ var ENTITY_ENTRY_INPUTS = [
4750
+ {
4751
+ id: "crm.deal",
4752
+ order: 10,
4753
+ label: "Deal",
4754
+ description: "A CRM opportunity or sales pipeline record.",
4755
+ ownedBySystemId: "sales.crm",
4756
+ table: "crm_deals",
4757
+ stateCatalogId: "crm.pipeline",
4758
+ links: [{ toEntity: "crm.contact", kind: "has-many", via: "deal_contacts", label: "contacts" }]
4759
+ },
4760
+ {
4761
+ id: "crm.contact",
4762
+ order: 20,
4763
+ label: "CRM Contact",
4764
+ description: "A person associated with a CRM relationship or deal.",
4765
+ ownedBySystemId: "sales.crm",
4766
+ table: "crm_contacts"
4767
+ },
4768
+ {
4769
+ id: "leadgen.list",
4770
+ order: 30,
4771
+ label: "Lead List",
4772
+ description: "A prospecting list that groups companies and contacts for acquisition workflows.",
4773
+ ownedBySystemId: "sales.lead-gen",
4774
+ table: "acq_lists",
4775
+ links: [
4776
+ { toEntity: "leadgen.company", kind: "has-many", via: "acq_list_companies", label: "companies" },
4777
+ { toEntity: "leadgen.contact", kind: "has-many", via: "acq_list_members", label: "contacts" }
4778
+ ]
4779
+ },
4780
+ {
4781
+ id: "leadgen.company",
4782
+ order: 40,
4783
+ label: "Lead Company",
4784
+ description: "A company record sourced, enriched, and qualified during prospecting.",
4785
+ ownedBySystemId: "sales.lead-gen",
4786
+ table: "acq_list_companies",
4787
+ stateCatalogId: "lead-gen.company",
4788
+ links: [
4789
+ { toEntity: "leadgen.list", kind: "belongs-to", via: "list_id", label: "list" },
4790
+ { toEntity: "leadgen.contact", kind: "has-many", via: "company_id", label: "contacts" }
4791
+ ]
4792
+ },
4793
+ {
4794
+ id: "leadgen.contact",
4795
+ order: 50,
4796
+ label: "Lead Contact",
4797
+ description: "A prospect contact discovered or enriched during lead generation.",
4798
+ ownedBySystemId: "sales.lead-gen",
4799
+ table: "acq_list_members",
4800
+ stateCatalogId: "lead-gen.contact",
4801
+ links: [
4802
+ { toEntity: "leadgen.list", kind: "belongs-to", via: "list_id", label: "list" },
4803
+ { toEntity: "leadgen.company", kind: "belongs-to", via: "company_id", label: "company" }
4804
+ ]
4805
+ },
4806
+ {
4807
+ id: "delivery.project",
4808
+ order: 60,
4809
+ label: "Project",
4810
+ description: "A client delivery project.",
4811
+ ownedBySystemId: "projects",
4812
+ table: "projects",
4813
+ links: [
4814
+ { toEntity: "delivery.milestone", kind: "has-many", via: "project_id", label: "milestones" },
4815
+ { toEntity: "delivery.task", kind: "has-many", via: "project_id", label: "tasks" }
4816
+ ]
4817
+ },
4818
+ {
4819
+ id: "delivery.milestone",
4820
+ order: 70,
4821
+ label: "Milestone",
4822
+ description: "A delivery checkpoint within a project.",
4823
+ ownedBySystemId: "projects",
4824
+ table: "project_milestones",
4825
+ links: [
4826
+ { toEntity: "delivery.project", kind: "belongs-to", via: "project_id", label: "project" },
4827
+ { toEntity: "delivery.task", kind: "has-many", via: "milestone_id", label: "tasks" }
4828
+ ]
4829
+ },
4830
+ {
4831
+ id: "delivery.task",
4832
+ order: 80,
4833
+ label: "Task",
4834
+ description: "A delivery task that can move through the task status catalog.",
4835
+ ownedBySystemId: "projects",
4836
+ table: "project_tasks",
4837
+ stateCatalogId: "delivery.task",
4838
+ links: [
4839
+ { toEntity: "delivery.project", kind: "belongs-to", via: "project_id", label: "project" },
4840
+ { toEntity: "delivery.milestone", kind: "belongs-to", via: "milestone_id", label: "milestone" }
4841
+ ]
4842
+ }
4843
+ ];
4844
+ Object.fromEntries(
4845
+ ENTITY_ENTRY_INPUTS.map((entity) => {
4846
+ const parsed = EntitySchema.parse(entity);
4847
+ return [parsed.id, parsed];
4848
+ })
4849
+ );
4850
+
4851
+ // ../core/src/organization-model/domains/actions.ts
4852
+ var ActionResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
4853
+ z.enum(["slash-command", "mcp-tool", "api-endpoint", "script-execution"]).meta({ label: "Invocation kind" });
4854
+ var ActionIdSchema = ModelIdSchema;
4855
+ var ActionScopeSchema = z.union([
4856
+ z.literal("global"),
4857
+ z.object({
4858
+ domain: ModelIdSchema
4859
+ })
4860
+ ]);
4741
4861
  z.object({
4742
- entityId: ModelIdSchema,
4743
- defaultPipelineId: ModelIdSchema,
4744
- pipelines: z.array(SalesPipelineSchema).min(1)
4862
+ actionId: ActionIdSchema.meta({ ref: "action" }),
4863
+ intent: z.enum(["exposes", "consumes"]).meta({ label: "Intent" })
4745
4864
  });
4746
- var CRM_DISCOVERY_REPLIED_STATE = {
4747
- stateKey: "discovery_replied",
4748
- label: "Discovery Replied"
4749
- };
4750
- var CRM_DISCOVERY_LINK_SENT_STATE = {
4751
- stateKey: "discovery_link_sent",
4752
- label: "Discovery Link Sent"
4753
- };
4754
- var CRM_DISCOVERY_NUDGING_STATE = {
4755
- stateKey: "discovery_nudging",
4756
- label: "Discovery Nudging"
4757
- };
4758
- var CRM_DISCOVERY_BOOKING_CANCELLED_STATE = {
4759
- stateKey: "discovery_booking_cancelled",
4760
- label: "Discovery Booking Cancelled"
4761
- };
4762
- var CRM_REPLY_SENT_STATE = {
4763
- stateKey: "reply_sent",
4764
- label: "Reply Sent"
4765
- };
4766
- var CRM_FOLLOWUP_1_SENT_STATE = {
4767
- stateKey: "followup_1_sent",
4768
- label: "Follow-up 1 Sent"
4769
- };
4770
- var CRM_FOLLOWUP_2_SENT_STATE = {
4771
- stateKey: "followup_2_sent",
4772
- label: "Follow-up 2 Sent"
4773
- };
4774
- var CRM_FOLLOWUP_3_SENT_STATE = {
4775
- stateKey: "followup_3_sent",
4776
- label: "Follow-up 3 Sent"
4777
- };
4778
- var CRM_PIPELINE_DEFINITION = {
4779
- pipelineKey: "crm",
4780
- stages: [
4781
- {
4782
- stageKey: "interested",
4783
- label: "Interested",
4784
- color: "blue",
4785
- states: [
4786
- CRM_DISCOVERY_REPLIED_STATE,
4787
- CRM_DISCOVERY_LINK_SENT_STATE,
4788
- CRM_DISCOVERY_NUDGING_STATE,
4789
- CRM_DISCOVERY_BOOKING_CANCELLED_STATE,
4790
- CRM_REPLY_SENT_STATE,
4791
- CRM_FOLLOWUP_1_SENT_STATE,
4792
- CRM_FOLLOWUP_2_SENT_STATE,
4793
- CRM_FOLLOWUP_3_SENT_STATE
4794
- ]
4795
- },
4796
- { stageKey: "proposal", label: "Proposal", color: "yellow", states: [] },
4797
- { stageKey: "closing", label: "Closing", color: "orange", states: [] },
4798
- { stageKey: "closed_won", label: "Closed Won", color: "green", states: [] },
4799
- { stageKey: "closed_lost", label: "Closed Lost", color: "red", states: [] },
4800
- { stageKey: "nurturing", label: "Nurturing", color: "grape", states: [] }
4801
- ]
4802
- };
4803
- var LEAD_GEN_STAGE_CATALOG = {
4804
- // Prospecting — company population
4805
- scraped: {
4806
- key: "scraped",
4807
- label: "Scraped",
4808
- description: "Company was scraped from a source directory (Apify actor run).",
4809
- order: 1,
4810
- entity: "company"
4865
+ var SlashCommandInvocationSchema = z.object({
4866
+ kind: z.literal("slash-command"),
4867
+ command: z.string().trim().min(1).max(200).regex(/^\/[^\s].*$/, "Slash commands must start with /"),
4868
+ toolFactory: ModelIdSchema.optional()
4869
+ });
4870
+ var McpToolInvocationSchema = z.object({
4871
+ kind: z.literal("mcp-tool"),
4872
+ server: ModelIdSchema,
4873
+ name: ModelIdSchema
4874
+ });
4875
+ var ApiEndpointInvocationSchema = z.object({
4876
+ kind: z.literal("api-endpoint"),
4877
+ method: z.enum(["GET", "POST", "PATCH", "DELETE"]).meta({ label: "HTTP method" }),
4878
+ path: z.string().trim().startsWith("/").max(500),
4879
+ requestSchema: ModelIdSchema.optional(),
4880
+ responseSchema: ModelIdSchema.optional()
4881
+ });
4882
+ var ScriptExecutionInvocationSchema = z.object({
4883
+ kind: z.literal("script-execution"),
4884
+ resourceId: ActionResourceIdSchema
4885
+ });
4886
+ var ActionInvocationSchema = z.discriminatedUnion("kind", [
4887
+ SlashCommandInvocationSchema,
4888
+ McpToolInvocationSchema,
4889
+ ApiEndpointInvocationSchema,
4890
+ ScriptExecutionInvocationSchema
4891
+ ]);
4892
+ var ActionSchema = z.object({
4893
+ id: ActionIdSchema,
4894
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
4895
+ order: z.number(),
4896
+ label: LabelSchema,
4897
+ description: DescriptionSchema.optional(),
4898
+ scope: ActionScopeSchema.default("global"),
4899
+ resourceId: ActionResourceIdSchema.optional(),
4900
+ affects: z.array(EntityIdSchema.meta({ ref: "entity" })).optional(),
4901
+ invocations: z.array(ActionInvocationSchema).default([]),
4902
+ knowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
4903
+ lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
4904
+ });
4905
+ z.record(z.string(), ActionSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
4906
+ message: "Each action entry id must match its map key"
4907
+ }).default({});
4908
+ var LEAD_GEN_ACTION_ENTRY_INPUTS = [
4909
+ {
4910
+ id: "lead-gen.company.source",
4911
+ order: 10,
4912
+ label: "Source companies",
4913
+ description: "Import source companies from a list provider.",
4914
+ scope: { domain: "sales" },
4915
+ resourceId: "lgn-import-workflow",
4916
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/source" }]
4811
4917
  },
4812
- populated: {
4813
- key: "populated",
4814
- label: "Companies found",
4815
- description: "Companies have been found and added to the lead-gen list.",
4816
- order: 2,
4817
- entity: "company"
4918
+ {
4919
+ id: "lead-gen.company.apollo-import",
4920
+ order: 20,
4921
+ label: "Import from Apollo",
4922
+ description: "Pull companies and seed contact data from an Apollo search or list.",
4923
+ scope: { domain: "sales" },
4924
+ resourceId: "lgn-01c-apollo-import-workflow",
4925
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/apollo-import" }]
4818
4926
  },
4819
- crawled: {
4820
- key: "crawled",
4821
- label: "Websites crawled",
4822
- description: "Company websites have been crawled (e.g. via Apify) and raw page content stored for downstream LLM analysis.",
4823
- order: 2.5,
4824
- entity: "company"
4927
+ {
4928
+ id: "lead-gen.contact.discover",
4929
+ order: 30,
4930
+ label: "Discover contact emails",
4931
+ description: "Find email addresses for contacts at qualified companies.",
4932
+ scope: { domain: "sales" },
4933
+ resourceId: "lgn-04-email-discovery-workflow",
4934
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/discover" }]
4825
4935
  },
4826
- extracted: {
4827
- key: "extracted",
4828
- label: "Websites analyzed",
4829
- description: "Company websites have been analyzed for business signals.",
4830
- order: 3,
4831
- entity: "company"
4936
+ {
4937
+ id: "lead-gen.contact.verify-email",
4938
+ order: 40,
4939
+ label: "Verify emails",
4940
+ description: "Check email deliverability before outreach.",
4941
+ scope: { domain: "sales" },
4942
+ resourceId: "lgn-05-email-verification-workflow",
4943
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/verify-email" }]
4832
4944
  },
4833
- enriched: {
4834
- key: "enriched",
4835
- label: "Enriched",
4836
- description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
4837
- order: 4,
4838
- entity: "company"
4945
+ {
4946
+ id: "lead-gen.company.apify-crawl",
4947
+ order: 50,
4948
+ label: "Crawl websites",
4949
+ description: "Crawl company websites via Apify and store raw page markdown in enrichmentData.websiteCrawl.pages for downstream LLM analysis.",
4950
+ scope: { domain: "sales" },
4951
+ resourceId: "lgn-02a-apify-website-crawl-workflow",
4952
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/apify-crawl" }]
4839
4953
  },
4840
- "decision-makers-enriched": {
4841
- key: "decision-makers-enriched",
4842
- label: "Decision-makers found",
4843
- description: "Decision-maker contacts discovered and attached to a qualified company.",
4844
- order: 6,
4845
- entity: "company",
4846
- recordEntity: "contact",
4847
- recordStageKey: "discovered"
4954
+ {
4955
+ id: "lead-gen.company.website-extract",
4956
+ order: 60,
4957
+ label: "Extract website signals",
4958
+ description: "Scrape and analyze company websites for qualification signals.",
4959
+ scope: { domain: "sales" },
4960
+ resourceId: "lgn-02-website-extract-workflow",
4961
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/website-extract" }]
4848
4962
  },
4849
- // Prospecting — contact discovery
4850
- discovered: {
4851
- key: "discovered",
4852
- label: "Decision-makers found",
4853
- description: "Decision-maker contact details have been found.",
4854
- order: 5,
4855
- entity: "contact"
4963
+ {
4964
+ id: "lead-gen.company.qualify",
4965
+ order: 70,
4966
+ label: "Qualify companies",
4967
+ description: "Score and filter companies against the ICP rubric.",
4968
+ scope: { domain: "sales" },
4969
+ resourceId: "lgn-03-company-qualification-workflow",
4970
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/qualify" }]
4856
4971
  },
4857
- verified: {
4858
- key: "verified",
4859
- label: "Emails verified",
4860
- description: "Contact email addresses have been checked for deliverability.",
4861
- order: 7,
4862
- entity: "contact"
4972
+ {
4973
+ id: "lead-gen.company.dtc-subscription-qualify",
4974
+ order: 80,
4975
+ label: "Qualify DTC subscription fit",
4976
+ description: "Classify subscription potential and consumable-product fit for DTC brands.",
4977
+ scope: { domain: "sales" },
4978
+ resourceId: "lgn-03b-dtc-subscription-score-workflow",
4979
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/dtc-subscription-qualify" }]
4863
4980
  },
4864
- // Qualification
4865
- qualified: {
4866
- key: "qualified",
4867
- label: "Companies qualified",
4868
- description: "Companies have been scored against the qualification criteria.",
4869
- order: 8,
4870
- entity: "company"
4981
+ {
4982
+ id: "lead-gen.contact.apollo-decision-maker-enrich",
4983
+ order: 90,
4984
+ label: "Enrich decision-makers",
4985
+ description: "Find and enrich qualified contacts at qualified companies via Apollo.",
4986
+ scope: { domain: "sales" },
4987
+ resourceId: "lgn-04b-apollo-decision-maker-enrich-workflow",
4988
+ invocations: [
4989
+ { kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/apollo-decision-maker-enrich" }
4990
+ ]
4871
4991
  },
4872
- // Outreach
4873
- personalized: {
4874
- key: "personalized",
4875
- label: "Personalized",
4876
- description: "Outreach message personalized for the contact (Instantly personalization workflow).",
4877
- order: 9,
4878
- entity: "contact"
4992
+ {
4993
+ id: "lead-gen.contact.personalize",
4994
+ order: 100,
4995
+ label: "Personalize outreach",
4996
+ description: "Generate personalized opening lines for each contact.",
4997
+ scope: { domain: "sales" },
4998
+ resourceId: "ist-personalization-workflow",
4999
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/personalize" }]
4879
5000
  },
4880
- uploaded: {
4881
- key: "uploaded",
4882
- label: "Reviewed and exported",
4883
- description: "Approved records have been reviewed and exported for handoff.",
4884
- order: 10,
4885
- entity: "company",
4886
- additionalEntities: ["contact"]
5001
+ {
5002
+ id: "lead-gen.review.outreach-ready",
5003
+ order: 110,
5004
+ label: "Upload to outreach",
5005
+ description: "Upload approved contacts to the outreach sequence after QC review.",
5006
+ scope: { domain: "sales" },
5007
+ resourceId: "ist-upload-contacts-workflow",
5008
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/review/outreach-ready" }]
4887
5009
  },
4888
- interested: {
4889
- key: "interested",
4890
- label: "Interested",
4891
- description: "Contact replied with a positive signal (Instantly reply-handler transition).",
4892
- order: 11,
4893
- entity: "contact"
5010
+ {
5011
+ id: "lead-gen.export.list",
5012
+ order: 120,
5013
+ label: "Export lead list",
5014
+ description: "Export approved leads as a downloadable lead list.",
5015
+ scope: { domain: "sales" },
5016
+ resourceId: "lgn-06-export-list-workflow",
5017
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/export/list" }]
5018
+ },
5019
+ {
5020
+ id: "lead-gen.company.cleanup",
5021
+ order: 130,
5022
+ label: "Clean up companies",
5023
+ description: "Remove disqualified or duplicate companies from the list.",
5024
+ scope: { domain: "sales" },
5025
+ resourceId: "lgn-company-cleanup-workflow",
5026
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/cleanup" }]
4894
5027
  }
4895
- };
5028
+ ];
5029
+ var LEAD_GEN_ACTION_ENTRIES = Object.fromEntries(
5030
+ LEAD_GEN_ACTION_ENTRY_INPUTS.map((action) => {
5031
+ const parsed = ActionSchema.parse(action);
5032
+ return [parsed.id, parsed];
5033
+ })
5034
+ );
4896
5035
 
4897
5036
  // ../core/src/organization-model/domains/prospecting.ts
4898
- var ProspectingLifecycleStageSchema = DisplayMetadataSchema.extend({
5037
+ DisplayMetadataSchema.extend({
4899
5038
  id: ModelIdSchema,
4900
5039
  order: z.number().min(0)
4901
5040
  });
@@ -4933,7 +5072,7 @@ var ProspectingBuildTemplateStepSchema = DisplayMetadataSchema.extend({
4933
5072
  recordSourceStageKey: ModelIdSchema.optional(),
4934
5073
  dependsOn: z.array(ModelIdSchema).optional(),
4935
5074
  dependencyMode: z.literal("per-record-eligibility"),
4936
- capabilityKey: ModelIdSchema,
5075
+ actionKey: ModelIdSchema,
4937
5076
  defaultBatchSize: z.number().int().positive(),
4938
5077
  maxBatchSize: z.number().int().positive(),
4939
5078
  recordColumns: RecordColumnsConfigSchema.optional(),
@@ -4942,7 +5081,7 @@ var ProspectingBuildTemplateStepSchema = DisplayMetadataSchema.extend({
4942
5081
  message: "defaultBatchSize must be less than or equal to maxBatchSize",
4943
5082
  path: ["defaultBatchSize"]
4944
5083
  });
4945
- var ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
5084
+ DisplayMetadataSchema.extend({
4946
5085
  id: ModelIdSchema,
4947
5086
  steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
4948
5087
  });
@@ -4970,8 +5109,18 @@ var DTC_RECORD_COLUMNS = {
4970
5109
  { key: "domain", label: "Domain", path: "company.domain" },
4971
5110
  { key: "description", label: "Description", path: "company.enrichmentData.websiteCrawl.companyDescription" },
4972
5111
  { key: "services", label: "Services", path: "company.enrichmentData.websiteCrawl.services", renderType: "json" },
4973
- { key: "automation-gaps", label: "Automation gaps", path: "company.enrichmentData.websiteCrawl.automationGaps", renderType: "json" },
4974
- { key: "contact-count", label: "Contacts", path: "company.enrichmentData.websiteCrawl.emailCount", renderType: "count" }
5112
+ {
5113
+ key: "automation-gaps",
5114
+ label: "Automation gaps",
5115
+ path: "company.enrichmentData.websiteCrawl.automationGaps",
5116
+ renderType: "json"
5117
+ },
5118
+ {
5119
+ key: "contact-count",
5120
+ label: "Contacts",
5121
+ path: "company.enrichmentData.websiteCrawl.emailCount",
5122
+ renderType: "count"
5123
+ }
4975
5124
  ]
4976
5125
  },
4977
5126
  qualified: {
@@ -4980,7 +5129,11 @@ var DTC_RECORD_COLUMNS = {
4980
5129
  { key: "domain", label: "Domain", path: "company.domain" },
4981
5130
  { key: "score", label: "Score", path: "company.qualificationScore", renderType: "badge", badgeColor: "green" },
4982
5131
  { key: "signals", label: "Signals", path: "company.qualificationSignals", renderType: "json" },
4983
- { key: "disqualified-reason", label: "Disqualified reason", path: "processingState.qualified.data.disqualifiedReason" }
5132
+ {
5133
+ key: "disqualified-reason",
5134
+ label: "Disqualified reason",
5135
+ path: "processingState.qualified.data.disqualifiedReason"
5136
+ }
4984
5137
  ]
4985
5138
  },
4986
5139
  decisionMakers: {
@@ -4989,105 +5142,35 @@ var DTC_RECORD_COLUMNS = {
4989
5142
  { key: "title", label: "Title", path: "contact.title" },
4990
5143
  { key: "email", label: "Email", path: "contact.email" },
4991
5144
  { key: "linkedin", label: "LinkedIn", path: "contact.linkedinUrl" },
4992
- { key: "priority-score", label: "Priority", path: "contact.enrichmentData.apollo.priorityScore", renderType: "badge" }
5145
+ {
5146
+ key: "priority-score",
5147
+ label: "Priority",
5148
+ path: "contact.enrichmentData.apollo.priorityScore",
5149
+ renderType: "badge"
5150
+ }
4993
5151
  ]
4994
5152
  },
4995
5153
  uploaded: {
4996
5154
  company: [
4997
5155
  { key: "name", label: "Company", path: "company.name" },
4998
5156
  { key: "domain", label: "Domain", path: "company.domain" },
4999
- { key: "contacts", label: "Contacts", path: "company.enrichmentData.approvedLeadListExport.contacts", renderType: "json" },
5157
+ {
5158
+ key: "contacts",
5159
+ label: "Contacts",
5160
+ path: "company.enrichmentData.approvedLeadListExport.contacts",
5161
+ renderType: "json"
5162
+ },
5000
5163
  { key: "score", label: "Score", path: "company.qualificationScore", renderType: "badge", badgeColor: "green" },
5001
- { key: "approval", label: "Approval", path: "company.enrichmentData.approvedLeadListExport.approvalStatus", renderType: "badge" }
5164
+ {
5165
+ key: "approval",
5166
+ label: "Approval",
5167
+ path: "company.enrichmentData.approvedLeadListExport.approvalStatus",
5168
+ renderType: "badge"
5169
+ }
5002
5170
  ]
5003
5171
  }
5004
5172
  };
5005
- z.object({
5006
- id: ModelIdSchema,
5007
- label: z.string(),
5008
- description: z.string(),
5009
- resourceId: ModelIdSchema
5010
- });
5011
- var CAPABILITY_REGISTRY = [
5012
- {
5013
- id: "lead-gen.company.source",
5014
- label: "Source companies",
5015
- description: "Import source companies from a list provider.",
5016
- resourceId: "lgn-import-workflow"
5017
- },
5018
- {
5019
- id: "lead-gen.company.apollo-import",
5020
- label: "Import from Apollo",
5021
- description: "Pull companies and seed contact data from an Apollo search or list.",
5022
- resourceId: "lgn-01c-apollo-import-workflow"
5023
- },
5024
- {
5025
- id: "lead-gen.contact.discover",
5026
- label: "Discover contact emails",
5027
- description: "Find email addresses for contacts at qualified companies.",
5028
- resourceId: "lgn-04-email-discovery-workflow"
5029
- },
5030
- {
5031
- id: "lead-gen.contact.verify-email",
5032
- label: "Verify emails",
5033
- description: "Check email deliverability before outreach.",
5034
- resourceId: "lgn-05-email-verification-workflow"
5035
- },
5036
- {
5037
- id: "lead-gen.company.apify-crawl",
5038
- label: "Crawl websites",
5039
- description: "Crawl company websites via Apify and store raw page markdown in enrichmentData.websiteCrawl.pages for downstream LLM analysis.",
5040
- resourceId: "lgn-02a-apify-website-crawl-workflow"
5041
- },
5042
- {
5043
- id: "lead-gen.company.website-extract",
5044
- label: "Extract website signals",
5045
- description: "Scrape and analyze company websites for qualification signals.",
5046
- resourceId: "lgn-02-website-extract-workflow"
5047
- },
5048
- {
5049
- id: "lead-gen.company.qualify",
5050
- label: "Qualify companies",
5051
- description: "Score and filter companies against the ICP rubric.",
5052
- resourceId: "lgn-03-company-qualification-workflow"
5053
- },
5054
- {
5055
- id: "lead-gen.company.dtc-subscription-qualify",
5056
- label: "Qualify DTC subscription fit",
5057
- description: "Classify subscription potential and consumable-product fit for DTC brands.",
5058
- resourceId: "lgn-03b-dtc-subscription-score-workflow"
5059
- },
5060
- {
5061
- id: "lead-gen.contact.apollo-decision-maker-enrich",
5062
- label: "Enrich decision-makers",
5063
- description: "Find and enrich qualified contacts at qualified companies via Apollo.",
5064
- resourceId: "lgn-04b-apollo-decision-maker-enrich-workflow"
5065
- },
5066
- {
5067
- id: "lead-gen.contact.personalize",
5068
- label: "Personalize outreach",
5069
- description: "Generate personalized opening lines for each contact.",
5070
- resourceId: "ist-personalization-workflow"
5071
- },
5072
- {
5073
- id: "lead-gen.review.outreach-ready",
5074
- label: "Upload to outreach",
5075
- description: "Upload approved contacts to the outreach sequence after QC review.",
5076
- resourceId: "ist-upload-contacts-workflow"
5077
- },
5078
- {
5079
- id: "lead-gen.export.list",
5080
- label: "Export lead list",
5081
- description: "Export approved leads as a downloadable lead list.",
5082
- resourceId: "lgn-06-export-list-workflow"
5083
- },
5084
- {
5085
- id: "lead-gen.company.cleanup",
5086
- label: "Clean up companies",
5087
- description: "Remove disqualified or duplicate companies from the list.",
5088
- resourceId: "lgn-company-cleanup-workflow"
5089
- }
5090
- ];
5173
+ var ACTION_REGISTRY = Object.values(LEAD_GEN_ACTION_ENTRIES);
5091
5174
  var PROSPECTING_STEPS = {
5092
5175
  localServices: {
5093
5176
  sourceCompanies: {
@@ -5097,7 +5180,7 @@ var PROSPECTING_STEPS = {
5097
5180
  outputs: ["company"],
5098
5181
  stageKey: "populated",
5099
5182
  dependencyMode: "per-record-eligibility",
5100
- capabilityKey: "lead-gen.company.source",
5183
+ actionKey: "lead-gen.company.source",
5101
5184
  defaultBatchSize: 100,
5102
5185
  maxBatchSize: 250
5103
5186
  },
@@ -5109,7 +5192,7 @@ var PROSPECTING_STEPS = {
5109
5192
  stageKey: "extracted",
5110
5193
  dependsOn: ["source-companies"],
5111
5194
  dependencyMode: "per-record-eligibility",
5112
- capabilityKey: "lead-gen.company.website-extract",
5195
+ actionKey: "lead-gen.company.website-extract",
5113
5196
  defaultBatchSize: 50,
5114
5197
  maxBatchSize: 100
5115
5198
  },
@@ -5121,7 +5204,7 @@ var PROSPECTING_STEPS = {
5121
5204
  stageKey: "qualified",
5122
5205
  dependsOn: ["analyze-websites"],
5123
5206
  dependencyMode: "per-record-eligibility",
5124
- capabilityKey: "lead-gen.company.qualify",
5207
+ actionKey: "lead-gen.company.qualify",
5125
5208
  defaultBatchSize: 100,
5126
5209
  maxBatchSize: 250
5127
5210
  },
@@ -5133,7 +5216,7 @@ var PROSPECTING_STEPS = {
5133
5216
  stageKey: "discovered",
5134
5217
  dependsOn: ["qualify-companies"],
5135
5218
  dependencyMode: "per-record-eligibility",
5136
- capabilityKey: "lead-gen.contact.discover",
5219
+ actionKey: "lead-gen.contact.discover",
5137
5220
  defaultBatchSize: 50,
5138
5221
  maxBatchSize: 100
5139
5222
  },
@@ -5145,7 +5228,7 @@ var PROSPECTING_STEPS = {
5145
5228
  stageKey: "verified",
5146
5229
  dependsOn: ["find-contacts"],
5147
5230
  dependencyMode: "per-record-eligibility",
5148
- capabilityKey: "lead-gen.contact.verify-email",
5231
+ actionKey: "lead-gen.contact.verify-email",
5149
5232
  defaultBatchSize: 100,
5150
5233
  maxBatchSize: 500
5151
5234
  },
@@ -5157,7 +5240,7 @@ var PROSPECTING_STEPS = {
5157
5240
  stageKey: "personalized",
5158
5241
  dependsOn: ["verify-emails"],
5159
5242
  dependencyMode: "per-record-eligibility",
5160
- capabilityKey: "lead-gen.contact.personalize",
5243
+ actionKey: "lead-gen.contact.personalize",
5161
5244
  defaultBatchSize: 25,
5162
5245
  maxBatchSize: 100
5163
5246
  },
@@ -5169,7 +5252,7 @@ var PROSPECTING_STEPS = {
5169
5252
  stageKey: "uploaded",
5170
5253
  dependsOn: ["personalize"],
5171
5254
  dependencyMode: "per-record-eligibility",
5172
- capabilityKey: "lead-gen.review.outreach-ready",
5255
+ actionKey: "lead-gen.review.outreach-ready",
5173
5256
  defaultBatchSize: 25,
5174
5257
  maxBatchSize: 100
5175
5258
  }
@@ -5183,7 +5266,7 @@ var PROSPECTING_STEPS = {
5183
5266
  outputs: ["company", "contact"],
5184
5267
  stageKey: "populated",
5185
5268
  dependencyMode: "per-record-eligibility",
5186
- capabilityKey: "lead-gen.company.apollo-import",
5269
+ actionKey: "lead-gen.company.apollo-import",
5187
5270
  defaultBatchSize: 250,
5188
5271
  maxBatchSize: 1e3,
5189
5272
  recordColumns: DTC_RECORD_COLUMNS.populated,
@@ -5208,7 +5291,7 @@ var PROSPECTING_STEPS = {
5208
5291
  stageKey: "crawled",
5209
5292
  dependsOn: ["import-apollo-search"],
5210
5293
  dependencyMode: "per-record-eligibility",
5211
- capabilityKey: "lead-gen.company.apify-crawl",
5294
+ actionKey: "lead-gen.company.apify-crawl",
5212
5295
  defaultBatchSize: 50,
5213
5296
  maxBatchSize: 100,
5214
5297
  recordColumns: DTC_RECORD_COLUMNS.crawled,
@@ -5234,7 +5317,7 @@ var PROSPECTING_STEPS = {
5234
5317
  stageKey: "extracted",
5235
5318
  dependsOn: ["apify-crawl"],
5236
5319
  dependencyMode: "per-record-eligibility",
5237
- capabilityKey: "lead-gen.company.website-extract",
5320
+ actionKey: "lead-gen.company.website-extract",
5238
5321
  defaultBatchSize: 50,
5239
5322
  maxBatchSize: 100,
5240
5323
  recordColumns: DTC_RECORD_COLUMNS.extracted
@@ -5248,7 +5331,7 @@ var PROSPECTING_STEPS = {
5248
5331
  stageKey: "qualified",
5249
5332
  dependsOn: ["analyze-websites"],
5250
5333
  dependencyMode: "per-record-eligibility",
5251
- capabilityKey: "lead-gen.company.dtc-subscription-qualify",
5334
+ actionKey: "lead-gen.company.dtc-subscription-qualify",
5252
5335
  defaultBatchSize: 100,
5253
5336
  maxBatchSize: 250,
5254
5337
  recordColumns: DTC_RECORD_COLUMNS.qualified
@@ -5263,7 +5346,7 @@ var PROSPECTING_STEPS = {
5263
5346
  recordEntity: "contact",
5264
5347
  dependsOn: ["score-dtc-fit"],
5265
5348
  dependencyMode: "per-record-eligibility",
5266
- capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
5349
+ actionKey: "lead-gen.contact.apollo-decision-maker-enrich",
5267
5350
  defaultBatchSize: 100,
5268
5351
  maxBatchSize: 250,
5269
5352
  recordColumns: DTC_RECORD_COLUMNS.decisionMakers,
@@ -5290,7 +5373,7 @@ var PROSPECTING_STEPS = {
5290
5373
  recordSourceStageKey: "qualified",
5291
5374
  dependsOn: ["enrich-decision-makers"],
5292
5375
  dependencyMode: "per-record-eligibility",
5293
- capabilityKey: "lead-gen.export.list",
5376
+ actionKey: "lead-gen.export.list",
5294
5377
  defaultBatchSize: 100,
5295
5378
  maxBatchSize: 250,
5296
5379
  recordColumns: DTC_RECORD_COLUMNS.uploaded,
@@ -5309,77 +5392,207 @@ var PROSPECTING_STEPS = {
5309
5392
  }
5310
5393
  }
5311
5394
  };
5395
+
5396
+ // ../core/src/business/acquisition/build-templates.ts
5397
+ var BUILD_TEMPLATE_CATALOG = [
5398
+ {
5399
+ id: "local-services",
5400
+ label: "Local Services",
5401
+ description: "Source, analyze, qualify, and personalize local service businesses for outreach.",
5402
+ steps: Object.values(PROSPECTING_STEPS.localServices)
5403
+ },
5404
+ {
5405
+ id: "dtc-subscription-apollo-clickup",
5406
+ label: "DTC Subscription (Apollo + ClickUp)",
5407
+ description: "Import DTC brand leads from Apollo, crawl their websites, score fit, enrich contacts, and export via ClickUp.",
5408
+ steps: Object.values(PROSPECTING_STEPS.dtcApolloClickup)
5409
+ }
5410
+ ];
5411
+ var PROSPECTING_BUILD_TEMPLATE_OPTIONS = BUILD_TEMPLATE_CATALOG.map(({ id, label, description }) => ({
5412
+ id,
5413
+ label,
5414
+ description
5415
+ }));
5416
+ function isProspectingBuildTemplateId(value) {
5417
+ return PROSPECTING_BUILD_TEMPLATE_OPTIONS.some((template) => template.id === value);
5418
+ }
5419
+
5420
+ // ../core/src/organization-model/catalogs/lead-gen.ts
5421
+ var LEAD_GEN_STAGE_CATALOG = {
5422
+ // Prospecting - company population
5423
+ scraped: {
5424
+ key: "scraped",
5425
+ label: "Scraped",
5426
+ description: "Company was scraped from a source directory (Apify actor run).",
5427
+ order: 1,
5428
+ entity: "company"
5429
+ },
5430
+ populated: {
5431
+ key: "populated",
5432
+ label: "Companies found",
5433
+ description: "Companies have been found and added to the lead-gen list.",
5434
+ order: 2,
5435
+ entity: "company"
5436
+ },
5437
+ crawled: {
5438
+ key: "crawled",
5439
+ label: "Websites crawled",
5440
+ description: "Company websites have been crawled (e.g. via Apify) and raw page content stored for downstream LLM analysis.",
5441
+ order: 2.5,
5442
+ entity: "company"
5443
+ },
5444
+ extracted: {
5445
+ key: "extracted",
5446
+ label: "Websites analyzed",
5447
+ description: "Company websites have been analyzed for business signals.",
5448
+ order: 3,
5449
+ entity: "company"
5450
+ },
5451
+ enriched: {
5452
+ key: "enriched",
5453
+ label: "Enriched",
5454
+ description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
5455
+ order: 4,
5456
+ entity: "company"
5457
+ },
5458
+ "decision-makers-enriched": {
5459
+ key: "decision-makers-enriched",
5460
+ label: "Decision-makers found",
5461
+ description: "Decision-maker contacts discovered and attached to a qualified company.",
5462
+ order: 6,
5463
+ entity: "company",
5464
+ recordEntity: "contact",
5465
+ recordStageKey: "discovered"
5466
+ },
5467
+ // Prospecting - contact discovery
5468
+ discovered: {
5469
+ key: "discovered",
5470
+ label: "Decision-makers found",
5471
+ description: "Decision-maker contact details have been found.",
5472
+ order: 5,
5473
+ entity: "contact"
5474
+ },
5475
+ verified: {
5476
+ key: "verified",
5477
+ label: "Emails verified",
5478
+ description: "Contact email addresses have been checked for deliverability.",
5479
+ order: 7,
5480
+ entity: "contact"
5481
+ },
5482
+ // Qualification
5483
+ qualified: {
5484
+ key: "qualified",
5485
+ label: "Companies qualified",
5486
+ description: "Companies have been scored against the qualification criteria.",
5487
+ order: 8,
5488
+ entity: "company"
5489
+ },
5490
+ // Outreach
5491
+ personalized: {
5492
+ key: "personalized",
5493
+ label: "Personalized",
5494
+ description: "Outreach message personalized for the contact (Instantly personalization workflow).",
5495
+ order: 9,
5496
+ entity: "contact"
5497
+ },
5498
+ uploaded: {
5499
+ key: "uploaded",
5500
+ label: "Reviewed and exported",
5501
+ description: "Approved records have been reviewed and exported for handoff.",
5502
+ order: 10,
5503
+ entity: "company",
5504
+ additionalEntities: ["contact"]
5505
+ },
5506
+ interested: {
5507
+ key: "interested",
5508
+ label: "Interested",
5509
+ description: "Contact replied with a positive signal (Instantly reply-handler transition).",
5510
+ order: 11,
5511
+ entity: "contact"
5512
+ }
5513
+ };
5514
+
5515
+ // ../core/src/organization-model/domains/sales.ts
5516
+ var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
5517
+ var SalesStageSchema = DisplayMetadataSchema.extend({
5518
+ id: ModelIdSchema,
5519
+ order: z.number().int().min(0),
5520
+ semanticClass: SalesStageSemanticClassSchema,
5521
+ surfaceIds: ReferenceIdsSchema,
5522
+ resourceIds: ReferenceIdsSchema
5523
+ });
5312
5524
  z.object({
5313
- listEntityId: ModelIdSchema,
5314
- companyEntityId: ModelIdSchema,
5315
- contactEntityId: ModelIdSchema,
5525
+ id: ModelIdSchema,
5526
+ label: z.string().trim().min(1).max(120),
5316
5527
  description: DescriptionSchema.optional(),
5317
- companyStages: z.array(ProspectingLifecycleStageSchema).min(1),
5318
- contactStages: z.array(ProspectingLifecycleStageSchema).min(1),
5319
- defaultBuildTemplateId: ModelIdSchema,
5320
- buildTemplates: z.array(ProspectingBuildTemplateSchema).min(1)
5528
+ entityId: ModelIdSchema,
5529
+ stages: z.array(SalesStageSchema).min(1)
5321
5530
  });
5322
- function toProspectingLifecycleStage(stage) {
5323
- return {
5324
- id: stage.key,
5325
- label: stage.label,
5326
- order: stage.order
5327
- };
5328
- }
5329
- function leadGenStagesForEntity(entity) {
5330
- return Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity || stage.additionalEntities?.includes(entity)).sort((a, b) => a.order - b.order).map(toProspectingLifecycleStage);
5331
- }
5332
- var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
5333
- companyStages: leadGenStagesForEntity("company"),
5334
- contactStages: leadGenStagesForEntity("contact"),
5335
- buildTemplates: [
5531
+ var CRM_DISCOVERY_REPLIED_STATE = {
5532
+ stateKey: "discovery_replied",
5533
+ label: "Discovery Replied"
5534
+ };
5535
+ var CRM_DISCOVERY_LINK_SENT_STATE = {
5536
+ stateKey: "discovery_link_sent",
5537
+ label: "Discovery Link Sent"
5538
+ };
5539
+ var CRM_DISCOVERY_NUDGING_STATE = {
5540
+ stateKey: "discovery_nudging",
5541
+ label: "Discovery Nudging"
5542
+ };
5543
+ var CRM_DISCOVERY_BOOKING_CANCELLED_STATE = {
5544
+ stateKey: "discovery_booking_cancelled",
5545
+ label: "Discovery Booking Cancelled"
5546
+ };
5547
+ var CRM_REPLY_SENT_STATE = {
5548
+ stateKey: "reply_sent",
5549
+ label: "Reply Sent"
5550
+ };
5551
+ var CRM_FOLLOWUP_1_SENT_STATE = {
5552
+ stateKey: "followup_1_sent",
5553
+ label: "Follow-up 1 Sent"
5554
+ };
5555
+ var CRM_FOLLOWUP_2_SENT_STATE = {
5556
+ stateKey: "followup_2_sent",
5557
+ label: "Follow-up 2 Sent"
5558
+ };
5559
+ var CRM_FOLLOWUP_3_SENT_STATE = {
5560
+ stateKey: "followup_3_sent",
5561
+ label: "Follow-up 3 Sent"
5562
+ };
5563
+ var CRM_PIPELINE_DEFINITION = {
5564
+ pipelineKey: "crm",
5565
+ stages: [
5336
5566
  {
5337
- id: "local-services",
5338
- label: "Local Services Prospecting",
5339
- description: "Curated local-services list build using company sourcing, website analysis, qualification, contact discovery, verification, personalization, and review.",
5340
- steps: [
5341
- PROSPECTING_STEPS.localServices.sourceCompanies,
5342
- PROSPECTING_STEPS.localServices.analyzeWebsites,
5343
- PROSPECTING_STEPS.localServices.qualifyCompanies,
5344
- PROSPECTING_STEPS.localServices.findContacts,
5345
- PROSPECTING_STEPS.localServices.verifyEmails,
5346
- PROSPECTING_STEPS.localServices.personalize,
5347
- PROSPECTING_STEPS.localServices.review
5567
+ stageKey: "interested",
5568
+ label: "Interested",
5569
+ color: "blue",
5570
+ states: [
5571
+ CRM_DISCOVERY_REPLIED_STATE,
5572
+ CRM_DISCOVERY_LINK_SENT_STATE,
5573
+ CRM_DISCOVERY_NUDGING_STATE,
5574
+ CRM_DISCOVERY_BOOKING_CANCELLED_STATE,
5575
+ CRM_REPLY_SENT_STATE,
5576
+ CRM_FOLLOWUP_1_SENT_STATE,
5577
+ CRM_FOLLOWUP_2_SENT_STATE,
5578
+ CRM_FOLLOWUP_3_SENT_STATE
5348
5579
  ]
5349
5580
  },
5350
- {
5351
- id: "dtc-subscription-apollo-clickup",
5352
- label: "DTC Subscription Apollo Export",
5353
- description: "Prospecting pipeline for DTC subscription or subscription-ready brands where Apollo is the source and contact-enrichment layer, Elevasis handles company research and fit scoring, and approved leads export as an approved lead list.",
5354
- steps: [
5355
- PROSPECTING_STEPS.dtcApolloClickup.importApolloSearch,
5356
- PROSPECTING_STEPS.dtcApolloClickup.apifyCrawl,
5357
- PROSPECTING_STEPS.dtcApolloClickup.analyzeWebsites,
5358
- PROSPECTING_STEPS.dtcApolloClickup.scoreDtcFit,
5359
- PROSPECTING_STEPS.dtcApolloClickup.enrichDecisionMakers,
5360
- PROSPECTING_STEPS.dtcApolloClickup.reviewAndExport
5361
- ]
5362
- }
5581
+ { stageKey: "proposal", label: "Proposal", color: "yellow", states: [] },
5582
+ { stageKey: "closing", label: "Closing", color: "orange", states: [] },
5583
+ { stageKey: "closed_won", label: "Closed Won", color: "green", states: [] },
5584
+ { stageKey: "closed_lost", label: "Closed Lost", color: "red", states: [] },
5585
+ { stageKey: "nurturing", label: "Nurturing", color: "grape", states: [] }
5363
5586
  ]
5364
5587
  };
5365
5588
 
5366
- // ../core/src/business/acquisition/build-templates.ts
5367
- var PROSPECTING_BUILD_TEMPLATE_OPTIONS = DEFAULT_ORGANIZATION_MODEL_PROSPECTING.buildTemplates.map(
5368
- ({ id, label, description }) => ({
5369
- id,
5370
- label,
5371
- description
5372
- })
5373
- );
5374
- function isProspectingBuildTemplateId(value) {
5375
- return PROSPECTING_BUILD_TEMPLATE_OPTIONS.some((template) => template.id === value);
5376
- }
5589
+ // ../core/src/business/acquisition/api-schemas.ts
5377
5590
  var ProcessingStageStatusSchema = z.enum(["success", "no_result", "skipped", "error"]);
5378
5591
  var LeadGenStageKeySchema = z.string().refine((value) => Object.prototype.hasOwnProperty.call(LEAD_GEN_STAGE_CATALOG, value), {
5379
5592
  message: "processing state key must match LEAD_GEN_STAGE_CATALOG"
5380
5593
  });
5381
- var LeadGenCapabilityKeySchema = z.string().refine((value) => CAPABILITY_REGISTRY.some((c) => c.id === value), {
5382
- message: "capabilityKey must match CAPABILITY_REGISTRY"
5594
+ var LeadGenActionKeySchema = z.string().refine((value) => ACTION_REGISTRY.some((c) => c.id === value), {
5595
+ message: "actionKey must match ACTION_REGISTRY"
5383
5596
  });
5384
5597
  var crmStageKeys = CRM_PIPELINE_DEFINITION.stages.map((stage) => stage.stageKey);
5385
5598
  var crmStateKeys = CRM_PIPELINE_DEFINITION.stages.flatMap((stage) => stage.states.map((state) => state.stateKey));
@@ -5659,7 +5872,7 @@ var BuildPlanSnapshotStepSchema = z.object({
5659
5872
  recordSourceStageKey: LeadGenStageKeySchema.optional(),
5660
5873
  dependsOn: z.array(z.string().trim().min(1).max(100)).optional(),
5661
5874
  dependencyMode: z.literal("per-record-eligibility"),
5662
- capabilityKey: LeadGenCapabilityKeySchema,
5875
+ actionKey: LeadGenActionKeySchema,
5663
5876
  defaultBatchSize: z.number().int().positive(),
5664
5877
  maxBatchSize: z.number().int().positive(),
5665
5878
  recordColumns: z.object({