@elevasis/sdk 1.17.0 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -36595,7 +36595,7 @@ var CredentialNameSchema = external_exports.string().trim().toLowerCase().min(1,
36595
36595
  /^[a-z0-9]+(-[a-z0-9]+)+$/,
36596
36596
  "Credential name must be lowercase letters, numbers, and hyphens in format: service-environment (e.g., gmail-prod, attio-dev)"
36597
36597
  );
36598
- var OAuthProviderSchema = external_exports.enum(["google-sheets", "dropbox"]);
36598
+ var OAuthProviderSchema = external_exports.enum(["google-sheets", "google-calendar", "dropbox"]);
36599
36599
  var OAuthCodeSchema = external_exports.string().min(10, "Authorization code too short").max(1e3, "Authorization code too long");
36600
36600
  var OAuthStateParamSchema = external_exports.string().min(10, "State parameter too short").max(2048, "State parameter too long");
36601
36601
  var SanitizedStringSchema = external_exports.string().trim().transform((str) => str.replace(/[<>'"]/g, ""));
@@ -36614,6 +36614,7 @@ var DateRangeSchema = external_exports.object({
36614
36614
  // ../core/src/organization-model/icons.ts
36615
36615
  var ORGANIZATION_MODEL_ICON_TOKENS = [
36616
36616
  "nav.dashboard",
36617
+ "nav.calendar",
36617
36618
  "nav.sales",
36618
36619
  "nav.crm",
36619
36620
  "nav.lead-gen",
@@ -36628,6 +36629,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
36628
36629
  "knowledge.strategy",
36629
36630
  "knowledge.reference",
36630
36631
  "feature.dashboard",
36632
+ "feature.calendar",
36631
36633
  "feature.sales",
36632
36634
  "feature.crm",
36633
36635
  "feature.finance",
@@ -36651,6 +36653,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
36651
36653
  "integration.google-sheets",
36652
36654
  "integration.attio",
36653
36655
  "surface.dashboard",
36656
+ "surface.calendar",
36654
36657
  "surface.overview",
36655
36658
  "surface.command-view",
36656
36659
  "surface.command-queue",
@@ -36850,6 +36853,89 @@ var DEFAULT_ORGANIZATION_MODEL_SALES = {
36850
36853
  }
36851
36854
  ]
36852
36855
  };
36856
+ var LEAD_GEN_STAGE_CATALOG = {
36857
+ // Prospecting — company population
36858
+ scraped: {
36859
+ key: "scraped",
36860
+ label: "Scraped",
36861
+ description: "Company was scraped from a source directory (Apify actor run).",
36862
+ order: 1,
36863
+ entity: "company"
36864
+ },
36865
+ populated: {
36866
+ key: "populated",
36867
+ label: "Companies found",
36868
+ description: "Companies have been found and added to the lead-gen list.",
36869
+ order: 2,
36870
+ entity: "company"
36871
+ },
36872
+ extracted: {
36873
+ key: "extracted",
36874
+ label: "Websites analyzed",
36875
+ description: "Company websites have been analyzed for business signals.",
36876
+ order: 3,
36877
+ entity: "company"
36878
+ },
36879
+ enriched: {
36880
+ key: "enriched",
36881
+ label: "Enriched",
36882
+ description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
36883
+ order: 4,
36884
+ entity: "company"
36885
+ },
36886
+ "decision-makers-enriched": {
36887
+ key: "decision-makers-enriched",
36888
+ label: "Decision-makers found",
36889
+ description: "Decision-maker contacts discovered and attached to a qualified company.",
36890
+ order: 6,
36891
+ entity: "company"
36892
+ },
36893
+ // Prospecting — contact discovery
36894
+ discovered: {
36895
+ key: "discovered",
36896
+ label: "Decision-makers found",
36897
+ description: "Decision-maker contact details have been found.",
36898
+ order: 5,
36899
+ entity: "contact"
36900
+ },
36901
+ verified: {
36902
+ key: "verified",
36903
+ label: "Emails verified",
36904
+ description: "Contact email addresses have been checked for deliverability.",
36905
+ order: 7,
36906
+ entity: "contact"
36907
+ },
36908
+ // Qualification
36909
+ qualified: {
36910
+ key: "qualified",
36911
+ label: "Companies qualified",
36912
+ description: "Companies have been scored against the qualification criteria.",
36913
+ order: 8,
36914
+ entity: "company"
36915
+ },
36916
+ // Outreach
36917
+ personalized: {
36918
+ key: "personalized",
36919
+ label: "Personalized",
36920
+ description: "Outreach message personalized for the contact (Instantly personalization workflow).",
36921
+ order: 9,
36922
+ entity: "contact"
36923
+ },
36924
+ uploaded: {
36925
+ key: "uploaded",
36926
+ label: "Reviewed and exported",
36927
+ description: "Approved records have been reviewed and exported for handoff.",
36928
+ order: 10,
36929
+ entity: "contact"
36930
+ },
36931
+ interested: {
36932
+ key: "interested",
36933
+ label: "Interested",
36934
+ description: "Contact replied with a positive signal (Instantly reply-handler transition).",
36935
+ order: 11,
36936
+ entity: "contact"
36937
+ }
36938
+ };
36853
36939
 
36854
36940
  // ../core/src/organization-model/domains/projects.ts
36855
36941
  var ProjectsDomainStateSchema = DisplayMetadataSchema.extend({
@@ -36919,6 +37005,252 @@ var ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
36919
37005
  id: ModelIdSchema,
36920
37006
  steps: external_exports.array(ProspectingBuildTemplateStepSchema).min(1)
36921
37007
  });
37008
+ var CapabilitySchema = external_exports.object({
37009
+ id: ModelIdSchema,
37010
+ label: external_exports.string(),
37011
+ description: external_exports.string(),
37012
+ resourceId: ModelIdSchema
37013
+ });
37014
+ var CAPABILITY_REGISTRY = [
37015
+ {
37016
+ id: "lead-gen.company.source",
37017
+ label: "Source companies",
37018
+ description: "Import source companies from a list provider.",
37019
+ resourceId: "lgn-import-workflow"
37020
+ },
37021
+ {
37022
+ id: "lead-gen.company.apollo-import",
37023
+ label: "Import from Apollo",
37024
+ description: "Pull companies and seed contact data from an Apollo search or list.",
37025
+ resourceId: "lgn-01c-apollo-import-workflow"
37026
+ },
37027
+ {
37028
+ id: "lead-gen.contact.discover",
37029
+ label: "Discover contact emails",
37030
+ description: "Find email addresses for contacts at qualified companies.",
37031
+ resourceId: "lgn-04-email-discovery-workflow"
37032
+ },
37033
+ {
37034
+ id: "lead-gen.contact.verify-email",
37035
+ label: "Verify emails",
37036
+ description: "Check email deliverability before outreach.",
37037
+ resourceId: "lgn-05-email-verification-workflow"
37038
+ },
37039
+ {
37040
+ id: "lead-gen.company.website-extract",
37041
+ label: "Extract website signals",
37042
+ description: "Scrape and analyze company websites for qualification signals.",
37043
+ resourceId: "lgn-02-website-extract-workflow"
37044
+ },
37045
+ {
37046
+ id: "lead-gen.company.qualify",
37047
+ label: "Qualify companies",
37048
+ description: "Score and filter companies against the ICP rubric.",
37049
+ resourceId: "lgn-03-company-qualification-workflow"
37050
+ },
37051
+ {
37052
+ id: "lead-gen.company.dtc-subscription-qualify",
37053
+ label: "Qualify DTC subscription fit",
37054
+ description: "Classify subscription potential and consumable-product fit for DTC brands.",
37055
+ resourceId: "lgn-03b-dtc-subscription-score-workflow"
37056
+ },
37057
+ {
37058
+ id: "lead-gen.contact.apollo-decision-maker-enrich",
37059
+ label: "Enrich decision-makers",
37060
+ description: "Find and enrich qualified contacts at qualified companies via Apollo.",
37061
+ resourceId: "lgn-04b-apollo-decision-maker-enrich-workflow"
37062
+ },
37063
+ {
37064
+ id: "lead-gen.contact.personalize",
37065
+ label: "Personalize outreach",
37066
+ description: "Generate personalized opening lines for each contact.",
37067
+ resourceId: "ist-personalization-workflow"
37068
+ },
37069
+ {
37070
+ id: "lead-gen.review.outreach-ready",
37071
+ label: "Upload to outreach",
37072
+ description: "Upload approved contacts to the outreach sequence after QC review.",
37073
+ resourceId: "ist-upload-contacts-workflow"
37074
+ },
37075
+ {
37076
+ id: "lead-gen.export.list",
37077
+ label: "Export lead list",
37078
+ description: "Export approved leads as a downloadable lead list.",
37079
+ resourceId: "lgn-06-export-list-workflow"
37080
+ },
37081
+ {
37082
+ id: "lead-gen.company.cleanup",
37083
+ label: "Clean up companies",
37084
+ description: "Remove disqualified or duplicate companies from the list.",
37085
+ resourceId: "lgn-company-cleanup-workflow"
37086
+ }
37087
+ ];
37088
+ var PROSPECTING_STEPS = {
37089
+ localServices: {
37090
+ sourceCompanies: {
37091
+ id: "source-companies",
37092
+ label: "Companies found",
37093
+ primaryEntity: "company",
37094
+ outputs: ["company"],
37095
+ stageKey: "populated",
37096
+ dependencyMode: "per-record-eligibility",
37097
+ capabilityKey: "lead-gen.company.source",
37098
+ defaultBatchSize: 100,
37099
+ maxBatchSize: 250
37100
+ },
37101
+ analyzeWebsites: {
37102
+ id: "analyze-websites",
37103
+ label: "Websites analyzed",
37104
+ primaryEntity: "company",
37105
+ outputs: ["company"],
37106
+ stageKey: "extracted",
37107
+ dependsOn: ["source-companies"],
37108
+ dependencyMode: "per-record-eligibility",
37109
+ capabilityKey: "lead-gen.company.website-extract",
37110
+ defaultBatchSize: 50,
37111
+ maxBatchSize: 100
37112
+ },
37113
+ qualifyCompanies: {
37114
+ id: "qualify-companies",
37115
+ label: "Companies qualified",
37116
+ primaryEntity: "company",
37117
+ outputs: ["company"],
37118
+ stageKey: "qualified",
37119
+ dependsOn: ["analyze-websites"],
37120
+ dependencyMode: "per-record-eligibility",
37121
+ capabilityKey: "lead-gen.company.qualify",
37122
+ defaultBatchSize: 100,
37123
+ maxBatchSize: 250
37124
+ },
37125
+ findContacts: {
37126
+ id: "find-contacts",
37127
+ label: "Decision-makers found",
37128
+ primaryEntity: "contact",
37129
+ outputs: ["contact"],
37130
+ stageKey: "discovered",
37131
+ dependsOn: ["qualify-companies"],
37132
+ dependencyMode: "per-record-eligibility",
37133
+ capabilityKey: "lead-gen.contact.discover",
37134
+ defaultBatchSize: 50,
37135
+ maxBatchSize: 100
37136
+ },
37137
+ verifyEmails: {
37138
+ id: "verify-emails",
37139
+ label: "Emails verified",
37140
+ primaryEntity: "contact",
37141
+ outputs: ["contact"],
37142
+ stageKey: "verified",
37143
+ dependsOn: ["find-contacts"],
37144
+ dependencyMode: "per-record-eligibility",
37145
+ capabilityKey: "lead-gen.contact.verify-email",
37146
+ defaultBatchSize: 100,
37147
+ maxBatchSize: 500
37148
+ },
37149
+ personalize: {
37150
+ id: "personalize",
37151
+ label: "Personalize",
37152
+ primaryEntity: "contact",
37153
+ outputs: ["contact"],
37154
+ stageKey: "personalized",
37155
+ dependsOn: ["verify-emails"],
37156
+ dependencyMode: "per-record-eligibility",
37157
+ capabilityKey: "lead-gen.contact.personalize",
37158
+ defaultBatchSize: 25,
37159
+ maxBatchSize: 100
37160
+ },
37161
+ review: {
37162
+ id: "review",
37163
+ label: "Reviewed and exported",
37164
+ primaryEntity: "contact",
37165
+ outputs: ["export"],
37166
+ stageKey: "uploaded",
37167
+ dependsOn: ["personalize"],
37168
+ dependencyMode: "per-record-eligibility",
37169
+ capabilityKey: "lead-gen.review.outreach-ready",
37170
+ defaultBatchSize: 25,
37171
+ maxBatchSize: 100
37172
+ }
37173
+ },
37174
+ dtcApolloClickup: {
37175
+ importApolloSearch: {
37176
+ id: "import-apollo-search",
37177
+ label: "Companies found",
37178
+ description: "Pull companies and seed contact data from a predefined Apollo search or list.",
37179
+ primaryEntity: "company",
37180
+ outputs: ["company", "contact"],
37181
+ stageKey: "populated",
37182
+ dependencyMode: "per-record-eligibility",
37183
+ capabilityKey: "lead-gen.company.apollo-import",
37184
+ defaultBatchSize: 250,
37185
+ maxBatchSize: 1e3
37186
+ },
37187
+ analyzeWebsites: {
37188
+ id: "analyze-websites",
37189
+ label: "Websites analyzed",
37190
+ description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
37191
+ primaryEntity: "company",
37192
+ outputs: ["company"],
37193
+ stageKey: "extracted",
37194
+ dependsOn: ["import-apollo-search"],
37195
+ dependencyMode: "per-record-eligibility",
37196
+ capabilityKey: "lead-gen.company.website-extract",
37197
+ defaultBatchSize: 50,
37198
+ maxBatchSize: 100
37199
+ },
37200
+ scoreDtcFit: {
37201
+ id: "score-dtc-fit",
37202
+ label: "Companies qualified",
37203
+ description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
37204
+ primaryEntity: "company",
37205
+ outputs: ["company"],
37206
+ stageKey: "qualified",
37207
+ dependsOn: ["analyze-websites"],
37208
+ dependencyMode: "per-record-eligibility",
37209
+ capabilityKey: "lead-gen.company.dtc-subscription-qualify",
37210
+ defaultBatchSize: 100,
37211
+ maxBatchSize: 250
37212
+ },
37213
+ enrichDecisionMakers: {
37214
+ id: "enrich-decision-makers",
37215
+ label: "Decision-makers found",
37216
+ description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
37217
+ primaryEntity: "company",
37218
+ outputs: ["contact"],
37219
+ stageKey: "decision-makers-enriched",
37220
+ dependsOn: ["score-dtc-fit"],
37221
+ dependencyMode: "per-record-eligibility",
37222
+ capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
37223
+ defaultBatchSize: 100,
37224
+ maxBatchSize: 250
37225
+ },
37226
+ verifyEmails: {
37227
+ id: "verify-emails",
37228
+ label: "Emails verified",
37229
+ description: "Verify deliverability before the QC and handoff step.",
37230
+ primaryEntity: "contact",
37231
+ outputs: ["contact"],
37232
+ stageKey: "verified",
37233
+ dependsOn: ["enrich-decision-makers"],
37234
+ dependencyMode: "per-record-eligibility",
37235
+ capabilityKey: "lead-gen.contact.verify-email",
37236
+ defaultBatchSize: 250,
37237
+ maxBatchSize: 500
37238
+ },
37239
+ reviewAndExport: {
37240
+ id: "review-and-export",
37241
+ label: "Reviewed and exported",
37242
+ description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
37243
+ primaryEntity: "company",
37244
+ outputs: ["export"],
37245
+ stageKey: "uploaded",
37246
+ dependsOn: ["verify-emails"],
37247
+ dependencyMode: "per-record-eligibility",
37248
+ capabilityKey: "lead-gen.export.list",
37249
+ defaultBatchSize: 100,
37250
+ maxBatchSize: 250
37251
+ }
37252
+ }
37253
+ };
36922
37254
  var OrganizationModelProspectingSchema = external_exports.object({
36923
37255
  listEntityId: ModelIdSchema,
36924
37256
  companyEntityId: ModelIdSchema,
@@ -36929,21 +37261,22 @@ var OrganizationModelProspectingSchema = external_exports.object({
36929
37261
  defaultBuildTemplateId: ModelIdSchema,
36930
37262
  buildTemplates: external_exports.array(ProspectingBuildTemplateSchema).min(1)
36931
37263
  });
37264
+ function toProspectingLifecycleStage(stage) {
37265
+ return {
37266
+ id: stage.key,
37267
+ label: stage.label,
37268
+ order: stage.order
37269
+ };
37270
+ }
37271
+ function leadGenStagesForEntity(entity) {
37272
+ return Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity).sort((a, b) => a.order - b.order).map(toProspectingLifecycleStage);
37273
+ }
36932
37274
  var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
36933
37275
  listEntityId: "leadgen.list",
36934
37276
  companyEntityId: "leadgen.company",
36935
37277
  contactEntityId: "leadgen.contact",
36936
- companyStages: [
36937
- { id: "populated", label: "Populated", order: 1 },
36938
- { id: "extracted", label: "Extracted", order: 2 },
36939
- { id: "qualified", label: "Qualified", order: 3 }
36940
- ],
36941
- contactStages: [
36942
- { id: "discovered", label: "Discovered", order: 1 },
36943
- { id: "verified", label: "Verified", order: 2 },
36944
- { id: "personalized", label: "Personalized", order: 3 },
36945
- { id: "uploaded", label: "Uploaded", order: 4 }
36946
- ],
37278
+ companyStages: leadGenStagesForEntity("company"),
37279
+ contactStages: leadGenStagesForEntity("contact"),
36947
37280
  defaultBuildTemplateId: "local-services",
36948
37281
  buildTemplates: [
36949
37282
  {
@@ -36951,89 +37284,13 @@ var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
36951
37284
  label: "Local Services Prospecting",
36952
37285
  description: "Curated local-services list build using company sourcing, website analysis, qualification, contact discovery, verification, personalization, and review.",
36953
37286
  steps: [
36954
- {
36955
- id: "source-companies",
36956
- label: "Source companies",
36957
- primaryEntity: "company",
36958
- outputs: ["company"],
36959
- stageKey: "populated",
36960
- dependencyMode: "per-record-eligibility",
36961
- capabilityKey: "lead-gen.company.source",
36962
- defaultBatchSize: 100,
36963
- maxBatchSize: 250
36964
- },
36965
- {
36966
- id: "analyze-websites",
36967
- label: "Analyze websites",
36968
- primaryEntity: "company",
36969
- outputs: ["company"],
36970
- stageKey: "extracted",
36971
- dependsOn: ["source-companies"],
36972
- dependencyMode: "per-record-eligibility",
36973
- capabilityKey: "lead-gen.company.website-extract",
36974
- defaultBatchSize: 50,
36975
- maxBatchSize: 100
36976
- },
36977
- {
36978
- id: "qualify-companies",
36979
- label: "Qualify companies",
36980
- primaryEntity: "company",
36981
- outputs: ["company"],
36982
- stageKey: "qualified",
36983
- dependsOn: ["analyze-websites"],
36984
- dependencyMode: "per-record-eligibility",
36985
- capabilityKey: "lead-gen.company.qualify",
36986
- defaultBatchSize: 100,
36987
- maxBatchSize: 250
36988
- },
36989
- {
36990
- id: "find-contacts",
36991
- label: "Find contacts",
36992
- primaryEntity: "contact",
36993
- outputs: ["contact"],
36994
- stageKey: "discovered",
36995
- dependsOn: ["qualify-companies"],
36996
- dependencyMode: "per-record-eligibility",
36997
- capabilityKey: "lead-gen.contact.discover",
36998
- defaultBatchSize: 50,
36999
- maxBatchSize: 100
37000
- },
37001
- {
37002
- id: "verify-emails",
37003
- label: "Verify emails",
37004
- primaryEntity: "contact",
37005
- outputs: ["contact"],
37006
- stageKey: "verified",
37007
- dependsOn: ["find-contacts"],
37008
- dependencyMode: "per-record-eligibility",
37009
- capabilityKey: "lead-gen.contact.verify-email",
37010
- defaultBatchSize: 100,
37011
- maxBatchSize: 500
37012
- },
37013
- {
37014
- id: "personalize",
37015
- label: "Personalize",
37016
- primaryEntity: "contact",
37017
- outputs: ["contact"],
37018
- stageKey: "personalized",
37019
- dependsOn: ["verify-emails"],
37020
- dependencyMode: "per-record-eligibility",
37021
- capabilityKey: "lead-gen.contact.personalize",
37022
- defaultBatchSize: 25,
37023
- maxBatchSize: 100
37024
- },
37025
- {
37026
- id: "review",
37027
- label: "Review",
37028
- primaryEntity: "contact",
37029
- outputs: ["export"],
37030
- stageKey: "uploaded",
37031
- dependsOn: ["personalize"],
37032
- dependencyMode: "per-record-eligibility",
37033
- capabilityKey: "lead-gen.review.outreach-ready",
37034
- defaultBatchSize: 25,
37035
- maxBatchSize: 100
37036
- }
37287
+ PROSPECTING_STEPS.localServices.sourceCompanies,
37288
+ PROSPECTING_STEPS.localServices.analyzeWebsites,
37289
+ PROSPECTING_STEPS.localServices.qualifyCompanies,
37290
+ PROSPECTING_STEPS.localServices.findContacts,
37291
+ PROSPECTING_STEPS.localServices.verifyEmails,
37292
+ PROSPECTING_STEPS.localServices.personalize,
37293
+ PROSPECTING_STEPS.localServices.review
37037
37294
  ]
37038
37295
  },
37039
37296
  {
@@ -37041,83 +37298,12 @@ var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
37041
37298
  label: "DTC Subscription Apollo Export",
37042
37299
  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.",
37043
37300
  steps: [
37044
- {
37045
- id: "import-apollo-search",
37046
- label: "Import Apollo search",
37047
- description: "Pull companies and seed contact data from a predefined Apollo search or list.",
37048
- primaryEntity: "company",
37049
- outputs: ["company", "contact"],
37050
- stageKey: "populated",
37051
- dependencyMode: "per-record-eligibility",
37052
- capabilityKey: "lead-gen.company.apollo-import",
37053
- defaultBatchSize: 250,
37054
- maxBatchSize: 1e3
37055
- },
37056
- {
37057
- id: "analyze-websites",
37058
- label: "Analyze websites",
37059
- description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
37060
- primaryEntity: "company",
37061
- outputs: ["company"],
37062
- stageKey: "extracted",
37063
- dependsOn: ["import-apollo-search"],
37064
- dependencyMode: "per-record-eligibility",
37065
- capabilityKey: "lead-gen.company.website-extract",
37066
- defaultBatchSize: 50,
37067
- maxBatchSize: 100
37068
- },
37069
- {
37070
- id: "score-dtc-fit",
37071
- label: "Score DTC fit",
37072
- description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
37073
- primaryEntity: "company",
37074
- outputs: ["company"],
37075
- stageKey: "qualified",
37076
- dependsOn: ["analyze-websites"],
37077
- dependencyMode: "per-record-eligibility",
37078
- capabilityKey: "lead-gen.company.dtc-subscription-qualify",
37079
- defaultBatchSize: 100,
37080
- maxBatchSize: 250
37081
- },
37082
- {
37083
- id: "enrich-decision-makers",
37084
- label: "Enrich decision-makers",
37085
- description: "Use Apollo to find qualified contacts such as founders, retention leads, lifecycle leads, and marketing owners.",
37086
- primaryEntity: "contact",
37087
- outputs: ["contact"],
37088
- stageKey: "discovered",
37089
- dependsOn: ["score-dtc-fit"],
37090
- dependencyMode: "per-record-eligibility",
37091
- capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
37092
- defaultBatchSize: 100,
37093
- maxBatchSize: 250
37094
- },
37095
- {
37096
- id: "verify-emails",
37097
- label: "Verify emails",
37098
- description: "Verify deliverability before the QC and handoff step.",
37099
- primaryEntity: "contact",
37100
- outputs: ["contact"],
37101
- stageKey: "verified",
37102
- dependsOn: ["enrich-decision-makers"],
37103
- dependencyMode: "per-record-eligibility",
37104
- capabilityKey: "lead-gen.contact.verify-email",
37105
- defaultBatchSize: 250,
37106
- maxBatchSize: 500
37107
- },
37108
- {
37109
- id: "review-and-export",
37110
- label: "Review and export",
37111
- description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
37112
- primaryEntity: "company",
37113
- outputs: ["export"],
37114
- stageKey: "uploaded",
37115
- dependsOn: ["verify-emails"],
37116
- dependencyMode: "per-record-eligibility",
37117
- capabilityKey: "lead-gen.export.list",
37118
- defaultBatchSize: 100,
37119
- maxBatchSize: 250
37120
- }
37301
+ PROSPECTING_STEPS.dtcApolloClickup.importApolloSearch,
37302
+ PROSPECTING_STEPS.dtcApolloClickup.analyzeWebsites,
37303
+ PROSPECTING_STEPS.dtcApolloClickup.scoreDtcFit,
37304
+ PROSPECTING_STEPS.dtcApolloClickup.enrichDecisionMakers,
37305
+ PROSPECTING_STEPS.dtcApolloClickup.verifyEmails,
37306
+ PROSPECTING_STEPS.dtcApolloClickup.reviewAndExport
37121
37307
  ]
37122
37308
  }
37123
37309
  ]
@@ -37564,6 +37750,8 @@ var DEFAULT_ORGANIZATION_MODEL_STATUSES = {
37564
37750
  var KnowledgeLinkSchema = external_exports.object({
37565
37751
  nodeId: NodeIdStringSchema
37566
37752
  });
37753
+ var KnowledgeSkillBindingSchema = external_exports.string().trim().min(1).max(120);
37754
+ var KnowledgeDomainBindingSchema = external_exports.string().trim().min(1).max(80);
37567
37755
  var OrgKnowledgeKindSchema = external_exports.enum(["playbook", "strategy", "reference"]);
37568
37756
  var OrgKnowledgeNodeSchema = external_exports.object({
37569
37757
  id: ModelIdSchema,
@@ -37578,6 +37766,10 @@ var OrgKnowledgeNodeSchema = external_exports.object({
37578
37766
  * Each link emits a `governs` edge: knowledge-node -> target node.
37579
37767
  */
37580
37768
  links: external_exports.array(KnowledgeLinkSchema).default([]),
37769
+ /** Operator skill or command bindings relevant to this node. */
37770
+ skills: external_exports.array(KnowledgeSkillBindingSchema).optional(),
37771
+ /** Domain key used to derive fast graph->skill registries. */
37772
+ domain: KnowledgeDomainBindingSchema.optional(),
37581
37773
  /** Identifiers of the roles or members who own this knowledge node. */
37582
37774
  ownerIds: external_exports.array(ModelIdSchema).default([]),
37583
37775
  /** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
@@ -37631,8 +37823,12 @@ var LEGACY_FEATURE_ALIASES = /* @__PURE__ */ new Map([
37631
37823
  function hasFeature(featuresById, featureId) {
37632
37824
  return featuresById.has(featureId) || featuresById.has(LEGACY_FEATURE_ALIASES.get(featureId) ?? "");
37633
37825
  }
37826
+ function defaultFeaturePathFor(id) {
37827
+ return `/${id.replaceAll(".", "/")}`;
37828
+ }
37634
37829
  var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
37635
37830
  const featuresById = collectIds(model.features, ctx, ["features"], "Feature");
37831
+ const featureIdsByEffectivePath = /* @__PURE__ */ new Map();
37636
37832
  model.features.forEach((feature, featureIndex) => {
37637
37833
  const segments = feature.id.split(".");
37638
37834
  if (segments.length > 1) {
@@ -37648,6 +37844,20 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
37648
37844
  const hasChildren = model.features.some(
37649
37845
  (candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.id !== feature.id
37650
37846
  );
37847
+ const contributesRoutePath = feature.path !== void 0 || !hasChildren;
37848
+ if (contributesRoutePath) {
37849
+ const effectivePath = feature.path ?? defaultFeaturePathFor(feature.id);
37850
+ const existingFeatureId = featureIdsByEffectivePath.get(effectivePath);
37851
+ if (existingFeatureId !== void 0) {
37852
+ addIssue(
37853
+ ctx,
37854
+ ["features", featureIndex, feature.path === void 0 ? "id" : "path"],
37855
+ `Feature "${feature.id}" effective path "${effectivePath}" duplicates feature "${existingFeatureId}"`
37856
+ );
37857
+ } else {
37858
+ featureIdsByEffectivePath.set(effectivePath, feature.id);
37859
+ }
37860
+ }
37651
37861
  if (hasChildren && feature.enabled) {
37652
37862
  const hasEnabledDescendant = model.features.some(
37653
37863
  (candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.enabled
@@ -37661,6 +37871,43 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
37661
37871
  }
37662
37872
  }
37663
37873
  });
37874
+ const surfacesById = collectIds(model.navigation.surfaces, ctx, ["navigation", "surfaces"], "Navigation surface");
37875
+ if (model.navigation.defaultSurfaceId !== void 0 && !surfacesById.has(model.navigation.defaultSurfaceId)) {
37876
+ addIssue(
37877
+ ctx,
37878
+ ["navigation", "defaultSurfaceId"],
37879
+ `Navigation defaultSurfaceId references unknown surface "${model.navigation.defaultSurfaceId}"`
37880
+ );
37881
+ }
37882
+ model.navigation.groups.forEach((group, groupIndex) => {
37883
+ group.surfaceIds.forEach((surfaceId, surfaceIndex) => {
37884
+ if (!surfacesById.has(surfaceId)) {
37885
+ addIssue(
37886
+ ctx,
37887
+ ["navigation", "groups", groupIndex, "surfaceIds", surfaceIndex],
37888
+ `Navigation group "${group.id}" references unknown surface "${surfaceId}"`
37889
+ );
37890
+ }
37891
+ });
37892
+ });
37893
+ model.navigation.surfaces.forEach((surface, surfaceIndex) => {
37894
+ if (surface.featureId !== void 0 && !hasFeature(featuresById, surface.featureId)) {
37895
+ addIssue(
37896
+ ctx,
37897
+ ["navigation", "surfaces", surfaceIndex, "featureId"],
37898
+ `Navigation surface "${surface.id}" references unknown feature "${surface.featureId}"`
37899
+ );
37900
+ }
37901
+ surface.featureIds.forEach((featureId, featureIndex) => {
37902
+ if (!hasFeature(featuresById, featureId)) {
37903
+ addIssue(
37904
+ ctx,
37905
+ ["navigation", "surfaces", surfaceIndex, "featureIds", featureIndex],
37906
+ `Navigation surface "${surface.id}" references unknown feature "${featureId}"`
37907
+ );
37908
+ }
37909
+ });
37910
+ });
37664
37911
  const segmentsById = new Map(model.customers.segments.map((seg) => [seg.id, seg]));
37665
37912
  model.offerings.products.forEach((product, productIndex) => {
37666
37913
  product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
@@ -37708,6 +37955,7 @@ var OrganizationGraphNodeKindSchema = external_exports.enum([
37708
37955
  "surface",
37709
37956
  "entity",
37710
37957
  "capability",
37958
+ "stage",
37711
37959
  "resource",
37712
37960
  "knowledge"
37713
37961
  ]);
@@ -41510,6 +41758,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
41510
41758
  enabled: true,
41511
41759
  uiPosition: "sidebar-primary"
41512
41760
  },
41761
+ {
41762
+ id: "monitoring.calendar",
41763
+ label: "Calendar",
41764
+ description: "Google Calendar events and agenda views",
41765
+ enabled: true,
41766
+ path: "/monitoring/calendar",
41767
+ icon: "feature.calendar"
41768
+ },
41513
41769
  {
41514
41770
  id: "monitoring.activity-log",
41515
41771
  label: "Activity Log",
@@ -41837,6 +42093,75 @@ function buildOrganizationGraph(input) {
41837
42093
  });
41838
42094
  }
41839
42095
  }
42096
+ const allStages = [
42097
+ ...organizationModel.prospecting.companyStages,
42098
+ ...organizationModel.prospecting.contactStages
42099
+ ].sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));
42100
+ for (const stage of allStages) {
42101
+ const id = nodeId("stage", stage.id);
42102
+ pushUniqueNode(nodes, nodeIds, {
42103
+ id,
42104
+ kind: "stage",
42105
+ label: stage.label,
42106
+ sourceId: stage.id,
42107
+ ...stage.description ? { description: stage.description } : {},
42108
+ ...stage.icon ? { icon: stage.icon } : {}
42109
+ });
42110
+ pushUniqueEdge(edges, edgeIds, {
42111
+ id: edgeId("contains", organizationNode.id, id),
42112
+ kind: "contains",
42113
+ sourceId: organizationNode.id,
42114
+ targetId: id
42115
+ });
42116
+ }
42117
+ for (const cap of [...CAPABILITY_REGISTRY].sort((a, b) => a.id.localeCompare(b.id))) {
42118
+ const id = nodeId("capability", cap.id);
42119
+ pushUniqueNode(nodes, nodeIds, {
42120
+ id,
42121
+ kind: "capability",
42122
+ label: cap.label,
42123
+ sourceId: cap.id,
42124
+ description: cap.description
42125
+ });
42126
+ pushUniqueEdge(edges, edgeIds, {
42127
+ id: edgeId("contains", organizationNode.id, id),
42128
+ kind: "contains",
42129
+ sourceId: organizationNode.id,
42130
+ targetId: id
42131
+ });
42132
+ const resourceNode = ensureResourceNode(nodes, nodeIds, resourceNodesById, cap.resourceId);
42133
+ pushUniqueEdge(edges, edgeIds, {
42134
+ id: edgeId("maps_to", id, resourceNode.id),
42135
+ kind: "maps_to",
42136
+ sourceId: id,
42137
+ targetId: resourceNode.id
42138
+ });
42139
+ }
42140
+ for (const template of [...organizationModel.prospecting.buildTemplates].sort((a, b) => a.id.localeCompare(b.id))) {
42141
+ const stepById = new Map(template.steps.map((s) => [s.id, s]));
42142
+ for (const step of [...template.steps].sort((a, b) => a.id.localeCompare(b.id))) {
42143
+ const stageNodeId = nodeId("stage", step.stageKey);
42144
+ const capNodeId = nodeId("capability", step.capabilityKey);
42145
+ pushUniqueEdge(edges, edgeIds, {
42146
+ id: edgeId("uses", stageNodeId, capNodeId, step.id),
42147
+ kind: "uses",
42148
+ sourceId: stageNodeId,
42149
+ targetId: capNodeId
42150
+ });
42151
+ for (const depId of step.dependsOn ?? []) {
42152
+ const depStep = stepById.get(depId);
42153
+ if (depStep) {
42154
+ const depStageNodeId = nodeId("stage", depStep.stageKey);
42155
+ pushUniqueEdge(edges, edgeIds, {
42156
+ id: edgeId("references", stageNodeId, depStageNodeId, step.id),
42157
+ kind: "references",
42158
+ sourceId: stageNodeId,
42159
+ targetId: depStageNodeId
42160
+ });
42161
+ }
42162
+ }
42163
+ }
42164
+ }
41840
42165
  if (commandViewData) {
41841
42166
  const commandViewResources = collectCommandViewResources(commandViewData).sort(
41842
42167
  (a, b) => a.resourceId.localeCompare(b.resourceId)
@@ -41893,6 +42218,10 @@ function buildOrganizationGraph(input) {
41893
42218
  return OrganizationGraphSchema.parse(graph);
41894
42219
  }
41895
42220
 
42221
+ // src/index.ts
42222
+ var listBuilderStageKeys = Object.keys(LEAD_GEN_STAGE_CATALOG);
42223
+ var ListBuilderStageKeySchema = external_exports.enum(listBuilderStageKeys);
42224
+
41896
42225
  // src/cli/config.ts
41897
42226
  var import_fs = require("fs");
41898
42227
  var import_path = require("path");
@@ -42089,7 +42418,7 @@ function wrapAction(commandName, fn) {
42089
42418
  // package.json
42090
42419
  var package_default = {
42091
42420
  name: "@elevasis/sdk",
42092
- version: "1.17.0",
42421
+ version: "1.19.0",
42093
42422
  description: "SDK for building Elevasis organization resources",
42094
42423
  type: "module",
42095
42424
  bin: {
@@ -44711,7 +45040,7 @@ function registerKnowledgeLs(program3) {
44711
45040
  function registerKnowledgeCat(program3) {
44712
45041
  program3.command("knowledge:cat <id>").description(
44713
45042
  "Print the raw MDX body of a knowledge node\n Example: elevasis-sdk knowledge:cat knowledge.outreach-playbook\n Use --json for structured output"
44714
- ).option("--json", "Return structured JSON: { id, kind, title, summary, body, links, ownerIds, updatedAt }").action(
45043
+ ).option("--json", "Return structured JSON with node fields").action(
44715
45044
  wrapAction("knowledge:cat", async (id, options) => {
44716
45045
  const projectRoot = getProjectRoot();
44717
45046
  const model = await loadOrgModel(projectRoot);
@@ -44732,6 +45061,8 @@ function registerKnowledgeCat(program3) {
44732
45061
  summary: node.summary,
44733
45062
  body: node.body,
44734
45063
  links: node.links,
45064
+ skills: node.skills,
45065
+ domain: node.domain,
44735
45066
  ownerIds: node.ownerIds,
44736
45067
  updatedAt: node.updatedAt
44737
45068
  },
@@ -44804,6 +45135,45 @@ function registerKnowledgeGraph(program3) {
44804
45135
  );
44805
45136
  }
44806
45137
 
45138
+ // src/cli/commands/knowledge/skills.ts
45139
+ function registerKnowledgeSkills(program3) {
45140
+ program3.command("knowledge:skills <id>").description(
45141
+ "Show skill bindings for a knowledge node\n Example: elevasis-sdk knowledge:skills knowledge.new-vertical-launch-playbook"
45142
+ ).option("--json", "Print JSON: { id, title, domain, skills }").action(
45143
+ wrapAction("knowledge:skills", async (id, options) => {
45144
+ const projectRoot = getProjectRoot();
45145
+ const model = await loadOrgModel(projectRoot);
45146
+ const knowledgeNodes = model.knowledge?.nodes ?? [];
45147
+ const normalizedNodeId = id.startsWith("knowledge:") ? id.slice("knowledge:".length) : id;
45148
+ const node = knowledgeNodes.find((n) => n.id === normalizedNodeId);
45149
+ if (!node) {
45150
+ process.stderr.write(`knowledge:skills: node not found: "${id}"
45151
+ `);
45152
+ process.exit(1);
45153
+ }
45154
+ const result = {
45155
+ id: node.id,
45156
+ title: node.title,
45157
+ domain: node.domain ?? null,
45158
+ skills: node.skills ?? []
45159
+ };
45160
+ if (options.json) {
45161
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
45162
+ return;
45163
+ }
45164
+ const lines = [`Skill bindings for ${node.id}`, `Domain: ${node.domain ?? "(none)"}`, "", "Skills:"];
45165
+ if (result.skills.length === 0) {
45166
+ lines.push(" (none)");
45167
+ } else {
45168
+ for (const skill of result.skills) {
45169
+ lines.push(` ${skill}`);
45170
+ }
45171
+ }
45172
+ process.stdout.write(lines.join("\n") + "\n");
45173
+ })
45174
+ );
45175
+ }
45176
+
44807
45177
  // src/cli/commands/knowledge/generate.ts
44808
45178
  var import_node_fs3 = require("node:fs");
44809
45179
  var import_node_path3 = require("node:path");
@@ -44886,10 +45256,35 @@ function readKnowledgeNodeMdx(filePath) {
44886
45256
  icon: optionalString(frontmatter, "icon", filePath),
44887
45257
  body,
44888
45258
  links: optionalStringArray(frontmatter, "links", filePath).map((nodeId2) => ({ nodeId: nodeId2 })),
45259
+ skills: optionalStringArray(frontmatter, "skills", filePath),
45260
+ domain: optionalString(frontmatter, "domain", filePath),
44889
45261
  ownerIds: optionalStringArray(frontmatter, "ownerIds", filePath),
44890
45262
  updatedAt: assertString(frontmatter, "updatedAt", filePath)
44891
45263
  };
44892
45264
  }
45265
+ function generateGraphSkillsRegistry(nodes) {
45266
+ const domains = {};
45267
+ for (const node of nodes) {
45268
+ if (!node.domain) continue;
45269
+ const domain2 = domains[node.domain] ?? { skills: [], nodes: [] };
45270
+ const skills = [...new Set(node.skills)].sort((a, b) => a.localeCompare(b));
45271
+ domain2.nodes.push({
45272
+ id: node.id,
45273
+ title: node.title,
45274
+ kind: node.kind,
45275
+ skills
45276
+ });
45277
+ domain2.skills = [.../* @__PURE__ */ new Set([...domain2.skills, ...skills])].sort((a, b) => a.localeCompare(b));
45278
+ domains[node.domain] = domain2;
45279
+ }
45280
+ for (const domain2 of Object.values(domains)) {
45281
+ domain2.nodes.sort((a, b) => a.id.localeCompare(b.id));
45282
+ }
45283
+ return {
45284
+ generatedBy: "generate-knowledge-nodes",
45285
+ domains: Object.fromEntries(Object.entries(domains).sort(([a], [b]) => a.localeCompare(b)))
45286
+ };
45287
+ }
44893
45288
  function generateKnowledgeNodesTs(options) {
44894
45289
  const exportedName = options.exportedName ?? "mdxKnowledgeNodes";
44895
45290
  const typeImport = options.typeImportPath ? [`import type { OrgKnowledgeNode } from '${options.typeImportPath}'`, ""] : [];
@@ -44925,6 +45320,15 @@ function generateKnowledgeNodes(options) {
44925
45320
  }),
44926
45321
  "utf8"
44927
45322
  );
45323
+ if (options.graphSkillsOutputPath) {
45324
+ (0, import_node_fs2.mkdirSync)((0, import_node_path2.dirname)(options.graphSkillsOutputPath), { recursive: true });
45325
+ (0, import_node_fs2.writeFileSync)(
45326
+ options.graphSkillsOutputPath,
45327
+ `${JSON.stringify(generateGraphSkillsRegistry(nodes), null, 2)}
45328
+ `,
45329
+ "utf8"
45330
+ );
45331
+ }
44928
45332
  return { nodes, outputPath: options.outputPath };
44929
45333
  }
44930
45334
 
@@ -44932,11 +45336,15 @@ function generateKnowledgeNodes(options) {
44932
45336
  function registerKnowledgeGenerate(program3) {
44933
45337
  program3.command("knowledge:generate").description(
44934
45338
  "Generate OrganizationModel knowledge nodes from MDX source files\n Example: elevasis-sdk knowledge:generate"
44935
- ).option("--source <path>", "MDX source directory relative to project root", "core/config/knowledge/nodes").option("--output <path>", "Generated TS file relative to project root", "core/config/knowledge/_generated/nodes.ts").action(
45339
+ ).option("--source <path>", "MDX source directory relative to project root", "core/config/knowledge/nodes").option("--output <path>", "Generated TS file relative to project root", "core/config/knowledge/_generated/nodes.ts").option("--skills-output <path>", "Generated graph skill registry relative to project root", ".claude/registries/graph-skills.json").action(
44936
45340
  wrapAction("knowledge:generate", async (options) => {
44937
45341
  const projectRoot = getProjectRoot();
44938
45342
  const sourceDir = (0, import_node_path3.resolve)(projectRoot, options.source ?? "core/config/knowledge/nodes");
44939
45343
  const outputPath = (0, import_node_path3.resolve)(projectRoot, options.output ?? "core/config/knowledge/_generated/nodes.ts");
45344
+ const graphSkillsOutputPath = (0, import_node_path3.resolve)(
45345
+ projectRoot,
45346
+ options.skillsOutput ?? ".claude/registries/graph-skills.json"
45347
+ );
44940
45348
  if (!(0, import_node_fs3.existsSync)(sourceDir)) {
44941
45349
  process.stderr.write(`knowledge:generate: source directory not found: ${sourceDir}
44942
45350
  `);
@@ -44946,9 +45354,12 @@ function registerKnowledgeGenerate(program3) {
44946
45354
  const result = generateKnowledgeNodes({
44947
45355
  sourceDir,
44948
45356
  outputPath,
45357
+ graphSkillsOutputPath,
44949
45358
  sourceLabel: options.source ?? "core/config/knowledge/nodes"
44950
45359
  });
44951
45360
  process.stdout.write(`Generated ${result.nodes.length} knowledge node(s): ${result.outputPath}
45361
+ `);
45362
+ process.stdout.write(`Generated graph skill registry: ${graphSkillsOutputPath}
44952
45363
  `);
44953
45364
  })
44954
45365
  );
@@ -44960,6 +45371,7 @@ function registerKnowledgeCommands(program3) {
44960
45371
  registerKnowledgeLs(program3);
44961
45372
  registerKnowledgeCat(program3);
44962
45373
  registerKnowledgeGraph(program3);
45374
+ registerKnowledgeSkills(program3);
44963
45375
  }
44964
45376
 
44965
45377
  // src/cli/commands/request/request.ts