@elevasis/core 0.17.0 → 0.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.
Files changed (44) hide show
  1. package/dist/index.d.ts +82 -1
  2. package/dist/index.js +291 -171
  3. package/dist/knowledge/index.d.ts +43 -0
  4. package/dist/organization-model/index.d.ts +82 -1
  5. package/dist/organization-model/index.js +291 -171
  6. package/dist/test-utils/index.d.ts +41 -12
  7. package/dist/test-utils/index.js +291 -171
  8. package/package.json +2 -1
  9. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +78 -65
  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 +100 -2
  13. package/src/business/acquisition/api-schemas.ts +81 -43
  14. package/src/business/acquisition/build-templates.test.ts +212 -0
  15. package/src/business/acquisition/types.ts +21 -38
  16. package/src/execution/engine/index.ts +436 -434
  17. package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -0
  18. package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -0
  19. package/src/execution/engine/tools/lead-service-types.ts +51 -9
  20. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -6
  21. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -5
  22. package/src/execution/engine/tools/platform/acquisition/types.ts +20 -9
  23. package/src/execution/engine/tools/registry.ts +700 -698
  24. package/src/execution/engine/tools/tool-maps.ts +10 -0
  25. package/src/execution/external/__tests__/api-schemas.test.ts +127 -0
  26. package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -6
  27. package/src/integrations/oauth/provider-registry.ts +74 -61
  28. package/src/integrations/oauth/server/credentials.ts +43 -39
  29. package/src/knowledge/__tests__/queries.test.ts +89 -0
  30. package/src/organization-model/__tests__/icons.test.ts +61 -0
  31. package/src/organization-model/__tests__/knowledge.test.ts +118 -1
  32. package/src/organization-model/__tests__/prospecting-ssot.test.ts +94 -0
  33. package/src/organization-model/defaults.ts +8 -0
  34. package/src/organization-model/domains/knowledge.ts +9 -0
  35. package/src/organization-model/domains/prospecting.ts +272 -226
  36. package/src/organization-model/domains/sales.ts +32 -25
  37. package/src/organization-model/icons.ts +3 -0
  38. package/src/organization-model/types.ts +9 -1
  39. package/src/platform/constants/versions.ts +1 -1
  40. package/src/platform/utils/__tests__/validation.test.ts +1084 -1083
  41. package/src/platform/utils/validation.ts +425 -425
  42. package/src/reference/_generated/contracts.md +78 -65
  43. package/src/server.ts +6 -0
  44. package/src/supabase/database.types.ts +6 -12
@@ -3,6 +3,7 @@ import { z } from 'zod';
3
3
  // src/organization-model/schema.ts
4
4
  var ORGANIZATION_MODEL_ICON_TOKENS = [
5
5
  "nav.dashboard",
6
+ "nav.calendar",
6
7
  "nav.sales",
7
8
  "nav.crm",
8
9
  "nav.lead-gen",
@@ -17,6 +18,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
17
18
  "knowledge.strategy",
18
19
  "knowledge.reference",
19
20
  "feature.dashboard",
21
+ "feature.calendar",
20
22
  "feature.sales",
21
23
  "feature.crm",
22
24
  "feature.finance",
@@ -40,6 +42,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
40
42
  "integration.google-sheets",
41
43
  "integration.attio",
42
44
  "surface.dashboard",
45
+ "surface.calendar",
43
46
  "surface.overview",
44
47
  "surface.command-view",
45
48
  "surface.command-queue",
@@ -220,6 +223,89 @@ var DEFAULT_ORGANIZATION_MODEL_SALES = {
220
223
  }
221
224
  ]
222
225
  };
226
+ var LEAD_GEN_STAGE_CATALOG = {
227
+ // Prospecting — company population
228
+ scraped: {
229
+ key: "scraped",
230
+ label: "Scraped",
231
+ description: "Company was scraped from a source directory (Apify actor run).",
232
+ order: 1,
233
+ entity: "company"
234
+ },
235
+ populated: {
236
+ key: "populated",
237
+ label: "Companies found",
238
+ description: "Companies have been found and added to the lead-gen list.",
239
+ order: 2,
240
+ entity: "company"
241
+ },
242
+ extracted: {
243
+ key: "extracted",
244
+ label: "Websites analyzed",
245
+ description: "Company websites have been analyzed for business signals.",
246
+ order: 3,
247
+ entity: "company"
248
+ },
249
+ enriched: {
250
+ key: "enriched",
251
+ label: "Enriched",
252
+ description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
253
+ order: 4,
254
+ entity: "company"
255
+ },
256
+ "decision-makers-enriched": {
257
+ key: "decision-makers-enriched",
258
+ label: "Decision-makers found",
259
+ description: "Decision-maker contacts discovered and attached to a qualified company.",
260
+ order: 6,
261
+ entity: "company"
262
+ },
263
+ // Prospecting — contact discovery
264
+ discovered: {
265
+ key: "discovered",
266
+ label: "Decision-makers found",
267
+ description: "Decision-maker contact details have been found.",
268
+ order: 5,
269
+ entity: "contact"
270
+ },
271
+ verified: {
272
+ key: "verified",
273
+ label: "Emails verified",
274
+ description: "Contact email addresses have been checked for deliverability.",
275
+ order: 7,
276
+ entity: "contact"
277
+ },
278
+ // Qualification
279
+ qualified: {
280
+ key: "qualified",
281
+ label: "Companies qualified",
282
+ description: "Companies have been scored against the qualification criteria.",
283
+ order: 8,
284
+ entity: "company"
285
+ },
286
+ // Outreach
287
+ personalized: {
288
+ key: "personalized",
289
+ label: "Personalized",
290
+ description: "Outreach message personalized for the contact (Instantly personalization workflow).",
291
+ order: 9,
292
+ entity: "contact"
293
+ },
294
+ uploaded: {
295
+ key: "uploaded",
296
+ label: "Reviewed and exported",
297
+ description: "Approved records have been reviewed and exported for handoff.",
298
+ order: 10,
299
+ entity: "contact"
300
+ },
301
+ interested: {
302
+ key: "interested",
303
+ label: "Interested",
304
+ description: "Contact replied with a positive signal (Instantly reply-handler transition).",
305
+ order: 11,
306
+ entity: "contact"
307
+ }
308
+ };
223
309
  var ProjectsDomainStateSchema = DisplayMetadataSchema.extend({
224
310
  id: ModelIdSchema,
225
311
  order: z.number().int().min(0)
@@ -300,6 +386,172 @@ var ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
300
386
  id: ModelIdSchema,
301
387
  steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
302
388
  });
389
+ var PROSPECTING_STEPS = {
390
+ localServices: {
391
+ sourceCompanies: {
392
+ id: "source-companies",
393
+ label: "Companies found",
394
+ primaryEntity: "company",
395
+ outputs: ["company"],
396
+ stageKey: "populated",
397
+ dependencyMode: "per-record-eligibility",
398
+ capabilityKey: "lead-gen.company.source",
399
+ defaultBatchSize: 100,
400
+ maxBatchSize: 250
401
+ },
402
+ analyzeWebsites: {
403
+ id: "analyze-websites",
404
+ label: "Websites analyzed",
405
+ primaryEntity: "company",
406
+ outputs: ["company"],
407
+ stageKey: "extracted",
408
+ dependsOn: ["source-companies"],
409
+ dependencyMode: "per-record-eligibility",
410
+ capabilityKey: "lead-gen.company.website-extract",
411
+ defaultBatchSize: 50,
412
+ maxBatchSize: 100
413
+ },
414
+ qualifyCompanies: {
415
+ id: "qualify-companies",
416
+ label: "Companies qualified",
417
+ primaryEntity: "company",
418
+ outputs: ["company"],
419
+ stageKey: "qualified",
420
+ dependsOn: ["analyze-websites"],
421
+ dependencyMode: "per-record-eligibility",
422
+ capabilityKey: "lead-gen.company.qualify",
423
+ defaultBatchSize: 100,
424
+ maxBatchSize: 250
425
+ },
426
+ findContacts: {
427
+ id: "find-contacts",
428
+ label: "Decision-makers found",
429
+ primaryEntity: "contact",
430
+ outputs: ["contact"],
431
+ stageKey: "discovered",
432
+ dependsOn: ["qualify-companies"],
433
+ dependencyMode: "per-record-eligibility",
434
+ capabilityKey: "lead-gen.contact.discover",
435
+ defaultBatchSize: 50,
436
+ maxBatchSize: 100
437
+ },
438
+ verifyEmails: {
439
+ id: "verify-emails",
440
+ label: "Emails verified",
441
+ primaryEntity: "contact",
442
+ outputs: ["contact"],
443
+ stageKey: "verified",
444
+ dependsOn: ["find-contacts"],
445
+ dependencyMode: "per-record-eligibility",
446
+ capabilityKey: "lead-gen.contact.verify-email",
447
+ defaultBatchSize: 100,
448
+ maxBatchSize: 500
449
+ },
450
+ personalize: {
451
+ id: "personalize",
452
+ label: "Personalize",
453
+ primaryEntity: "contact",
454
+ outputs: ["contact"],
455
+ stageKey: "personalized",
456
+ dependsOn: ["verify-emails"],
457
+ dependencyMode: "per-record-eligibility",
458
+ capabilityKey: "lead-gen.contact.personalize",
459
+ defaultBatchSize: 25,
460
+ maxBatchSize: 100
461
+ },
462
+ review: {
463
+ id: "review",
464
+ label: "Reviewed and exported",
465
+ primaryEntity: "contact",
466
+ outputs: ["export"],
467
+ stageKey: "uploaded",
468
+ dependsOn: ["personalize"],
469
+ dependencyMode: "per-record-eligibility",
470
+ capabilityKey: "lead-gen.review.outreach-ready",
471
+ defaultBatchSize: 25,
472
+ maxBatchSize: 100
473
+ }
474
+ },
475
+ dtcApolloClickup: {
476
+ importApolloSearch: {
477
+ id: "import-apollo-search",
478
+ label: "Companies found",
479
+ description: "Pull companies and seed contact data from a predefined Apollo search or list.",
480
+ primaryEntity: "company",
481
+ outputs: ["company", "contact"],
482
+ stageKey: "populated",
483
+ dependencyMode: "per-record-eligibility",
484
+ capabilityKey: "lead-gen.company.apollo-import",
485
+ defaultBatchSize: 250,
486
+ maxBatchSize: 1e3
487
+ },
488
+ analyzeWebsites: {
489
+ id: "analyze-websites",
490
+ label: "Websites analyzed",
491
+ description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
492
+ primaryEntity: "company",
493
+ outputs: ["company"],
494
+ stageKey: "extracted",
495
+ dependsOn: ["import-apollo-search"],
496
+ dependencyMode: "per-record-eligibility",
497
+ capabilityKey: "lead-gen.company.website-extract",
498
+ defaultBatchSize: 50,
499
+ maxBatchSize: 100
500
+ },
501
+ scoreDtcFit: {
502
+ id: "score-dtc-fit",
503
+ label: "Companies qualified",
504
+ description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
505
+ primaryEntity: "company",
506
+ outputs: ["company"],
507
+ stageKey: "qualified",
508
+ dependsOn: ["analyze-websites"],
509
+ dependencyMode: "per-record-eligibility",
510
+ capabilityKey: "lead-gen.company.dtc-subscription-qualify",
511
+ defaultBatchSize: 100,
512
+ maxBatchSize: 250
513
+ },
514
+ enrichDecisionMakers: {
515
+ id: "enrich-decision-makers",
516
+ label: "Decision-makers found",
517
+ description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
518
+ primaryEntity: "company",
519
+ outputs: ["contact"],
520
+ stageKey: "decision-makers-enriched",
521
+ dependsOn: ["score-dtc-fit"],
522
+ dependencyMode: "per-record-eligibility",
523
+ capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
524
+ defaultBatchSize: 100,
525
+ maxBatchSize: 250
526
+ },
527
+ verifyEmails: {
528
+ id: "verify-emails",
529
+ label: "Emails verified",
530
+ description: "Verify deliverability before the QC and handoff step.",
531
+ primaryEntity: "contact",
532
+ outputs: ["contact"],
533
+ stageKey: "verified",
534
+ dependsOn: ["enrich-decision-makers"],
535
+ dependencyMode: "per-record-eligibility",
536
+ capabilityKey: "lead-gen.contact.verify-email",
537
+ defaultBatchSize: 250,
538
+ maxBatchSize: 500
539
+ },
540
+ reviewAndExport: {
541
+ id: "review-and-export",
542
+ label: "Reviewed and exported",
543
+ description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
544
+ primaryEntity: "company",
545
+ outputs: ["export"],
546
+ stageKey: "uploaded",
547
+ dependsOn: ["verify-emails"],
548
+ dependencyMode: "per-record-eligibility",
549
+ capabilityKey: "lead-gen.export.list",
550
+ defaultBatchSize: 100,
551
+ maxBatchSize: 250
552
+ }
553
+ }
554
+ };
303
555
  var OrganizationModelProspectingSchema = z.object({
304
556
  listEntityId: ModelIdSchema,
305
557
  companyEntityId: ModelIdSchema,
@@ -310,21 +562,22 @@ var OrganizationModelProspectingSchema = z.object({
310
562
  defaultBuildTemplateId: ModelIdSchema,
311
563
  buildTemplates: z.array(ProspectingBuildTemplateSchema).min(1)
312
564
  });
565
+ function toProspectingLifecycleStage(stage) {
566
+ return {
567
+ id: stage.key,
568
+ label: stage.label,
569
+ order: stage.order
570
+ };
571
+ }
572
+ function leadGenStagesForEntity(entity) {
573
+ return Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity).sort((a, b) => a.order - b.order).map(toProspectingLifecycleStage);
574
+ }
313
575
  var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
314
576
  listEntityId: "leadgen.list",
315
577
  companyEntityId: "leadgen.company",
316
578
  contactEntityId: "leadgen.contact",
317
- companyStages: [
318
- { id: "populated", label: "Populated", order: 1 },
319
- { id: "extracted", label: "Extracted", order: 2 },
320
- { id: "qualified", label: "Qualified", order: 3 }
321
- ],
322
- contactStages: [
323
- { id: "discovered", label: "Discovered", order: 1 },
324
- { id: "verified", label: "Verified", order: 2 },
325
- { id: "personalized", label: "Personalized", order: 3 },
326
- { id: "uploaded", label: "Uploaded", order: 4 }
327
- ],
579
+ companyStages: leadGenStagesForEntity("company"),
580
+ contactStages: leadGenStagesForEntity("contact"),
328
581
  defaultBuildTemplateId: "local-services",
329
582
  buildTemplates: [
330
583
  {
@@ -332,89 +585,13 @@ var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
332
585
  label: "Local Services Prospecting",
333
586
  description: "Curated local-services list build using company sourcing, website analysis, qualification, contact discovery, verification, personalization, and review.",
334
587
  steps: [
335
- {
336
- id: "source-companies",
337
- label: "Source companies",
338
- primaryEntity: "company",
339
- outputs: ["company"],
340
- stageKey: "populated",
341
- dependencyMode: "per-record-eligibility",
342
- capabilityKey: "lead-gen.company.source",
343
- defaultBatchSize: 100,
344
- maxBatchSize: 250
345
- },
346
- {
347
- id: "analyze-websites",
348
- label: "Analyze websites",
349
- primaryEntity: "company",
350
- outputs: ["company"],
351
- stageKey: "extracted",
352
- dependsOn: ["source-companies"],
353
- dependencyMode: "per-record-eligibility",
354
- capabilityKey: "lead-gen.company.website-extract",
355
- defaultBatchSize: 50,
356
- maxBatchSize: 100
357
- },
358
- {
359
- id: "qualify-companies",
360
- label: "Qualify companies",
361
- primaryEntity: "company",
362
- outputs: ["company"],
363
- stageKey: "qualified",
364
- dependsOn: ["analyze-websites"],
365
- dependencyMode: "per-record-eligibility",
366
- capabilityKey: "lead-gen.company.qualify",
367
- defaultBatchSize: 100,
368
- maxBatchSize: 250
369
- },
370
- {
371
- id: "find-contacts",
372
- label: "Find contacts",
373
- primaryEntity: "contact",
374
- outputs: ["contact"],
375
- stageKey: "discovered",
376
- dependsOn: ["qualify-companies"],
377
- dependencyMode: "per-record-eligibility",
378
- capabilityKey: "lead-gen.contact.discover",
379
- defaultBatchSize: 50,
380
- maxBatchSize: 100
381
- },
382
- {
383
- id: "verify-emails",
384
- label: "Verify emails",
385
- primaryEntity: "contact",
386
- outputs: ["contact"],
387
- stageKey: "verified",
388
- dependsOn: ["find-contacts"],
389
- dependencyMode: "per-record-eligibility",
390
- capabilityKey: "lead-gen.contact.verify-email",
391
- defaultBatchSize: 100,
392
- maxBatchSize: 500
393
- },
394
- {
395
- id: "personalize",
396
- label: "Personalize",
397
- primaryEntity: "contact",
398
- outputs: ["contact"],
399
- stageKey: "personalized",
400
- dependsOn: ["verify-emails"],
401
- dependencyMode: "per-record-eligibility",
402
- capabilityKey: "lead-gen.contact.personalize",
403
- defaultBatchSize: 25,
404
- maxBatchSize: 100
405
- },
406
- {
407
- id: "review",
408
- label: "Review",
409
- primaryEntity: "contact",
410
- outputs: ["export"],
411
- stageKey: "uploaded",
412
- dependsOn: ["personalize"],
413
- dependencyMode: "per-record-eligibility",
414
- capabilityKey: "lead-gen.review.outreach-ready",
415
- defaultBatchSize: 25,
416
- maxBatchSize: 100
417
- }
588
+ PROSPECTING_STEPS.localServices.sourceCompanies,
589
+ PROSPECTING_STEPS.localServices.analyzeWebsites,
590
+ PROSPECTING_STEPS.localServices.qualifyCompanies,
591
+ PROSPECTING_STEPS.localServices.findContacts,
592
+ PROSPECTING_STEPS.localServices.verifyEmails,
593
+ PROSPECTING_STEPS.localServices.personalize,
594
+ PROSPECTING_STEPS.localServices.review
418
595
  ]
419
596
  },
420
597
  {
@@ -422,83 +599,12 @@ var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
422
599
  label: "DTC Subscription Apollo Export",
423
600
  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.",
424
601
  steps: [
425
- {
426
- id: "import-apollo-search",
427
- label: "Import Apollo search",
428
- description: "Pull companies and seed contact data from a predefined Apollo search or list.",
429
- primaryEntity: "company",
430
- outputs: ["company", "contact"],
431
- stageKey: "populated",
432
- dependencyMode: "per-record-eligibility",
433
- capabilityKey: "lead-gen.company.apollo-import",
434
- defaultBatchSize: 250,
435
- maxBatchSize: 1e3
436
- },
437
- {
438
- id: "analyze-websites",
439
- label: "Analyze websites",
440
- description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
441
- primaryEntity: "company",
442
- outputs: ["company"],
443
- stageKey: "extracted",
444
- dependsOn: ["import-apollo-search"],
445
- dependencyMode: "per-record-eligibility",
446
- capabilityKey: "lead-gen.company.website-extract",
447
- defaultBatchSize: 50,
448
- maxBatchSize: 100
449
- },
450
- {
451
- id: "score-dtc-fit",
452
- label: "Score DTC fit",
453
- description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
454
- primaryEntity: "company",
455
- outputs: ["company"],
456
- stageKey: "qualified",
457
- dependsOn: ["analyze-websites"],
458
- dependencyMode: "per-record-eligibility",
459
- capabilityKey: "lead-gen.company.dtc-subscription-qualify",
460
- defaultBatchSize: 100,
461
- maxBatchSize: 250
462
- },
463
- {
464
- id: "enrich-decision-makers",
465
- label: "Enrich decision-makers",
466
- description: "Use Apollo to find qualified contacts such as founders, retention leads, lifecycle leads, and marketing owners.",
467
- primaryEntity: "contact",
468
- outputs: ["contact"],
469
- stageKey: "discovered",
470
- dependsOn: ["score-dtc-fit"],
471
- dependencyMode: "per-record-eligibility",
472
- capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
473
- defaultBatchSize: 100,
474
- maxBatchSize: 250
475
- },
476
- {
477
- id: "verify-emails",
478
- label: "Verify emails",
479
- description: "Verify deliverability before the QC and handoff step.",
480
- primaryEntity: "contact",
481
- outputs: ["contact"],
482
- stageKey: "verified",
483
- dependsOn: ["enrich-decision-makers"],
484
- dependencyMode: "per-record-eligibility",
485
- capabilityKey: "lead-gen.contact.verify-email",
486
- defaultBatchSize: 250,
487
- maxBatchSize: 500
488
- },
489
- {
490
- id: "review-and-export",
491
- label: "Review and export",
492
- description: "Operator QC approves or rejects leads, then approved records are exported as a lead list.",
493
- primaryEntity: "company",
494
- outputs: ["export"],
495
- stageKey: "uploaded",
496
- dependsOn: ["verify-emails"],
497
- dependencyMode: "per-record-eligibility",
498
- capabilityKey: "lead-gen.export.list",
499
- defaultBatchSize: 100,
500
- maxBatchSize: 250
501
- }
602
+ PROSPECTING_STEPS.dtcApolloClickup.importApolloSearch,
603
+ PROSPECTING_STEPS.dtcApolloClickup.analyzeWebsites,
604
+ PROSPECTING_STEPS.dtcApolloClickup.scoreDtcFit,
605
+ PROSPECTING_STEPS.dtcApolloClickup.enrichDecisionMakers,
606
+ PROSPECTING_STEPS.dtcApolloClickup.verifyEmails,
607
+ PROSPECTING_STEPS.dtcApolloClickup.reviewAndExport
502
608
  ]
503
609
  }
504
610
  ]
@@ -945,6 +1051,8 @@ var DEFAULT_ORGANIZATION_MODEL_STATUSES = {
945
1051
  var KnowledgeLinkSchema = z.object({
946
1052
  nodeId: NodeIdStringSchema
947
1053
  });
1054
+ var KnowledgeSkillBindingSchema = z.string().trim().min(1).max(120);
1055
+ var KnowledgeDomainBindingSchema = z.string().trim().min(1).max(80);
948
1056
  var OrgKnowledgeKindSchema = z.enum(["playbook", "strategy", "reference"]);
949
1057
  var OrgKnowledgeNodeSchema = z.object({
950
1058
  id: ModelIdSchema,
@@ -959,6 +1067,10 @@ var OrgKnowledgeNodeSchema = z.object({
959
1067
  * Each link emits a `governs` edge: knowledge-node -> target node.
960
1068
  */
961
1069
  links: z.array(KnowledgeLinkSchema).default([]),
1070
+ /** Operator skill or command bindings relevant to this node. */
1071
+ skills: z.array(KnowledgeSkillBindingSchema).optional(),
1072
+ /** Domain key used to derive fast graph->skill registries. */
1073
+ domain: KnowledgeDomainBindingSchema.optional(),
962
1074
  /** Identifiers of the roles or members who own this knowledge node. */
963
1075
  ownerIds: z.array(ModelIdSchema).default([]),
964
1076
  /** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
@@ -1262,6 +1374,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
1262
1374
  enabled: true,
1263
1375
  uiPosition: "sidebar-primary"
1264
1376
  },
1377
+ {
1378
+ id: "monitoring.calendar",
1379
+ label: "Calendar",
1380
+ description: "Google Calendar events and agenda views",
1381
+ enabled: true,
1382
+ path: "/monitoring/calendar",
1383
+ icon: "feature.calendar"
1384
+ },
1265
1385
  {
1266
1386
  id: "monitoring.activity-log",
1267
1387
  label: "Activity Log",