@elevasis/core 0.18.0 → 0.20.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 (54) hide show
  1. package/dist/index.d.ts +82 -1
  2. package/dist/index.js +353 -171
  3. package/dist/knowledge/index.d.ts +44 -1
  4. package/dist/organization-model/index.d.ts +82 -1
  5. package/dist/organization-model/index.js +353 -171
  6. package/dist/test-utils/index.d.ts +41 -12
  7. package/dist/test-utils/index.js +352 -171
  8. package/package.json +4 -3
  9. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +89 -69
  10. package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -0
  11. package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -128
  12. package/src/business/acquisition/api-schemas.test.ts +199 -15
  13. package/src/business/acquisition/api-schemas.ts +116 -51
  14. package/src/business/acquisition/build-templates.test.ts +212 -0
  15. package/src/business/acquisition/derive-actions.test.ts +1 -1
  16. package/src/business/acquisition/types.ts +21 -38
  17. package/src/business/deals/api-schemas.ts +2 -2
  18. package/src/execution/engine/index.ts +436 -434
  19. package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -0
  20. package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -0
  21. package/src/execution/engine/tools/lead-service-types.ts +51 -9
  22. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -6
  23. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -5
  24. package/src/execution/engine/tools/platform/acquisition/types.ts +20 -9
  25. package/src/execution/engine/tools/registry.ts +700 -698
  26. package/src/execution/engine/tools/tool-maps.ts +10 -0
  27. package/src/execution/external/__tests__/api-schemas.test.ts +127 -0
  28. package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -6
  29. package/src/integrations/oauth/provider-registry.ts +74 -61
  30. package/src/integrations/oauth/server/credentials.ts +43 -39
  31. package/src/knowledge/__tests__/queries.test.ts +89 -0
  32. package/src/organization-model/__tests__/graph.test.ts +108 -2
  33. package/src/organization-model/__tests__/icons.test.ts +61 -0
  34. package/src/organization-model/__tests__/knowledge.test.ts +118 -1
  35. package/src/organization-model/__tests__/prospecting-ssot.test.ts +91 -0
  36. package/src/organization-model/__tests__/schema.test.ts +122 -0
  37. package/src/organization-model/__tests__/surface-projection.test.ts +174 -0
  38. package/src/organization-model/defaults.ts +8 -0
  39. package/src/organization-model/domains/knowledge.ts +9 -0
  40. package/src/organization-model/domains/prospecting.ts +347 -226
  41. package/src/organization-model/domains/sales.ts +40 -30
  42. package/src/organization-model/graph/build.ts +74 -0
  43. package/src/organization-model/graph/schema.ts +1 -0
  44. package/src/organization-model/graph/types.ts +1 -0
  45. package/src/organization-model/icons.ts +3 -0
  46. package/src/organization-model/schema.ts +63 -0
  47. package/src/organization-model/surface-projection.ts +218 -0
  48. package/src/organization-model/types.ts +9 -1
  49. package/src/platform/constants/versions.ts +1 -1
  50. package/src/platform/utils/__tests__/validation.test.ts +1084 -1083
  51. package/src/platform/utils/validation.ts +425 -425
  52. package/src/reference/_generated/contracts.md +89 -69
  53. package/src/server.ts +6 -0
  54. package/src/supabase/database.types.ts +6 -12
@@ -19418,6 +19418,7 @@ function makeTask(overrides = {}) {
19418
19418
  }
19419
19419
  var ORGANIZATION_MODEL_ICON_TOKENS = [
19420
19420
  "nav.dashboard",
19421
+ "nav.calendar",
19421
19422
  "nav.sales",
19422
19423
  "nav.crm",
19423
19424
  "nav.lead-gen",
@@ -19432,6 +19433,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
19432
19433
  "knowledge.strategy",
19433
19434
  "knowledge.reference",
19434
19435
  "feature.dashboard",
19436
+ "feature.calendar",
19435
19437
  "feature.sales",
19436
19438
  "feature.crm",
19437
19439
  "feature.finance",
@@ -19455,6 +19457,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
19455
19457
  "integration.google-sheets",
19456
19458
  "integration.attio",
19457
19459
  "surface.dashboard",
19460
+ "surface.calendar",
19458
19461
  "surface.overview",
19459
19462
  "surface.command-view",
19460
19463
  "surface.command-queue",
@@ -19635,6 +19638,89 @@ var DEFAULT_ORGANIZATION_MODEL_SALES = {
19635
19638
  }
19636
19639
  ]
19637
19640
  };
19641
+ var LEAD_GEN_STAGE_CATALOG = {
19642
+ // Prospecting — company population
19643
+ scraped: {
19644
+ key: "scraped",
19645
+ label: "Scraped",
19646
+ description: "Company was scraped from a source directory (Apify actor run).",
19647
+ order: 1,
19648
+ entity: "company"
19649
+ },
19650
+ populated: {
19651
+ key: "populated",
19652
+ label: "Companies found",
19653
+ description: "Companies have been found and added to the lead-gen list.",
19654
+ order: 2,
19655
+ entity: "company"
19656
+ },
19657
+ extracted: {
19658
+ key: "extracted",
19659
+ label: "Websites analyzed",
19660
+ description: "Company websites have been analyzed for business signals.",
19661
+ order: 3,
19662
+ entity: "company"
19663
+ },
19664
+ enriched: {
19665
+ key: "enriched",
19666
+ label: "Enriched",
19667
+ description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
19668
+ order: 4,
19669
+ entity: "company"
19670
+ },
19671
+ "decision-makers-enriched": {
19672
+ key: "decision-makers-enriched",
19673
+ label: "Decision-makers found",
19674
+ description: "Decision-maker contacts discovered and attached to a qualified company.",
19675
+ order: 6,
19676
+ entity: "company"
19677
+ },
19678
+ // Prospecting — contact discovery
19679
+ discovered: {
19680
+ key: "discovered",
19681
+ label: "Decision-makers found",
19682
+ description: "Decision-maker contact details have been found.",
19683
+ order: 5,
19684
+ entity: "contact"
19685
+ },
19686
+ verified: {
19687
+ key: "verified",
19688
+ label: "Emails verified",
19689
+ description: "Contact email addresses have been checked for deliverability.",
19690
+ order: 7,
19691
+ entity: "contact"
19692
+ },
19693
+ // Qualification
19694
+ qualified: {
19695
+ key: "qualified",
19696
+ label: "Companies qualified",
19697
+ description: "Companies have been scored against the qualification criteria.",
19698
+ order: 8,
19699
+ entity: "company"
19700
+ },
19701
+ // Outreach
19702
+ personalized: {
19703
+ key: "personalized",
19704
+ label: "Personalized",
19705
+ description: "Outreach message personalized for the contact (Instantly personalization workflow).",
19706
+ order: 9,
19707
+ entity: "contact"
19708
+ },
19709
+ uploaded: {
19710
+ key: "uploaded",
19711
+ label: "Reviewed and exported",
19712
+ description: "Approved records have been reviewed and exported for handoff.",
19713
+ order: 10,
19714
+ entity: "contact"
19715
+ },
19716
+ interested: {
19717
+ key: "interested",
19718
+ label: "Interested",
19719
+ description: "Contact replied with a positive signal (Instantly reply-handler transition).",
19720
+ order: 11,
19721
+ entity: "contact"
19722
+ }
19723
+ };
19638
19724
  var ProjectsDomainStateSchema = DisplayMetadataSchema.extend({
19639
19725
  id: ModelIdSchema,
19640
19726
  order: z.number().int().min(0)
@@ -19715,6 +19801,178 @@ var ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
19715
19801
  id: ModelIdSchema,
19716
19802
  steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
19717
19803
  });
19804
+ z.object({
19805
+ id: ModelIdSchema,
19806
+ label: z.string(),
19807
+ description: z.string(),
19808
+ resourceId: ModelIdSchema
19809
+ });
19810
+ var PROSPECTING_STEPS = {
19811
+ localServices: {
19812
+ sourceCompanies: {
19813
+ id: "source-companies",
19814
+ label: "Companies found",
19815
+ primaryEntity: "company",
19816
+ outputs: ["company"],
19817
+ stageKey: "populated",
19818
+ dependencyMode: "per-record-eligibility",
19819
+ capabilityKey: "lead-gen.company.source",
19820
+ defaultBatchSize: 100,
19821
+ maxBatchSize: 250
19822
+ },
19823
+ analyzeWebsites: {
19824
+ id: "analyze-websites",
19825
+ label: "Websites analyzed",
19826
+ primaryEntity: "company",
19827
+ outputs: ["company"],
19828
+ stageKey: "extracted",
19829
+ dependsOn: ["source-companies"],
19830
+ dependencyMode: "per-record-eligibility",
19831
+ capabilityKey: "lead-gen.company.website-extract",
19832
+ defaultBatchSize: 50,
19833
+ maxBatchSize: 100
19834
+ },
19835
+ qualifyCompanies: {
19836
+ id: "qualify-companies",
19837
+ label: "Companies qualified",
19838
+ primaryEntity: "company",
19839
+ outputs: ["company"],
19840
+ stageKey: "qualified",
19841
+ dependsOn: ["analyze-websites"],
19842
+ dependencyMode: "per-record-eligibility",
19843
+ capabilityKey: "lead-gen.company.qualify",
19844
+ defaultBatchSize: 100,
19845
+ maxBatchSize: 250
19846
+ },
19847
+ findContacts: {
19848
+ id: "find-contacts",
19849
+ label: "Decision-makers found",
19850
+ primaryEntity: "contact",
19851
+ outputs: ["contact"],
19852
+ stageKey: "discovered",
19853
+ dependsOn: ["qualify-companies"],
19854
+ dependencyMode: "per-record-eligibility",
19855
+ capabilityKey: "lead-gen.contact.discover",
19856
+ defaultBatchSize: 50,
19857
+ maxBatchSize: 100
19858
+ },
19859
+ verifyEmails: {
19860
+ id: "verify-emails",
19861
+ label: "Emails verified",
19862
+ primaryEntity: "contact",
19863
+ outputs: ["contact"],
19864
+ stageKey: "verified",
19865
+ dependsOn: ["find-contacts"],
19866
+ dependencyMode: "per-record-eligibility",
19867
+ capabilityKey: "lead-gen.contact.verify-email",
19868
+ defaultBatchSize: 100,
19869
+ maxBatchSize: 500
19870
+ },
19871
+ personalize: {
19872
+ id: "personalize",
19873
+ label: "Personalize",
19874
+ primaryEntity: "contact",
19875
+ outputs: ["contact"],
19876
+ stageKey: "personalized",
19877
+ dependsOn: ["verify-emails"],
19878
+ dependencyMode: "per-record-eligibility",
19879
+ capabilityKey: "lead-gen.contact.personalize",
19880
+ defaultBatchSize: 25,
19881
+ maxBatchSize: 100
19882
+ },
19883
+ review: {
19884
+ id: "review",
19885
+ label: "Reviewed and exported",
19886
+ primaryEntity: "contact",
19887
+ outputs: ["export"],
19888
+ stageKey: "uploaded",
19889
+ dependsOn: ["personalize"],
19890
+ dependencyMode: "per-record-eligibility",
19891
+ capabilityKey: "lead-gen.review.outreach-ready",
19892
+ defaultBatchSize: 25,
19893
+ maxBatchSize: 100
19894
+ }
19895
+ },
19896
+ dtcApolloClickup: {
19897
+ importApolloSearch: {
19898
+ id: "import-apollo-search",
19899
+ label: "Companies found",
19900
+ description: "Pull companies and seed contact data from a predefined Apollo search or list.",
19901
+ primaryEntity: "company",
19902
+ outputs: ["company", "contact"],
19903
+ stageKey: "populated",
19904
+ dependencyMode: "per-record-eligibility",
19905
+ capabilityKey: "lead-gen.company.apollo-import",
19906
+ defaultBatchSize: 250,
19907
+ maxBatchSize: 1e3
19908
+ },
19909
+ analyzeWebsites: {
19910
+ id: "analyze-websites",
19911
+ label: "Websites analyzed",
19912
+ description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
19913
+ primaryEntity: "company",
19914
+ outputs: ["company"],
19915
+ stageKey: "extracted",
19916
+ dependsOn: ["import-apollo-search"],
19917
+ dependencyMode: "per-record-eligibility",
19918
+ capabilityKey: "lead-gen.company.website-extract",
19919
+ defaultBatchSize: 50,
19920
+ maxBatchSize: 100
19921
+ },
19922
+ scoreDtcFit: {
19923
+ id: "score-dtc-fit",
19924
+ label: "Companies qualified",
19925
+ description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
19926
+ primaryEntity: "company",
19927
+ outputs: ["company"],
19928
+ stageKey: "qualified",
19929
+ dependsOn: ["analyze-websites"],
19930
+ dependencyMode: "per-record-eligibility",
19931
+ capabilityKey: "lead-gen.company.dtc-subscription-qualify",
19932
+ defaultBatchSize: 100,
19933
+ maxBatchSize: 250
19934
+ },
19935
+ enrichDecisionMakers: {
19936
+ id: "enrich-decision-makers",
19937
+ label: "Decision-makers found",
19938
+ description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
19939
+ primaryEntity: "company",
19940
+ outputs: ["contact"],
19941
+ stageKey: "decision-makers-enriched",
19942
+ dependsOn: ["score-dtc-fit"],
19943
+ dependencyMode: "per-record-eligibility",
19944
+ capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
19945
+ defaultBatchSize: 100,
19946
+ maxBatchSize: 250
19947
+ },
19948
+ verifyEmails: {
19949
+ id: "verify-emails",
19950
+ label: "Emails verified",
19951
+ description: "Verify deliverability before the QC and handoff step.",
19952
+ primaryEntity: "contact",
19953
+ outputs: ["contact"],
19954
+ stageKey: "verified",
19955
+ dependsOn: ["enrich-decision-makers"],
19956
+ dependencyMode: "per-record-eligibility",
19957
+ capabilityKey: "lead-gen.contact.verify-email",
19958
+ defaultBatchSize: 250,
19959
+ maxBatchSize: 500
19960
+ },
19961
+ reviewAndExport: {
19962
+ id: "review-and-export",
19963
+ label: "Reviewed and exported",
19964
+ description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
19965
+ primaryEntity: "company",
19966
+ outputs: ["export"],
19967
+ stageKey: "uploaded",
19968
+ dependsOn: ["verify-emails"],
19969
+ dependencyMode: "per-record-eligibility",
19970
+ capabilityKey: "lead-gen.export.list",
19971
+ defaultBatchSize: 100,
19972
+ maxBatchSize: 250
19973
+ }
19974
+ }
19975
+ };
19718
19976
  var OrganizationModelProspectingSchema = z.object({
19719
19977
  listEntityId: ModelIdSchema,
19720
19978
  companyEntityId: ModelIdSchema,
@@ -19725,21 +19983,22 @@ var OrganizationModelProspectingSchema = z.object({
19725
19983
  defaultBuildTemplateId: ModelIdSchema,
19726
19984
  buildTemplates: z.array(ProspectingBuildTemplateSchema).min(1)
19727
19985
  });
19986
+ function toProspectingLifecycleStage(stage) {
19987
+ return {
19988
+ id: stage.key,
19989
+ label: stage.label,
19990
+ order: stage.order
19991
+ };
19992
+ }
19993
+ function leadGenStagesForEntity(entity) {
19994
+ return Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity).sort((a3, b2) => a3.order - b2.order).map(toProspectingLifecycleStage);
19995
+ }
19728
19996
  var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
19729
19997
  listEntityId: "leadgen.list",
19730
19998
  companyEntityId: "leadgen.company",
19731
19999
  contactEntityId: "leadgen.contact",
19732
- companyStages: [
19733
- { id: "populated", label: "Populated", order: 1 },
19734
- { id: "extracted", label: "Extracted", order: 2 },
19735
- { id: "qualified", label: "Qualified", order: 3 }
19736
- ],
19737
- contactStages: [
19738
- { id: "discovered", label: "Discovered", order: 1 },
19739
- { id: "verified", label: "Verified", order: 2 },
19740
- { id: "personalized", label: "Personalized", order: 3 },
19741
- { id: "uploaded", label: "Uploaded", order: 4 }
19742
- ],
20000
+ companyStages: leadGenStagesForEntity("company"),
20001
+ contactStages: leadGenStagesForEntity("contact"),
19743
20002
  defaultBuildTemplateId: "local-services",
19744
20003
  buildTemplates: [
19745
20004
  {
@@ -19747,89 +20006,13 @@ var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
19747
20006
  label: "Local Services Prospecting",
19748
20007
  description: "Curated local-services list build using company sourcing, website analysis, qualification, contact discovery, verification, personalization, and review.",
19749
20008
  steps: [
19750
- {
19751
- id: "source-companies",
19752
- label: "Source companies",
19753
- primaryEntity: "company",
19754
- outputs: ["company"],
19755
- stageKey: "populated",
19756
- dependencyMode: "per-record-eligibility",
19757
- capabilityKey: "lead-gen.company.source",
19758
- defaultBatchSize: 100,
19759
- maxBatchSize: 250
19760
- },
19761
- {
19762
- id: "analyze-websites",
19763
- label: "Analyze websites",
19764
- primaryEntity: "company",
19765
- outputs: ["company"],
19766
- stageKey: "extracted",
19767
- dependsOn: ["source-companies"],
19768
- dependencyMode: "per-record-eligibility",
19769
- capabilityKey: "lead-gen.company.website-extract",
19770
- defaultBatchSize: 50,
19771
- maxBatchSize: 100
19772
- },
19773
- {
19774
- id: "qualify-companies",
19775
- label: "Qualify companies",
19776
- primaryEntity: "company",
19777
- outputs: ["company"],
19778
- stageKey: "qualified",
19779
- dependsOn: ["analyze-websites"],
19780
- dependencyMode: "per-record-eligibility",
19781
- capabilityKey: "lead-gen.company.qualify",
19782
- defaultBatchSize: 100,
19783
- maxBatchSize: 250
19784
- },
19785
- {
19786
- id: "find-contacts",
19787
- label: "Find contacts",
19788
- primaryEntity: "contact",
19789
- outputs: ["contact"],
19790
- stageKey: "discovered",
19791
- dependsOn: ["qualify-companies"],
19792
- dependencyMode: "per-record-eligibility",
19793
- capabilityKey: "lead-gen.contact.discover",
19794
- defaultBatchSize: 50,
19795
- maxBatchSize: 100
19796
- },
19797
- {
19798
- id: "verify-emails",
19799
- label: "Verify emails",
19800
- primaryEntity: "contact",
19801
- outputs: ["contact"],
19802
- stageKey: "verified",
19803
- dependsOn: ["find-contacts"],
19804
- dependencyMode: "per-record-eligibility",
19805
- capabilityKey: "lead-gen.contact.verify-email",
19806
- defaultBatchSize: 100,
19807
- maxBatchSize: 500
19808
- },
19809
- {
19810
- id: "personalize",
19811
- label: "Personalize",
19812
- primaryEntity: "contact",
19813
- outputs: ["contact"],
19814
- stageKey: "personalized",
19815
- dependsOn: ["verify-emails"],
19816
- dependencyMode: "per-record-eligibility",
19817
- capabilityKey: "lead-gen.contact.personalize",
19818
- defaultBatchSize: 25,
19819
- maxBatchSize: 100
19820
- },
19821
- {
19822
- id: "review",
19823
- label: "Review",
19824
- primaryEntity: "contact",
19825
- outputs: ["export"],
19826
- stageKey: "uploaded",
19827
- dependsOn: ["personalize"],
19828
- dependencyMode: "per-record-eligibility",
19829
- capabilityKey: "lead-gen.review.outreach-ready",
19830
- defaultBatchSize: 25,
19831
- maxBatchSize: 100
19832
- }
20009
+ PROSPECTING_STEPS.localServices.sourceCompanies,
20010
+ PROSPECTING_STEPS.localServices.analyzeWebsites,
20011
+ PROSPECTING_STEPS.localServices.qualifyCompanies,
20012
+ PROSPECTING_STEPS.localServices.findContacts,
20013
+ PROSPECTING_STEPS.localServices.verifyEmails,
20014
+ PROSPECTING_STEPS.localServices.personalize,
20015
+ PROSPECTING_STEPS.localServices.review
19833
20016
  ]
19834
20017
  },
19835
20018
  {
@@ -19837,83 +20020,12 @@ var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
19837
20020
  label: "DTC Subscription Apollo Export",
19838
20021
  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.",
19839
20022
  steps: [
19840
- {
19841
- id: "import-apollo-search",
19842
- label: "Import Apollo search",
19843
- description: "Pull companies and seed contact data from a predefined Apollo search or list.",
19844
- primaryEntity: "company",
19845
- outputs: ["company", "contact"],
19846
- stageKey: "populated",
19847
- dependencyMode: "per-record-eligibility",
19848
- capabilityKey: "lead-gen.company.apollo-import",
19849
- defaultBatchSize: 250,
19850
- maxBatchSize: 1e3
19851
- },
19852
- {
19853
- id: "analyze-websites",
19854
- label: "Analyze websites",
19855
- description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
19856
- primaryEntity: "company",
19857
- outputs: ["company"],
19858
- stageKey: "extracted",
19859
- dependsOn: ["import-apollo-search"],
19860
- dependencyMode: "per-record-eligibility",
19861
- capabilityKey: "lead-gen.company.website-extract",
19862
- defaultBatchSize: 50,
19863
- maxBatchSize: 100
19864
- },
19865
- {
19866
- id: "score-dtc-fit",
19867
- label: "Score DTC fit",
19868
- description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
19869
- primaryEntity: "company",
19870
- outputs: ["company"],
19871
- stageKey: "qualified",
19872
- dependsOn: ["analyze-websites"],
19873
- dependencyMode: "per-record-eligibility",
19874
- capabilityKey: "lead-gen.company.dtc-subscription-qualify",
19875
- defaultBatchSize: 100,
19876
- maxBatchSize: 250
19877
- },
19878
- {
19879
- id: "enrich-decision-makers",
19880
- label: "Enrich decision-makers",
19881
- description: "Use Apollo to find qualified contacts such as founders, retention leads, lifecycle leads, and marketing owners.",
19882
- primaryEntity: "contact",
19883
- outputs: ["contact"],
19884
- stageKey: "discovered",
19885
- dependsOn: ["score-dtc-fit"],
19886
- dependencyMode: "per-record-eligibility",
19887
- capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
19888
- defaultBatchSize: 100,
19889
- maxBatchSize: 250
19890
- },
19891
- {
19892
- id: "verify-emails",
19893
- label: "Verify emails",
19894
- description: "Verify deliverability before the QC and handoff step.",
19895
- primaryEntity: "contact",
19896
- outputs: ["contact"],
19897
- stageKey: "verified",
19898
- dependsOn: ["enrich-decision-makers"],
19899
- dependencyMode: "per-record-eligibility",
19900
- capabilityKey: "lead-gen.contact.verify-email",
19901
- defaultBatchSize: 250,
19902
- maxBatchSize: 500
19903
- },
19904
- {
19905
- id: "review-and-export",
19906
- label: "Review and export",
19907
- description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
19908
- primaryEntity: "company",
19909
- outputs: ["export"],
19910
- stageKey: "uploaded",
19911
- dependsOn: ["verify-emails"],
19912
- dependencyMode: "per-record-eligibility",
19913
- capabilityKey: "lead-gen.export.list",
19914
- defaultBatchSize: 100,
19915
- maxBatchSize: 250
19916
- }
20023
+ PROSPECTING_STEPS.dtcApolloClickup.importApolloSearch,
20024
+ PROSPECTING_STEPS.dtcApolloClickup.analyzeWebsites,
20025
+ PROSPECTING_STEPS.dtcApolloClickup.scoreDtcFit,
20026
+ PROSPECTING_STEPS.dtcApolloClickup.enrichDecisionMakers,
20027
+ PROSPECTING_STEPS.dtcApolloClickup.verifyEmails,
20028
+ PROSPECTING_STEPS.dtcApolloClickup.reviewAndExport
19917
20029
  ]
19918
20030
  }
19919
20031
  ]
@@ -20342,6 +20454,8 @@ var DEFAULT_ORGANIZATION_MODEL_STATUSES = {
20342
20454
  var KnowledgeLinkSchema = z.object({
20343
20455
  nodeId: NodeIdStringSchema
20344
20456
  });
20457
+ var KnowledgeSkillBindingSchema = z.string().trim().min(1).max(120);
20458
+ var KnowledgeDomainBindingSchema = z.string().trim().min(1).max(80);
20345
20459
  var OrgKnowledgeKindSchema = z.enum(["playbook", "strategy", "reference"]);
20346
20460
  var OrgKnowledgeNodeSchema = z.object({
20347
20461
  id: ModelIdSchema,
@@ -20356,6 +20470,10 @@ var OrgKnowledgeNodeSchema = z.object({
20356
20470
  * Each link emits a `governs` edge: knowledge-node -> target node.
20357
20471
  */
20358
20472
  links: z.array(KnowledgeLinkSchema).default([]),
20473
+ /** Operator skill or command bindings relevant to this node. */
20474
+ skills: z.array(KnowledgeSkillBindingSchema).optional(),
20475
+ /** Domain key used to derive fast graph->skill registries. */
20476
+ domain: KnowledgeDomainBindingSchema.optional(),
20359
20477
  /** Identifiers of the roles or members who own this knowledge node. */
20360
20478
  ownerIds: z.array(ModelIdSchema).default([]),
20361
20479
  /** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
@@ -20409,8 +20527,12 @@ var LEGACY_FEATURE_ALIASES = /* @__PURE__ */ new Map([
20409
20527
  function hasFeature(featuresById, featureId) {
20410
20528
  return featuresById.has(featureId) || featuresById.has(LEGACY_FEATURE_ALIASES.get(featureId) ?? "");
20411
20529
  }
20530
+ function defaultFeaturePathFor(id) {
20531
+ return `/${id.replaceAll(".", "/")}`;
20532
+ }
20412
20533
  var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
20413
20534
  const featuresById = collectIds(model.features, ctx, ["features"], "Feature");
20535
+ const featureIdsByEffectivePath = /* @__PURE__ */ new Map();
20414
20536
  model.features.forEach((feature, featureIndex) => {
20415
20537
  const segments = feature.id.split(".");
20416
20538
  if (segments.length > 1) {
@@ -20426,6 +20548,20 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
20426
20548
  const hasChildren = model.features.some(
20427
20549
  (candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.id !== feature.id
20428
20550
  );
20551
+ const contributesRoutePath = feature.path !== void 0 || !hasChildren;
20552
+ if (contributesRoutePath) {
20553
+ const effectivePath = feature.path ?? defaultFeaturePathFor(feature.id);
20554
+ const existingFeatureId = featureIdsByEffectivePath.get(effectivePath);
20555
+ if (existingFeatureId !== void 0) {
20556
+ addIssue(
20557
+ ctx,
20558
+ ["features", featureIndex, feature.path === void 0 ? "id" : "path"],
20559
+ `Feature "${feature.id}" effective path "${effectivePath}" duplicates feature "${existingFeatureId}"`
20560
+ );
20561
+ } else {
20562
+ featureIdsByEffectivePath.set(effectivePath, feature.id);
20563
+ }
20564
+ }
20429
20565
  if (hasChildren && feature.enabled) {
20430
20566
  const hasEnabledDescendant = model.features.some(
20431
20567
  (candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.enabled
@@ -20439,6 +20575,43 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
20439
20575
  }
20440
20576
  }
20441
20577
  });
20578
+ const surfacesById = collectIds(model.navigation.surfaces, ctx, ["navigation", "surfaces"], "Navigation surface");
20579
+ if (model.navigation.defaultSurfaceId !== void 0 && !surfacesById.has(model.navigation.defaultSurfaceId)) {
20580
+ addIssue(
20581
+ ctx,
20582
+ ["navigation", "defaultSurfaceId"],
20583
+ `Navigation defaultSurfaceId references unknown surface "${model.navigation.defaultSurfaceId}"`
20584
+ );
20585
+ }
20586
+ model.navigation.groups.forEach((group, groupIndex) => {
20587
+ group.surfaceIds.forEach((surfaceId, surfaceIndex) => {
20588
+ if (!surfacesById.has(surfaceId)) {
20589
+ addIssue(
20590
+ ctx,
20591
+ ["navigation", "groups", groupIndex, "surfaceIds", surfaceIndex],
20592
+ `Navigation group "${group.id}" references unknown surface "${surfaceId}"`
20593
+ );
20594
+ }
20595
+ });
20596
+ });
20597
+ model.navigation.surfaces.forEach((surface, surfaceIndex) => {
20598
+ if (surface.featureId !== void 0 && !hasFeature(featuresById, surface.featureId)) {
20599
+ addIssue(
20600
+ ctx,
20601
+ ["navigation", "surfaces", surfaceIndex, "featureId"],
20602
+ `Navigation surface "${surface.id}" references unknown feature "${surface.featureId}"`
20603
+ );
20604
+ }
20605
+ surface.featureIds.forEach((featureId, featureIndex) => {
20606
+ if (!hasFeature(featuresById, featureId)) {
20607
+ addIssue(
20608
+ ctx,
20609
+ ["navigation", "surfaces", surfaceIndex, "featureIds", featureIndex],
20610
+ `Navigation surface "${surface.id}" references unknown feature "${featureId}"`
20611
+ );
20612
+ }
20613
+ });
20614
+ });
20442
20615
  const segmentsById = new Map(model.customers.segments.map((seg) => [seg.id, seg]));
20443
20616
  model.offerings.products.forEach((product, productIndex) => {
20444
20617
  product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
@@ -20606,6 +20779,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
20606
20779
  enabled: true,
20607
20780
  uiPosition: "sidebar-primary"
20608
20781
  },
20782
+ {
20783
+ id: "monitoring.calendar",
20784
+ label: "Calendar",
20785
+ description: "Google Calendar events and agenda views",
20786
+ enabled: true,
20787
+ path: "/monitoring/calendar",
20788
+ icon: "feature.calendar"
20789
+ },
20609
20790
  {
20610
20791
  id: "monitoring.activity-log",
20611
20792
  label: "Activity Log",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/core",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "license": "MIT",
5
5
  "description": "Minimal shared constants across Elevasis monorepo",
6
6
  "sideEffects": false,
@@ -41,13 +41,14 @@
41
41
  "rollup-plugin-dts": "^6.3.0",
42
42
  "tsup": "^8.0.0",
43
43
  "typescript": "5.9.2",
44
- "@repo/eslint-config": "0.0.0",
45
- "@repo/typescript-config": "0.0.0"
44
+ "@repo/typescript-config": "0.0.0",
45
+ "@repo/eslint-config": "0.0.0"
46
46
  },
47
47
  "dependencies": {
48
48
  "@anthropic-ai/sdk": "^0.62.0",
49
49
  "yaml": "^2.8.1",
50
50
  "@google/genai": "^1.30.0",
51
+ "@googleapis/calendar": "^14.0.0",
51
52
  "@googleapis/gmail": "^15.0.0",
52
53
  "@googleapis/sheets": "^12.0.0",
53
54
  "@sentry/node": "^8.55.0",