@elevasis/sdk 1.24.0 → 1.26.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 (66) hide show
  1. package/dist/cli.cjs +875 -834
  2. package/dist/index.d.ts +4857 -4547
  3. package/dist/index.js +564 -2338
  4. package/dist/node/index.d.ts +693 -1356
  5. package/dist/node/index.js +1 -1
  6. package/dist/test-utils/index.d.ts +4186 -4139
  7. package/dist/test-utils/index.js +694 -2769
  8. package/dist/types/worker/adapters/clickup.d.ts +22 -0
  9. package/dist/types/worker/adapters/index.d.ts +1 -0
  10. package/dist/types/worker/index.d.ts +3 -2
  11. package/dist/types/worker/platform.d.ts +2 -2
  12. package/dist/worker/index.js +427 -2803
  13. package/package.json +2 -2
  14. package/reference/_navigation.md +11 -1
  15. package/reference/_reference-manifest.json +70 -0
  16. package/reference/claude-config/rules/organization-model.md +12 -1
  17. package/reference/claude-config/rules/organization-os.md +12 -1
  18. package/reference/claude-config/skills/om/SKILL.md +13 -5
  19. package/reference/claude-config/skills/om/operations/codify-level-a.md +109 -100
  20. package/reference/claude-config/skills/om/operations/customers.md +10 -6
  21. package/reference/claude-config/skills/om/operations/features.md +7 -3
  22. package/reference/claude-config/skills/om/operations/goals.md +10 -6
  23. package/reference/claude-config/skills/om/operations/identity.md +8 -5
  24. package/reference/claude-config/skills/om/operations/labels.md +17 -1
  25. package/reference/claude-config/skills/om/operations/offerings.md +11 -7
  26. package/reference/claude-config/skills/om/operations/roles.md +11 -7
  27. package/reference/claude-config/skills/om/operations/techStack.md +10 -2
  28. package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +32 -0
  29. package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +43 -0
  30. package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +40 -0
  31. package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +61 -0
  32. package/reference/cli-management.mdx +539 -0
  33. package/reference/cli.mdx +579 -808
  34. package/reference/concepts.mdx +134 -146
  35. package/reference/deployment/api.mdx +296 -297
  36. package/reference/deployment/command-center.mdx +208 -209
  37. package/reference/deployment/index.mdx +194 -195
  38. package/reference/deployment/provided-features.mdx +110 -107
  39. package/reference/deployment/ui-execution.mdx +249 -250
  40. package/reference/framework/index.mdx +111 -195
  41. package/reference/framework/resource-documentation.mdx +90 -0
  42. package/reference/framework/tutorial-system.mdx +135 -135
  43. package/reference/getting-started.mdx +141 -142
  44. package/reference/index.mdx +95 -106
  45. package/reference/packages/ui/src/auth/README.md +6 -6
  46. package/reference/platform-tools/adapters-integration.mdx +300 -301
  47. package/reference/platform-tools/adapters-platform.mdx +552 -553
  48. package/reference/platform-tools/index.mdx +216 -217
  49. package/reference/platform-tools/type-safety.mdx +82 -82
  50. package/reference/resources/index.mdx +348 -349
  51. package/reference/resources/patterns.mdx +446 -449
  52. package/reference/resources/types.mdx +115 -116
  53. package/reference/roadmap.mdx +164 -165
  54. package/reference/rules/organization-model.md +14 -0
  55. package/reference/runtime.mdx +172 -173
  56. package/reference/scaffold/operations/propagation-pipeline.md +1 -1
  57. package/reference/scaffold/recipes/customize-crm-actions.md +45 -46
  58. package/reference/scaffold/recipes/extend-crm.md +253 -255
  59. package/reference/scaffold/recipes/extend-lead-gen.md +130 -77
  60. package/reference/scaffold/recipes/index.md +43 -44
  61. package/reference/scaffold/reference/contracts.md +1275 -1432
  62. package/reference/scaffold/reference/glossary.md +8 -6
  63. package/reference/scaffold/ui/feature-flags-and-gating.md +59 -46
  64. package/reference/scaffold/ui/feature-shell.mdx +11 -11
  65. package/reference/scaffold/ui/recipes.md +24 -24
  66. package/reference/troubleshooting.mdx +222 -223
@@ -373,8 +373,8 @@ interface ModelConfig {
373
373
  }
374
374
 
375
375
  declare const ResourceGovernanceStatusSchema: z.ZodEnum<{
376
- deprecated: "deprecated";
377
376
  active: "active";
377
+ deprecated: "deprecated";
378
378
  archived: "archived";
379
379
  }>;
380
380
  declare const WorkflowResourceEntrySchema$1: z.ZodObject<{
@@ -385,8 +385,8 @@ declare const WorkflowResourceEntrySchema$1: z.ZodObject<{
385
385
  description: z.ZodOptional<z.ZodString>;
386
386
  ownerRoleId: z.ZodOptional<z.ZodString>;
387
387
  status: z.ZodEnum<{
388
- deprecated: "deprecated";
389
388
  active: "active";
389
+ deprecated: "deprecated";
390
390
  archived: "archived";
391
391
  }>;
392
392
  ontology: z.ZodOptional<z.ZodObject<{
@@ -404,12 +404,12 @@ declare const WorkflowResourceEntrySchema$1: z.ZodObject<{
404
404
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
405
405
  path: z.ZodString;
406
406
  role: z.ZodEnum<{
407
- config: "config";
408
407
  entrypoint: "entrypoint";
409
408
  handler: "handler";
410
409
  schema: "schema";
411
410
  test: "test";
412
411
  docs: "docs";
412
+ config: "config";
413
413
  }>;
414
414
  symbol: z.ZodOptional<z.ZodString>;
415
415
  description: z.ZodOptional<z.ZodString>;
@@ -420,10 +420,10 @@ declare const WorkflowResourceEntrySchema$1: z.ZodObject<{
420
420
  label: z.ZodString;
421
421
  payloadSchema: z.ZodOptional<z.ZodString>;
422
422
  lifecycle: z.ZodOptional<z.ZodEnum<{
423
+ active: "active";
423
424
  deprecated: "deprecated";
424
425
  draft: "draft";
425
426
  beta: "beta";
426
- active: "active";
427
427
  archived: "archived";
428
428
  }>>;
429
429
  }, z.core.$strip>>>;
@@ -436,8 +436,8 @@ declare const AgentResourceEntrySchema: z.ZodObject<{
436
436
  description: z.ZodOptional<z.ZodString>;
437
437
  ownerRoleId: z.ZodOptional<z.ZodString>;
438
438
  status: z.ZodEnum<{
439
- deprecated: "deprecated";
440
439
  active: "active";
440
+ deprecated: "deprecated";
441
441
  archived: "archived";
442
442
  }>;
443
443
  ontology: z.ZodOptional<z.ZodObject<{
@@ -455,12 +455,12 @@ declare const AgentResourceEntrySchema: z.ZodObject<{
455
455
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
456
456
  path: z.ZodString;
457
457
  role: z.ZodEnum<{
458
- config: "config";
459
458
  entrypoint: "entrypoint";
460
459
  handler: "handler";
461
460
  schema: "schema";
462
461
  test: "test";
463
462
  docs: "docs";
463
+ config: "config";
464
464
  }>;
465
465
  symbol: z.ZodOptional<z.ZodString>;
466
466
  description: z.ZodOptional<z.ZodString>;
@@ -502,10 +502,10 @@ declare const AgentResourceEntrySchema: z.ZodObject<{
502
502
  label: z.ZodString;
503
503
  payloadSchema: z.ZodOptional<z.ZodString>;
504
504
  lifecycle: z.ZodOptional<z.ZodEnum<{
505
+ active: "active";
505
506
  deprecated: "deprecated";
506
507
  draft: "draft";
507
508
  beta: "beta";
508
- active: "active";
509
509
  archived: "archived";
510
510
  }>>;
511
511
  }, z.core.$strip>>>;
@@ -518,8 +518,8 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
518
518
  description: z.ZodOptional<z.ZodString>;
519
519
  ownerRoleId: z.ZodOptional<z.ZodString>;
520
520
  status: z.ZodEnum<{
521
- deprecated: "deprecated";
522
521
  active: "active";
522
+ deprecated: "deprecated";
523
523
  archived: "archived";
524
524
  }>;
525
525
  ontology: z.ZodOptional<z.ZodObject<{
@@ -537,12 +537,12 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
537
537
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
538
538
  path: z.ZodString;
539
539
  role: z.ZodEnum<{
540
- config: "config";
541
540
  entrypoint: "entrypoint";
542
541
  handler: "handler";
543
542
  schema: "schema";
544
543
  test: "test";
545
544
  docs: "docs";
545
+ config: "config";
546
546
  }>;
547
547
  symbol: z.ZodOptional<z.ZodString>;
548
548
  description: z.ZodOptional<z.ZodString>;
@@ -553,10 +553,10 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
553
553
  label: z.ZodString;
554
554
  payloadSchema: z.ZodOptional<z.ZodString>;
555
555
  lifecycle: z.ZodOptional<z.ZodEnum<{
556
+ active: "active";
556
557
  deprecated: "deprecated";
557
558
  draft: "draft";
558
559
  beta: "beta";
559
- active: "active";
560
560
  archived: "archived";
561
561
  }>>;
562
562
  }, z.core.$strip>>>;
@@ -568,8 +568,8 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
568
568
  description: z.ZodOptional<z.ZodString>;
569
569
  ownerRoleId: z.ZodOptional<z.ZodString>;
570
570
  status: z.ZodEnum<{
571
- deprecated: "deprecated";
572
571
  active: "active";
572
+ deprecated: "deprecated";
573
573
  archived: "archived";
574
574
  }>;
575
575
  ontology: z.ZodOptional<z.ZodObject<{
@@ -587,12 +587,12 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
587
587
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
588
588
  path: z.ZodString;
589
589
  role: z.ZodEnum<{
590
- config: "config";
591
590
  entrypoint: "entrypoint";
592
591
  handler: "handler";
593
592
  schema: "schema";
594
593
  test: "test";
595
594
  docs: "docs";
595
+ config: "config";
596
596
  }>;
597
597
  symbol: z.ZodOptional<z.ZodString>;
598
598
  description: z.ZodOptional<z.ZodString>;
@@ -634,10 +634,10 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
634
634
  label: z.ZodString;
635
635
  payloadSchema: z.ZodOptional<z.ZodString>;
636
636
  lifecycle: z.ZodOptional<z.ZodEnum<{
637
+ active: "active";
637
638
  deprecated: "deprecated";
638
639
  draft: "draft";
639
640
  beta: "beta";
640
- active: "active";
641
641
  archived: "archived";
642
642
  }>>;
643
643
  }, z.core.$strip>>>;
@@ -649,8 +649,8 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
649
649
  description: z.ZodOptional<z.ZodString>;
650
650
  ownerRoleId: z.ZodOptional<z.ZodString>;
651
651
  status: z.ZodEnum<{
652
- deprecated: "deprecated";
653
652
  active: "active";
653
+ deprecated: "deprecated";
654
654
  archived: "archived";
655
655
  }>;
656
656
  ontology: z.ZodOptional<z.ZodObject<{
@@ -668,12 +668,12 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
668
668
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
669
669
  path: z.ZodString;
670
670
  role: z.ZodEnum<{
671
- config: "config";
672
671
  entrypoint: "entrypoint";
673
672
  handler: "handler";
674
673
  schema: "schema";
675
674
  test: "test";
676
675
  docs: "docs";
676
+ config: "config";
677
677
  }>;
678
678
  symbol: z.ZodOptional<z.ZodString>;
679
679
  description: z.ZodOptional<z.ZodString>;
@@ -688,8 +688,8 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
688
688
  description: z.ZodOptional<z.ZodString>;
689
689
  ownerRoleId: z.ZodOptional<z.ZodString>;
690
690
  status: z.ZodEnum<{
691
- deprecated: "deprecated";
692
691
  active: "active";
692
+ deprecated: "deprecated";
693
693
  archived: "archived";
694
694
  }>;
695
695
  ontology: z.ZodOptional<z.ZodObject<{
@@ -707,12 +707,12 @@ declare const ResourceEntrySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
707
707
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
708
708
  path: z.ZodString;
709
709
  role: z.ZodEnum<{
710
- config: "config";
711
710
  entrypoint: "entrypoint";
712
711
  handler: "handler";
713
712
  schema: "schema";
714
713
  test: "test";
715
714
  docs: "docs";
715
+ config: "config";
716
716
  }>;
717
717
  symbol: z.ZodOptional<z.ZodString>;
718
718
  description: z.ZodOptional<z.ZodString>;
@@ -1388,668 +1388,108 @@ declare const OntologyScopeSchema: z.ZodDefault<z.ZodObject<{
1388
1388
  }, z.core.$strip>>;
1389
1389
  type OntologyScope = z.infer<typeof OntologyScopeSchema>;
1390
1390
 
1391
- /**
1392
- * MetricsCollector
1393
- * Tracks execution timing and ROI metrics
1394
- */
1395
- declare class MetricsCollector {
1396
- private timings;
1397
- private durationMs?;
1398
- /**
1399
- * Start a timer with a label
1400
- */
1401
- startTimer(label: string): void;
1402
- /**
1403
- * End a timer and calculate duration
1404
- * If label is 'execution', stores duration for metrics summary
1405
- */
1406
- endTimer(label: string): number | null;
1407
- /**
1408
- * Build execution metrics summary with optional ROI calculation
1409
- */
1410
- buildExecutionMetrics(metricsConfig?: ResourceMetricsConfig): ExecutionMetricsSummary;
1391
+ type JsonPrimitive = string | number | boolean | null;
1392
+ type JsonValue = JsonPrimitive | JsonValue[] | {
1393
+ [key: string]: JsonValue;
1394
+ };
1395
+ /** Explicit interface needed to annotate the recursive SystemEntrySchema. */
1396
+ interface SystemEntry {
1397
+ id: string;
1398
+ label?: string;
1399
+ title?: string;
1400
+ description?: string;
1401
+ kind?: 'product' | 'operational' | 'platform' | 'diagnostic';
1402
+ parentSystemId?: string;
1403
+ ui?: {
1404
+ path: string;
1405
+ surfaces: string[];
1406
+ icon?: string;
1407
+ order?: number;
1408
+ };
1409
+ lifecycle?: 'draft' | 'beta' | 'active' | 'deprecated' | 'archived';
1410
+ responsibleRoleId?: string;
1411
+ governedByKnowledge?: string[];
1412
+ actions?: {
1413
+ actionId: string;
1414
+ intent: 'exposes' | 'consumes';
1415
+ invocation?: unknown;
1416
+ }[];
1417
+ policies?: string[];
1418
+ drivesGoals?: string[];
1419
+ /** @deprecated Use lifecycle. Accepted for one publish cycle. */
1420
+ status?: 'active' | 'deprecated' | 'archived';
1421
+ path?: string;
1422
+ icon?: string;
1423
+ color?: string;
1424
+ uiPosition?: 'sidebar-primary' | 'sidebar-bottom';
1425
+ enabled?: boolean;
1426
+ devOnly?: boolean;
1427
+ requiresAdmin?: boolean;
1428
+ order: number;
1429
+ config?: Record<string, JsonValue>;
1430
+ ontology?: OntologyScope;
1431
+ systems?: Record<string, SystemEntry>;
1432
+ subsystems?: Record<string, SystemEntry>;
1411
1433
  }
1412
1434
 
1413
- interface BaseAICall {
1414
- callSequence: number;
1415
- callType: 'agent-reasoning' | 'agent-completion' | 'workflow-step' | 'tool' | 'other';
1416
- model: LLMModel;
1417
- inputTokens: number;
1418
- outputTokens: number;
1419
- costUsd: number;
1420
- latencyMs: number;
1421
- context?: AICallContext;
1422
- }
1423
- type AICallContext = AgentReasoningContext | AgentCompletionContext | WorkflowStepContext | ToolCallContext | OtherCallContext;
1424
- interface AgentReasoningContext {
1425
- type: 'agent-reasoning';
1426
- iteration: number;
1427
- actionsPlanned?: string[];
1428
- sessionId?: string;
1429
- turnNumber?: number;
1430
- }
1431
- interface AgentCompletionContext {
1432
- type: 'agent-completion';
1433
- attempt: 1 | 2;
1434
- validationFailed?: boolean;
1435
- sessionId?: string;
1436
- turnNumber?: number;
1437
- }
1438
- interface WorkflowStepContext {
1439
- type: 'workflow-step';
1440
- stepId: string;
1441
- stepName?: string;
1442
- stepSequence?: number;
1443
- }
1444
- interface ToolCallContext {
1445
- type: 'tool';
1446
- toolName: string;
1447
- parentIteration?: number;
1448
- parentStepId?: string;
1449
- }
1450
- interface OtherCallContext {
1451
- type: 'other';
1435
+ declare const SurfaceTypeSchema: z.ZodEnum<{
1436
+ dashboard: "dashboard";
1437
+ settings: "settings";
1438
+ graph: "graph";
1439
+ page: "page";
1440
+ detail: "detail";
1441
+ list: "list";
1442
+ }>;
1443
+ interface SidebarSurfaceNode {
1444
+ type: 'surface';
1445
+ label: string;
1446
+ path: string;
1447
+ surfaceType: z.infer<typeof SurfaceTypeSchema>;
1452
1448
  description?: string;
1453
- metadata?: Record<string, unknown>;
1454
- }
1455
- type AICallRecord = BaseAICall;
1456
- /**
1457
- * Raw LLM usage data returned by adapters
1458
- * Used as input to AIUsageCollector.record()
1459
- */
1460
- interface LLMUsageData {
1461
- model: LLMModel;
1462
- inputTokens: number;
1463
- outputTokens: number;
1464
- latencyMs: number;
1465
- /** Actual cost from provider in USD (when available, e.g., OpenRouter) */
1466
- cost?: number;
1467
- }
1468
- interface AIUsageSummary {
1469
- model: LLMModel;
1470
- totalInputTokens: number;
1471
- totalOutputTokens: number;
1472
- totalTokens: number;
1473
- totalCostUsd: number;
1474
- callCount: number;
1475
- calls: AICallRecord[];
1476
- }
1477
- interface ExecutionMetricsSummary {
1478
- durationMs?: number;
1479
- automationSavingsUsd?: number;
1480
- }
1481
- interface ResourceMetricsConfig {
1482
- estimatedManualMinutes: number;
1483
- hourlyLaborRateUsd: number;
1484
- confidenceLevel?: 'low' | 'medium' | 'high';
1485
- notes?: string;
1449
+ icon?: string;
1450
+ order?: number;
1451
+ targets?: {
1452
+ systems?: string[];
1453
+ entities?: string[];
1454
+ resources?: string[];
1455
+ actions?: string[];
1456
+ };
1457
+ devOnly?: boolean;
1458
+ requiresAdmin?: boolean;
1486
1459
  }
1487
-
1488
- /**
1489
- * AIUsageCollector
1490
- * Centralized token tracking that aggregates usage across all LLM calls in an execution
1491
- */
1492
- declare class AIUsageCollector {
1493
- private model;
1494
- private calls;
1495
- private callSequence;
1496
- /**
1497
- * Record a single AI call with usage metrics
1498
- *
1499
- * @param usage - Token usage and latency data from LLM adapter
1500
- * @param callType - Type discriminator (agent-reasoning, tool, etc.)
1501
- * @param context - Optional typed context specific to callType
1502
- */
1503
- record(usage: LLMUsageData, callType?: BaseAICall['callType'], context?: AICallContext): void;
1504
- /**
1505
- * Get aggregated summary of all AI calls
1506
- */
1507
- getSummary(): AIUsageSummary;
1508
- /**
1509
- * Check if any usage has been recorded
1510
- */
1511
- hasUsage(): boolean;
1460
+ interface SidebarGroupNode {
1461
+ type: 'group';
1462
+ label: string;
1463
+ description?: string;
1464
+ icon?: string;
1465
+ order?: number;
1466
+ children: Record<string, SidebarNode>;
1512
1467
  }
1468
+ type SidebarNode = SidebarSurfaceNode | SidebarGroupNode;
1513
1469
 
1514
- /**
1515
- * Base Execution Engine type definitions
1516
- * Core types shared across all Execution Engine resources
1517
- */
1518
-
1519
- /**
1520
- * Immutable execution metadata
1521
- * Represents complete execution identity (who, what, when, where)
1522
- * Shared across ExecutionContext and ExecutionLoggerContext to eliminate field duplication
1523
- */
1524
- interface ExecutionMetadata {
1525
- executionId: string;
1526
- organizationId: string;
1527
- organizationName: string;
1528
- resourceId: string;
1529
- userId?: string;
1530
- sessionId?: string;
1531
- sessionTurnNumber?: number;
1532
- }
1533
- /**
1534
- * Unified message event type - covers all message types in sessions
1535
- * Replaces separate SessionTurnMessages and AgentActivityEvent mechanisms
1536
- */
1537
- /**
1538
- * Structured action metadata attached to assistant messages.
1539
- * Frontend reads this instead of parsing text prefixes.
1540
- */
1541
- type AssistantAction = {
1542
- kind: 'navigate';
1543
- path: string;
1544
- reason: string;
1545
- } | {
1546
- kind: 'update_filters';
1547
- timeRange: string | null;
1548
- statusFilter: string | null;
1549
- searchQuery: string | null;
1550
- };
1551
- type MessageEvent = {
1552
- type: 'user_message';
1553
- text: string;
1554
- } | {
1555
- type: 'assistant_message';
1556
- text: string;
1557
- _action?: AssistantAction;
1558
- } | {
1559
- type: 'agent:started';
1560
- } | {
1561
- type: 'agent:completed';
1562
- } | {
1563
- type: 'agent:error';
1564
- error: string;
1565
- } | {
1566
- type: 'agent:reasoning';
1567
- iteration: number;
1568
- reasoning: string;
1569
- } | {
1570
- type: 'agent:tool_call';
1571
- toolName: string;
1572
- args: Record<string, unknown>;
1573
- } | {
1574
- type: 'agent:tool_result';
1575
- toolName: string;
1576
- success: boolean;
1577
- result?: unknown;
1578
- error?: string;
1579
- };
1580
- /**
1581
- * Execution context for all resources
1582
- * Unified callback replaces SessionTurnMessages (removed)
1583
- */
1584
- interface ExecutionContext extends ExecutionMetadata {
1585
- logger: IExecutionLogger;
1586
- signal?: AbortSignal;
1587
- onMessageEvent?: (event: MessageEvent) => Promise<void>;
1588
- /** Called per iteration to write heartbeat + check stall status. Non-fatal if it throws. */
1589
- onHeartbeat?: () => Promise<void>;
1590
- aiUsageCollector?: AIUsageCollector;
1591
- metricsCollector?: MetricsCollector;
1592
- parentExecutionId?: string;
1593
- executionDepth: number;
1594
- credentialName?: string;
1595
- store: Map<string, unknown>;
1596
- }
1597
- interface Contract {
1598
- inputSchema: z.ZodSchema;
1599
- outputSchema?: z.ZodSchema;
1600
- }
1601
-
1602
- /**
1603
- * Tool definitions
1604
- *
1605
- * Tool interface used by agents and workflows.
1606
- * Provides a universal interface for AI systems to interact with tools.
1607
- */
1608
-
1609
- /**
1610
- * Options for tool execution
1611
- * Provides named parameters for better API clarity and extensibility
1612
- */
1613
- interface ToolExecutionOptions {
1614
- /** Tool input (validated against inputSchema before execution) */
1615
- input: unknown;
1616
- /** Execution context with multi-tenant isolation and observability (optional for simple tools, required for platform/integration tools) */
1617
- executionContext?: ExecutionContext;
1618
- /** Full iteration context for advanced tools (provides access to memoryManager, toolRegistry, logger, etc.) */
1619
- iterationContext?: IterationContext;
1620
- /** Abort signal for timeout/cancellation -- forward to fetch() calls for clean cancellation */
1621
- signal?: AbortSignal;
1622
- }
1623
- /**
1624
- * Tool interface for AI systems
1625
- *
1626
- * Used by:
1627
- * - Agents: For agentic tool use (reasoning loop selects and executes tools)
1628
- * - Workflows: For workflow step tool invocation (future)
1629
- * - Platform tools: createApprovalTool(), createSchedulerTool()
1630
- * - Integration tools: External API calls (Gmail, Slack, etc.)
1631
- */
1632
- interface Tool {
1633
- name: string;
1634
- description: string;
1635
- inputSchema: z.ZodSchema;
1636
- outputSchema: z.ZodSchema;
1637
- execute: (options: ToolExecutionOptions) => Promise<unknown>;
1638
- timeout?: number;
1639
- }
1640
-
1641
- /**
1642
- * Supported integration types
1643
- *
1644
- * These represent the available integration adapters that can be used with tools.
1645
- * Each integration type corresponds to an adapter implementation.
1646
- *
1647
- * Note: Concrete adapter implementations are deferred until needed.
1648
- * This type provides compile-time safety and auto-completion for tool definitions.
1649
- */
1650
- type IntegrationType = 'gmail' | 'google-sheets' | 'slack' | 'github' | 'linear' | 'attio' | 'airtable' | 'salesforce' | 'hubspot' | 'stripe' | 'twilio' | 'sendgrid' | 'mailgun' | 'zapier' | 'webhook' | 'apify' | 'instantly' | 'resend' | 'signature-api' | 'dropbox' | 'anymailfinder' | 'tomba' | 'millionverifier';
1651
-
1652
- type JsonPrimitive = string | number | boolean | null;
1653
- type JsonValue = JsonPrimitive | JsonValue[] | {
1654
- [key: string]: JsonValue;
1655
- };
1656
- /** Explicit interface needed to annotate the recursive SystemEntrySchema. */
1657
- interface SystemEntry {
1658
- id: string;
1659
- label?: string;
1660
- title?: string;
1661
- description?: string;
1662
- kind?: 'product' | 'operational' | 'platform' | 'diagnostic';
1663
- parentSystemId?: string;
1664
- ui?: {
1665
- path: string;
1666
- surfaces: string[];
1667
- icon?: string;
1668
- order?: number;
1669
- };
1670
- lifecycle?: 'draft' | 'beta' | 'active' | 'deprecated' | 'archived';
1671
- responsibleRoleId?: string;
1672
- governedByKnowledge?: string[];
1673
- actions?: {
1674
- actionId: string;
1675
- intent: 'exposes' | 'consumes';
1676
- invocation?: unknown;
1677
- }[];
1678
- policies?: string[];
1679
- drivesGoals?: string[];
1680
- /** @deprecated Use lifecycle. Accepted for one publish cycle. */
1681
- status?: 'active' | 'deprecated' | 'archived';
1682
- path?: string;
1683
- icon?: string;
1684
- color?: string;
1685
- uiPosition?: 'sidebar-primary' | 'sidebar-bottom';
1686
- enabled?: boolean;
1687
- devOnly?: boolean;
1688
- requiresAdmin?: boolean;
1689
- order: number;
1690
- config?: Record<string, JsonValue>;
1691
- ontology?: OntologyScope;
1692
- systems?: Record<string, SystemEntry>;
1693
- subsystems?: Record<string, SystemEntry>;
1694
- }
1695
-
1696
- /**
1697
- * Resource Registry type definitions
1698
- */
1699
-
1700
- /**
1701
- * Environment/deployment status for resources
1702
- */
1703
- type ResourceStatus = 'dev' | 'prod';
1704
- /**
1705
- * All resource types in the platform
1706
- * Used as the discriminator field in ResourceDefinition
1707
- */
1708
- type ResourceType = 'agent' | 'workflow' | 'trigger' | 'integration' | 'external' | 'human';
1709
- type ResourceSystemSummary = Pick<SystemEntry, 'id' | 'title' | 'description' | 'kind' | 'lifecycle'>;
1710
- /**
1711
- * Base interface for ALL platform resources
1712
- * Shared by both executable (agents, workflows) and non-executable (triggers, integrations, etc.) resources
1713
- */
1714
- interface ResourceDefinition {
1715
- /** Unique resource identifier */
1716
- resourceId: string;
1717
- /** Display name */
1718
- name: string;
1719
- /** Purpose and functionality description */
1720
- description: string;
1721
- /** Version for change tracking and evolution */
1722
- version: string;
1723
- /** Resource type discriminator */
1724
- type: ResourceType;
1725
- /** Environment/deployment status */
1726
- status: ResourceStatus;
1727
- /** Graph links to Organization Model nodes */
1728
- links?: ResourceLink[];
1729
- /** Infrastructure category for filtering */
1730
- category?: ResourceCategory;
1731
- /** Whether the agent supports multi-turn sessions (agents only) */
1732
- sessionCapable?: boolean;
1733
- /** Whether the resource is local (monorepo) or remote (externally deployed) */
1734
- origin?: 'local' | 'remote';
1735
- /** OM System membership — dot-separated system path (e.g. "sys.lead-gen"), when backed by a Resource descriptor */
1736
- systemPath?: string;
1737
- /** Display metadata for the owning OM System */
1738
- system?: ResourceSystemSummary;
1739
- /** Governance lifecycle status from the OM Resource descriptor */
1740
- governanceStatus?: ResourceGovernanceStatus;
1741
- /** Whether this resource is archived and should be excluded from registration and deployment */
1742
- archived?: boolean;
1743
- }
1744
- /** Webhook provider identifiers */
1745
- type WebhookProviderType = 'cal-com' | 'stripe' | 'signature-api' | 'instantly' | 'apify' | 'test';
1746
- /** Webhook trigger configuration */
1747
- interface WebhookTriggerConfig {
1748
- /** Provider identifier */
1749
- provider: WebhookProviderType;
1750
- /** Event type for documentation (not used for matching - workflow handles routing) */
1751
- event?: string;
1752
- /** Optional filtering (e.g., specific form ID for Fillout) */
1753
- filter?: Record<string, string>;
1754
- /** References credential in credentials table for per-org webhook secrets */
1755
- credentialName?: string;
1756
- }
1757
- /** Schedule trigger configuration */
1758
- interface ScheduleTriggerConfig {
1759
- /** Cron expression (e.g., '0 6 * * *') */
1760
- cron: string;
1761
- /** Optional timezone (default: UTC) */
1762
- timezone?: string;
1763
- }
1764
- /** Event trigger configuration */
1765
- interface EventTriggerConfig {
1766
- /** Internal event type */
1767
- eventType: string;
1768
- /** Event source */
1769
- source?: string;
1770
- }
1771
- /** Union of all trigger configs */
1772
- type TriggerConfig = WebhookTriggerConfig | ScheduleTriggerConfig | EventTriggerConfig;
1773
- /**
1774
- * Trigger metadata - entry points that initiate resource execution
1775
- *
1776
- * Triggers represent how executions start: webhooks from external services,
1777
- * scheduled cron jobs, platform events, or manual user actions.
1778
- *
1779
- * BREAKING CHANGES (2025-11-30):
1780
- * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
1781
- * - Field renames: `id` -> `resourceId` (inherited), `type` -> `triggerType`
1782
- * - Relationship rename: `invokes` -> `triggers` (unified vocabulary)
1783
- * - New required fields: `version` (inherited), `type: 'trigger'` (inherited)
1784
- * - triggers object now includes `externalResources` option
1785
- *
1786
- * @example
1787
- * // TriggerDefinition - metadata only
1788
- * {
1789
- * resourceId: 'trigger-new-order',
1790
- * type: 'trigger',
1791
- * triggerType: 'webhook',
1792
- * name: 'New Order',
1793
- * description: 'Webhook from Shopify on new orders',
1794
- * version: '1.0.0',
1795
- * status: 'prod',
1796
- * webhookPath: '/webhooks/shopify/orders'
1797
- * }
1798
- *
1799
- * // Relationships declared in ResourceRelationships (not on TriggerDefinition):
1800
- * // relationships: {
1801
- * // 'trigger-new-order': { triggers: { workflows: ['order-fulfillment-workflow'] } }
1802
- * // }
1803
- */
1804
- interface TriggerDefinition extends ResourceDefinition {
1805
- /** Resource type discriminator (narrowed from base union) */
1806
- type: 'trigger';
1807
- /** Trigger mechanism type (renamed from 'type' to avoid collision with base type discriminator) */
1808
- triggerType: 'webhook' | 'schedule' | 'manual' | 'event';
1809
- /** Type-specific configuration */
1810
- config?: TriggerConfig;
1811
- /** For webhook triggers: path like '/webhooks/shopify/orders' */
1812
- webhookPath?: string;
1813
- /** For schedule triggers: cron expression like '0 6 * * *' */
1814
- schedule?: string;
1815
- /** For event triggers: event type like 'low-stock-alert' */
1816
- eventType?: string;
1817
- }
1818
- /**
1819
- * Integration metadata - external service connections
1820
- *
1821
- * References credentials table for actual connection. No connection status
1822
- * stored here (queried at runtime from credentials table).
1823
- *
1824
- * BREAKING CHANGES (2025-11-30):
1825
- * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
1826
- * - Field renames: `id` -> `resourceId` (inherited)
1827
- * - New required field: `status` (inherited) - organizations must add status to all integrations
1828
- * - New required field: `version` (inherited) - organizations must add version to all integrations
1829
- * - New required field: `type: 'integration'` (inherited) - resource type discriminator
1830
- *
1831
- * @example
1832
- * {
1833
- * resourceId: 'integration-shopify-prod',
1834
- * type: 'integration',
1835
- * provider: 'shopify',
1836
- * credentialName: 'shopify-prod',
1837
- * name: 'Shopify Production',
1838
- * description: 'E-commerce platform',
1839
- * version: '1.0.0',
1840
- * status: 'prod'
1841
- * }
1842
- */
1843
- interface IntegrationDefinition extends ResourceDefinition {
1844
- /** Resource type discriminator (narrowed from base union) */
1845
- type: 'integration';
1846
- /** OM descriptor that owns canonical identity and governance metadata. */
1847
- resource?: Extract<ResourceEntry, {
1848
- kind: 'integration';
1849
- }>;
1850
- /** Integration provider type */
1851
- provider: IntegrationType;
1852
- /** References credentials table (e.g., 'shopify-prod', 'zendesk-api') */
1853
- credentialName: string;
1854
- }
1855
- /**
1856
- * Explicit resource relationship declaration
1857
- *
1858
- * Single-direction only - Command View derives reverse relationships.
1859
- * Agents/workflows declare what they trigger and use.
1860
- *
1861
- * @example
1862
- * {
1863
- * triggers: { workflows: ['order-fulfillment-workflow'] },
1864
- * uses: { integrations: ['integration-shopify-prod', 'integration-postgres'] }
1865
- * }
1866
- */
1867
- interface RelationshipDeclaration {
1868
- /** Resources this resource triggers */
1869
- triggers?: {
1870
- /** Agent resourceIds this resource triggers */
1871
- agents?: string[];
1872
- /** Workflow resourceIds this resource triggers */
1873
- workflows?: string[];
1874
- };
1875
- /** Integrations this resource uses */
1876
- uses?: {
1877
- /** Integration IDs this resource uses */
1878
- integrations?: string[];
1879
- };
1880
- }
1881
- /**
1882
- * Resource relationships map
1883
- * Maps resourceId to its relationship declarations
1884
- *
1885
- * @example
1886
- * {
1887
- * 'order-processor-agent': {
1888
- * triggers: { workflows: ['order-fulfillment-workflow'] },
1889
- * uses: { integrations: ['integration-shopify-prod'] }
1890
- * }
1891
- * }
1892
- */
1893
- type ResourceRelationships = Record<string, RelationshipDeclaration>;
1894
- /**
1895
- * External platform type
1896
- * Supported third-party automation platforms
1897
- */
1898
- type ExternalPlatform = 'n8n' | 'make' | 'zapier' | 'other';
1899
- /**
1900
- * External automation resource metadata
1901
- *
1902
- * Represents workflows/automations running on third-party platforms
1903
- * (n8n, Make, Zapier, etc.) for visualization in Command View.
1904
- *
1905
- * NOTE: This is metadata ONLY for visualization. No execution logic,
1906
- * no API integration with external platforms, no status syncing.
1907
- *
1908
- * BREAKING CHANGES (2025-11-30):
1909
- * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
1910
- * - Field renames: `id` -> `resourceId` (inherited)
1911
- * - New required field: `version` (inherited) - organizations must add version to all external resources
1912
- * - New required field: `type: 'external'` (inherited) - resource type discriminator
1913
- * - REMOVED FIELD: `triggeredBy` - per relationship-consolidation design, all relationships are forward-only declarations
1914
- *
1915
- * @example
1916
- * {
1917
- * resourceId: 'external-n8n-order-sync',
1918
- * type: 'external',
1919
- * version: '1.0.0',
1920
- * platform: 'n8n',
1921
- * name: 'Shopify Order Sync',
1922
- * description: 'Legacy n8n workflow for syncing Shopify orders',
1923
- * status: 'prod',
1924
- * platformUrl: 'https://n8n.client.com/workflow/123',
1925
- * triggers: { workflows: ['order-fulfillment-workflow'] },
1926
- * uses: { integrations: ['integration-shopify-prod'] }
1927
- * }
1928
- */
1929
- interface ExternalResourceDefinition extends ResourceDefinition {
1930
- /** Resource type discriminator (narrowed from base union) */
1931
- type: 'external';
1932
- /** Platform type */
1933
- platform: ExternalPlatform;
1934
- /** Link to external platform (e.g., n8n workflow editor URL) */
1935
- platformUrl?: string;
1936
- /** Platform's internal ID/reference */
1937
- externalId?: string;
1938
- /** What this external resource triggers (external -> internal) */
1939
- triggers?: {
1940
- /** Elevasis workflow resourceIds this external automation triggers */
1941
- workflows?: string[];
1942
- /** Elevasis agent resourceIds this external automation triggers */
1943
- agents?: string[];
1944
- };
1945
- /** Integrations this external resource uses (shared credentials) */
1946
- uses?: {
1947
- /** Integration IDs this external automation uses */
1948
- integrations?: string[];
1949
- };
1950
- }
1951
- /**
1952
- * Human Checkpoint definition - human decision points in automation
1953
- *
1954
- * Represents where human judgment is deployed in the automation landscape.
1955
- * Tasks with matching command_queue_group are routed to this checkpoint.
1956
- *
1957
- * BREAKING CHANGES (2025-11-30):
1958
- * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
1959
- * - Field renames: `id` -> `resourceId` (inherited)
1960
- * - description is now REQUIRED (was optional) - organizations must add description to all human checkpoints
1961
- * - New required field: `version` (inherited) - organizations must add version to all human checkpoints
1962
- * - New required field: `type: 'human'` (inherited) - resource type discriminator
1963
- *
1964
- * @example
1965
- * {
1966
- * resourceId: 'sales-approval',
1967
- * type: 'human',
1968
- * name: 'Sales Approval Queue',
1969
- * description: 'High-value order approvals for sales team',
1970
- * version: '1.0.0',
1971
- * status: 'prod',
1972
- * requestedBy: { agents: ['order-processor-agent'] },
1973
- * routesTo: { agents: ['order-fulfillment-agent'] }
1974
- * }
1975
- */
1976
- interface HumanCheckpointDefinition extends ResourceDefinition {
1977
- /** Resource type discriminator (narrowed from base union) */
1978
- type: 'human';
1979
- /** Resources that create tasks for this checkpoint */
1980
- requestedBy?: {
1981
- /** Agent resourceIds that request approval here */
1982
- agents?: string[];
1983
- /** Workflow resourceIds that request approval here */
1984
- workflows?: string[];
1985
- };
1986
- /** Resources that receive approved decisions */
1987
- routesTo?: {
1988
- /** Agent resourceIds that handle approved tasks */
1989
- agents?: string[];
1990
- /** Workflow resourceIds that handle approved tasks */
1991
- workflows?: string[];
1992
- };
1993
- }
1994
-
1995
- declare const SurfaceTypeSchema: z.ZodEnum<{
1996
- dashboard: "dashboard";
1997
- settings: "settings";
1998
- graph: "graph";
1999
- list: "list";
2000
- page: "page";
2001
- detail: "detail";
2002
- }>;
2003
- interface SidebarSurfaceNode {
2004
- type: 'surface';
2005
- label: string;
2006
- path: string;
2007
- surfaceType: z.infer<typeof SurfaceTypeSchema>;
2008
- description?: string;
2009
- icon?: string;
2010
- order?: number;
2011
- targets?: {
2012
- systems?: string[];
2013
- entities?: string[];
2014
- resources?: string[];
2015
- actions?: string[];
2016
- };
2017
- devOnly?: boolean;
2018
- requiresAdmin?: boolean;
2019
- }
2020
- interface SidebarGroupNode {
2021
- type: 'group';
2022
- label: string;
2023
- description?: string;
2024
- icon?: string;
2025
- order?: number;
2026
- children: Record<string, SidebarNode>;
2027
- }
2028
- type SidebarNode = SidebarSurfaceNode | SidebarGroupNode;
2029
-
2030
- declare const LinkSchema: z.ZodObject<{
2031
- nodeId: z.ZodString;
2032
- kind: z.ZodEnum<{
2033
- links: "links";
2034
- affects: "affects";
2035
- effects: "effects";
2036
- actions: "actions";
2037
- reads: "reads";
2038
- writes: "writes";
2039
- emits: "emits";
2040
- triggers: "triggers";
2041
- uses: "uses";
2042
- approval: "approval";
2043
- contains: "contains";
2044
- references: "references";
2045
- maps_to: "maps_to";
2046
- governs: "governs";
2047
- originates_from: "originates_from";
2048
- applies_to: "applies_to";
2049
- uses_catalog: "uses_catalog";
2050
- }>;
2051
- }, z.core.$strip>;
2052
- type Link = z.infer<typeof LinkSchema>;
1470
+ declare const LinkSchema: z.ZodObject<{
1471
+ nodeId: z.ZodString;
1472
+ kind: z.ZodEnum<{
1473
+ affects: "affects";
1474
+ actions: "actions";
1475
+ effects: "effects";
1476
+ links: "links";
1477
+ reads: "reads";
1478
+ writes: "writes";
1479
+ emits: "emits";
1480
+ triggers: "triggers";
1481
+ uses: "uses";
1482
+ approval: "approval";
1483
+ contains: "contains";
1484
+ references: "references";
1485
+ maps_to: "maps_to";
1486
+ governs: "governs";
1487
+ originates_from: "originates_from";
1488
+ applies_to: "applies_to";
1489
+ uses_catalog: "uses_catalog";
1490
+ }>;
1491
+ }, z.core.$strip>;
1492
+ type Link = z.infer<typeof LinkSchema>;
2053
1493
 
2054
1494
  declare const OrganizationModelSchema$1: z.ZodObject<{
2055
1495
  version: z.ZodDefault<z.ZodLiteral<1>>;
@@ -2225,7 +1665,7 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2225
1665
  lastModified: string;
2226
1666
  } | undefined;
2227
1667
  }>>;
2228
- branding: z.ZodObject<{
1668
+ branding: z.ZodDefault<z.ZodObject<{
2229
1669
  organizationName: z.ZodString;
2230
1670
  productName: z.ZodString;
2231
1671
  shortName: z.ZodString;
@@ -2234,7 +1674,7 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2234
1674
  light: z.ZodOptional<z.ZodString>;
2235
1675
  dark: z.ZodOptional<z.ZodString>;
2236
1676
  }, z.core.$strip>>;
2237
- }, z.core.$strip>;
1677
+ }, z.core.$strip>>;
2238
1678
  navigation: z.ZodDefault<z.ZodObject<{
2239
1679
  sidebar: z.ZodDefault<z.ZodObject<{
2240
1680
  primary: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<SidebarNode, unknown, z.core.$ZodTypeInternals<SidebarNode, unknown>>>>;
@@ -2455,8 +1895,8 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2455
1895
  description: z.ZodOptional<z.ZodString>;
2456
1896
  ownerRoleId: z.ZodOptional<z.ZodString>;
2457
1897
  status: z.ZodEnum<{
2458
- deprecated: "deprecated";
2459
1898
  active: "active";
1899
+ deprecated: "deprecated";
2460
1900
  archived: "archived";
2461
1901
  }>;
2462
1902
  ontology: z.ZodOptional<z.ZodObject<{
@@ -2474,12 +1914,12 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2474
1914
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
2475
1915
  path: z.ZodString;
2476
1916
  role: z.ZodEnum<{
2477
- config: "config";
2478
1917
  entrypoint: "entrypoint";
2479
1918
  handler: "handler";
2480
1919
  schema: "schema";
2481
1920
  test: "test";
2482
1921
  docs: "docs";
1922
+ config: "config";
2483
1923
  }>;
2484
1924
  symbol: z.ZodOptional<z.ZodString>;
2485
1925
  description: z.ZodOptional<z.ZodString>;
@@ -2490,10 +1930,10 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2490
1930
  label: z.ZodString;
2491
1931
  payloadSchema: z.ZodOptional<z.ZodString>;
2492
1932
  lifecycle: z.ZodOptional<z.ZodEnum<{
1933
+ active: "active";
2493
1934
  deprecated: "deprecated";
2494
1935
  draft: "draft";
2495
1936
  beta: "beta";
2496
- active: "active";
2497
1937
  archived: "archived";
2498
1938
  }>>;
2499
1939
  }, z.core.$strip>>>;
@@ -2505,8 +1945,8 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2505
1945
  description: z.ZodOptional<z.ZodString>;
2506
1946
  ownerRoleId: z.ZodOptional<z.ZodString>;
2507
1947
  status: z.ZodEnum<{
2508
- deprecated: "deprecated";
2509
1948
  active: "active";
1949
+ deprecated: "deprecated";
2510
1950
  archived: "archived";
2511
1951
  }>;
2512
1952
  ontology: z.ZodOptional<z.ZodObject<{
@@ -2524,12 +1964,12 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2524
1964
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
2525
1965
  path: z.ZodString;
2526
1966
  role: z.ZodEnum<{
2527
- config: "config";
2528
1967
  entrypoint: "entrypoint";
2529
1968
  handler: "handler";
2530
1969
  schema: "schema";
2531
1970
  test: "test";
2532
1971
  docs: "docs";
1972
+ config: "config";
2533
1973
  }>;
2534
1974
  symbol: z.ZodOptional<z.ZodString>;
2535
1975
  description: z.ZodOptional<z.ZodString>;
@@ -2571,10 +2011,10 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2571
2011
  label: z.ZodString;
2572
2012
  payloadSchema: z.ZodOptional<z.ZodString>;
2573
2013
  lifecycle: z.ZodOptional<z.ZodEnum<{
2014
+ active: "active";
2574
2015
  deprecated: "deprecated";
2575
2016
  draft: "draft";
2576
2017
  beta: "beta";
2577
- active: "active";
2578
2018
  archived: "archived";
2579
2019
  }>>;
2580
2020
  }, z.core.$strip>>>;
@@ -2586,8 +2026,8 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2586
2026
  description: z.ZodOptional<z.ZodString>;
2587
2027
  ownerRoleId: z.ZodOptional<z.ZodString>;
2588
2028
  status: z.ZodEnum<{
2589
- deprecated: "deprecated";
2590
2029
  active: "active";
2030
+ deprecated: "deprecated";
2591
2031
  archived: "archived";
2592
2032
  }>;
2593
2033
  ontology: z.ZodOptional<z.ZodObject<{
@@ -2605,12 +2045,12 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2605
2045
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
2606
2046
  path: z.ZodString;
2607
2047
  role: z.ZodEnum<{
2608
- config: "config";
2609
2048
  entrypoint: "entrypoint";
2610
2049
  handler: "handler";
2611
2050
  schema: "schema";
2612
2051
  test: "test";
2613
2052
  docs: "docs";
2053
+ config: "config";
2614
2054
  }>;
2615
2055
  symbol: z.ZodOptional<z.ZodString>;
2616
2056
  description: z.ZodOptional<z.ZodString>;
@@ -2625,8 +2065,8 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2625
2065
  description: z.ZodOptional<z.ZodString>;
2626
2066
  ownerRoleId: z.ZodOptional<z.ZodString>;
2627
2067
  status: z.ZodEnum<{
2628
- deprecated: "deprecated";
2629
2068
  active: "active";
2069
+ deprecated: "deprecated";
2630
2070
  archived: "archived";
2631
2071
  }>;
2632
2072
  ontology: z.ZodOptional<z.ZodObject<{
@@ -2644,12 +2084,12 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2644
2084
  codeRefs: z.ZodDefault<z.ZodArray<z.ZodObject<{
2645
2085
  path: z.ZodString;
2646
2086
  role: z.ZodEnum<{
2647
- config: "config";
2648
2087
  entrypoint: "entrypoint";
2649
2088
  handler: "handler";
2650
2089
  schema: "schema";
2651
2090
  test: "test";
2652
2091
  docs: "docs";
2092
+ config: "config";
2653
2093
  }>;
2654
2094
  symbol: z.ZodOptional<z.ZodString>;
2655
2095
  description: z.ZodOptional<z.ZodString>;
@@ -2763,10 +2203,10 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2763
2203
  }, z.core.$strip>], "kind">>>;
2764
2204
  knowledge: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodString>>>;
2765
2205
  lifecycle: z.ZodDefault<z.ZodEnum<{
2206
+ active: "active";
2766
2207
  deprecated: "deprecated";
2767
2208
  draft: "draft";
2768
2209
  beta: "beta";
2769
- active: "active";
2770
2210
  archived: "archived";
2771
2211
  }>>;
2772
2212
  }, z.core.$strip>>>>;
@@ -2844,10 +2284,10 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2844
2284
  roleIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
2845
2285
  }, z.core.$strip>>;
2846
2286
  lifecycle: z.ZodDefault<z.ZodEnum<{
2287
+ active: "active";
2847
2288
  deprecated: "deprecated";
2848
2289
  draft: "draft";
2849
2290
  beta: "beta";
2850
- active: "active";
2851
2291
  archived: "archived";
2852
2292
  }>>;
2853
2293
  }, z.core.$strip>>>>;
@@ -2930,12 +2370,12 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2930
2370
  kind: z.ZodEnum<{
2931
2371
  knowledge: "knowledge";
2932
2372
  system: "system";
2373
+ resource: "resource";
2933
2374
  action: "action";
2934
2375
  ontology: "ontology";
2935
2376
  role: "role";
2936
- goal: "goal";
2937
- resource: "resource";
2938
2377
  stage: "stage";
2378
+ goal: "goal";
2939
2379
  "customer-segment": "customer-segment";
2940
2380
  offering: "offering";
2941
2381
  }>;
@@ -2945,7 +2385,7 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2945
2385
  nodeId: z.ZodUnion<readonly [z.ZodString, z.ZodTemplateLiteral<`ontology:${string}`>]>;
2946
2386
  }, z.core.$strip>]>, z.ZodTransform<{
2947
2387
  target: {
2948
- kind: "knowledge" | "system" | "action" | "ontology" | "role" | "goal" | "resource" | "stage" | "customer-segment" | "offering";
2388
+ kind: "knowledge" | "system" | "resource" | "action" | "ontology" | "role" | "stage" | "goal" | "customer-segment" | "offering";
2949
2389
  id: string;
2950
2390
  };
2951
2391
  nodeId: string;
@@ -2953,7 +2393,7 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2953
2393
  nodeId: string;
2954
2394
  } | {
2955
2395
  target: {
2956
- kind: "knowledge" | "system" | "action" | "ontology" | "role" | "goal" | "resource" | "stage" | "customer-segment" | "offering";
2396
+ kind: "knowledge" | "system" | "resource" | "action" | "ontology" | "role" | "stage" | "goal" | "customer-segment" | "offering";
2957
2397
  id: string;
2958
2398
  };
2959
2399
  }>>>>;
@@ -2962,7 +2402,567 @@ declare const OrganizationModelSchema$1: z.ZodObject<{
2962
2402
  }, z.core.$strip>>>>;
2963
2403
  }, z.core.$strip>;
2964
2404
 
2965
- type OrganizationModel$1 = z.infer<typeof OrganizationModelSchema$1>;
2405
+ type OrganizationModel$1 = z.infer<typeof OrganizationModelSchema$1>;
2406
+
2407
+ /**
2408
+ * MetricsCollector
2409
+ * Tracks execution timing and ROI metrics
2410
+ */
2411
+ declare class MetricsCollector {
2412
+ private timings;
2413
+ private durationMs?;
2414
+ /**
2415
+ * Start a timer with a label
2416
+ */
2417
+ startTimer(label: string): void;
2418
+ /**
2419
+ * End a timer and calculate duration
2420
+ * If label is 'execution', stores duration for metrics summary
2421
+ */
2422
+ endTimer(label: string): number | null;
2423
+ /**
2424
+ * Build execution metrics summary with optional ROI calculation
2425
+ */
2426
+ buildExecutionMetrics(metricsConfig?: ResourceMetricsConfig): ExecutionMetricsSummary;
2427
+ }
2428
+
2429
+ interface BaseAICall {
2430
+ callSequence: number;
2431
+ callType: 'agent-reasoning' | 'agent-completion' | 'workflow-step' | 'tool' | 'other';
2432
+ model: LLMModel;
2433
+ inputTokens: number;
2434
+ outputTokens: number;
2435
+ costUsd: number;
2436
+ latencyMs: number;
2437
+ context?: AICallContext;
2438
+ }
2439
+ type AICallContext = AgentReasoningContext | AgentCompletionContext | WorkflowStepContext | ToolCallContext | OtherCallContext;
2440
+ interface AgentReasoningContext {
2441
+ type: 'agent-reasoning';
2442
+ iteration: number;
2443
+ actionsPlanned?: string[];
2444
+ sessionId?: string;
2445
+ turnNumber?: number;
2446
+ }
2447
+ interface AgentCompletionContext {
2448
+ type: 'agent-completion';
2449
+ attempt: 1 | 2;
2450
+ validationFailed?: boolean;
2451
+ sessionId?: string;
2452
+ turnNumber?: number;
2453
+ }
2454
+ interface WorkflowStepContext {
2455
+ type: 'workflow-step';
2456
+ stepId: string;
2457
+ stepName?: string;
2458
+ stepSequence?: number;
2459
+ }
2460
+ interface ToolCallContext {
2461
+ type: 'tool';
2462
+ toolName: string;
2463
+ parentIteration?: number;
2464
+ parentStepId?: string;
2465
+ }
2466
+ interface OtherCallContext {
2467
+ type: 'other';
2468
+ description?: string;
2469
+ metadata?: Record<string, unknown>;
2470
+ }
2471
+ type AICallRecord = BaseAICall;
2472
+ /**
2473
+ * Raw LLM usage data returned by adapters
2474
+ * Used as input to AIUsageCollector.record()
2475
+ */
2476
+ interface LLMUsageData {
2477
+ model: LLMModel;
2478
+ inputTokens: number;
2479
+ outputTokens: number;
2480
+ latencyMs: number;
2481
+ /** Actual cost from provider in USD (when available, e.g., OpenRouter) */
2482
+ cost?: number;
2483
+ }
2484
+ interface AIUsageSummary {
2485
+ model: LLMModel;
2486
+ totalInputTokens: number;
2487
+ totalOutputTokens: number;
2488
+ totalTokens: number;
2489
+ totalCostUsd: number;
2490
+ callCount: number;
2491
+ calls: AICallRecord[];
2492
+ }
2493
+ interface ExecutionMetricsSummary {
2494
+ durationMs?: number;
2495
+ automationSavingsUsd?: number;
2496
+ }
2497
+ interface ResourceMetricsConfig {
2498
+ estimatedManualMinutes: number;
2499
+ hourlyLaborRateUsd: number;
2500
+ confidenceLevel?: 'low' | 'medium' | 'high';
2501
+ notes?: string;
2502
+ }
2503
+
2504
+ /**
2505
+ * AIUsageCollector
2506
+ * Centralized token tracking that aggregates usage across all LLM calls in an execution
2507
+ */
2508
+ declare class AIUsageCollector {
2509
+ private model;
2510
+ private calls;
2511
+ private callSequence;
2512
+ /**
2513
+ * Record a single AI call with usage metrics
2514
+ *
2515
+ * @param usage - Token usage and latency data from LLM adapter
2516
+ * @param callType - Type discriminator (agent-reasoning, tool, etc.)
2517
+ * @param context - Optional typed context specific to callType
2518
+ */
2519
+ record(usage: LLMUsageData, callType?: BaseAICall['callType'], context?: AICallContext): void;
2520
+ /**
2521
+ * Get aggregated summary of all AI calls
2522
+ */
2523
+ getSummary(): AIUsageSummary;
2524
+ /**
2525
+ * Check if any usage has been recorded
2526
+ */
2527
+ hasUsage(): boolean;
2528
+ }
2529
+
2530
+ /**
2531
+ * Base Execution Engine type definitions
2532
+ * Core types shared across all Execution Engine resources
2533
+ */
2534
+
2535
+ /**
2536
+ * Immutable execution metadata
2537
+ * Represents complete execution identity (who, what, when, where)
2538
+ * Shared across ExecutionContext and ExecutionLoggerContext to eliminate field duplication
2539
+ */
2540
+ interface ExecutionMetadata {
2541
+ executionId: string;
2542
+ organizationId: string;
2543
+ organizationName: string;
2544
+ resourceId: string;
2545
+ userId?: string;
2546
+ sessionId?: string;
2547
+ sessionTurnNumber?: number;
2548
+ }
2549
+ /**
2550
+ * Unified message event type - covers all message types in sessions
2551
+ * Replaces separate SessionTurnMessages and AgentActivityEvent mechanisms
2552
+ */
2553
+ /**
2554
+ * Structured action metadata attached to assistant messages.
2555
+ * Frontend reads this instead of parsing text prefixes.
2556
+ */
2557
+ type AssistantAction = {
2558
+ kind: 'navigate';
2559
+ path: string;
2560
+ reason: string;
2561
+ } | {
2562
+ kind: 'update_filters';
2563
+ timeRange: string | null;
2564
+ statusFilter: string | null;
2565
+ searchQuery: string | null;
2566
+ };
2567
+ type MessageEvent = {
2568
+ type: 'user_message';
2569
+ text: string;
2570
+ } | {
2571
+ type: 'assistant_message';
2572
+ text: string;
2573
+ _action?: AssistantAction;
2574
+ } | {
2575
+ type: 'agent:started';
2576
+ } | {
2577
+ type: 'agent:completed';
2578
+ } | {
2579
+ type: 'agent:error';
2580
+ error: string;
2581
+ } | {
2582
+ type: 'agent:reasoning';
2583
+ iteration: number;
2584
+ reasoning: string;
2585
+ } | {
2586
+ type: 'agent:tool_call';
2587
+ toolName: string;
2588
+ args: Record<string, unknown>;
2589
+ } | {
2590
+ type: 'agent:tool_result';
2591
+ toolName: string;
2592
+ success: boolean;
2593
+ result?: unknown;
2594
+ error?: string;
2595
+ };
2596
+ /**
2597
+ * Execution context for all resources
2598
+ * Unified callback replaces SessionTurnMessages (removed)
2599
+ */
2600
+ interface ExecutionContext extends ExecutionMetadata {
2601
+ logger: IExecutionLogger;
2602
+ signal?: AbortSignal;
2603
+ onMessageEvent?: (event: MessageEvent) => Promise<void>;
2604
+ /** Called per iteration to write heartbeat + check stall status. Non-fatal if it throws. */
2605
+ onHeartbeat?: () => Promise<void>;
2606
+ aiUsageCollector?: AIUsageCollector;
2607
+ metricsCollector?: MetricsCollector;
2608
+ parentExecutionId?: string;
2609
+ executionDepth: number;
2610
+ credentialName?: string;
2611
+ store: Map<string, unknown>;
2612
+ }
2613
+ interface Contract {
2614
+ inputSchema: z.ZodSchema;
2615
+ outputSchema?: z.ZodSchema;
2616
+ }
2617
+
2618
+ /**
2619
+ * Tool definitions
2620
+ *
2621
+ * Tool interface used by agents and workflows.
2622
+ * Provides a universal interface for AI systems to interact with tools.
2623
+ */
2624
+
2625
+ /**
2626
+ * Options for tool execution
2627
+ * Provides named parameters for better API clarity and extensibility
2628
+ */
2629
+ interface ToolExecutionOptions {
2630
+ /** Tool input (validated against inputSchema before execution) */
2631
+ input: unknown;
2632
+ /** Execution context with multi-tenant isolation and observability (optional for simple tools, required for platform/integration tools) */
2633
+ executionContext?: ExecutionContext;
2634
+ /** Full iteration context for advanced tools (provides access to memoryManager, toolRegistry, logger, etc.) */
2635
+ iterationContext?: IterationContext;
2636
+ /** Abort signal for timeout/cancellation -- forward to fetch() calls for clean cancellation */
2637
+ signal?: AbortSignal;
2638
+ }
2639
+ /**
2640
+ * Tool interface for AI systems
2641
+ *
2642
+ * Used by:
2643
+ * - Agents: For agentic tool use (reasoning loop selects and executes tools)
2644
+ * - Workflows: For workflow step tool invocation (future)
2645
+ * - Platform tools: createApprovalTool(), createSchedulerTool()
2646
+ * - Integration tools: External API calls (Gmail, Slack, etc.)
2647
+ */
2648
+ interface Tool {
2649
+ name: string;
2650
+ description: string;
2651
+ inputSchema: z.ZodSchema;
2652
+ outputSchema: z.ZodSchema;
2653
+ execute: (options: ToolExecutionOptions) => Promise<unknown>;
2654
+ timeout?: number;
2655
+ }
2656
+
2657
+ /**
2658
+ * Supported integration types
2659
+ *
2660
+ * These represent the available integration adapters that can be used with tools.
2661
+ * Each integration type corresponds to an adapter implementation.
2662
+ *
2663
+ * Note: Concrete adapter implementations are deferred until needed.
2664
+ * This type provides compile-time safety and auto-completion for tool definitions.
2665
+ */
2666
+ type IntegrationType = 'gmail' | 'google-sheets' | 'slack' | 'github' | 'linear' | 'attio' | 'airtable' | 'salesforce' | 'hubspot' | 'stripe' | 'twilio' | 'sendgrid' | 'mailgun' | 'zapier' | 'webhook' | 'apify' | 'instantly' | 'resend' | 'signature-api' | 'dropbox' | 'anymailfinder' | 'tomba' | 'millionverifier';
2667
+
2668
+ /**
2669
+ * Resource Registry type definitions
2670
+ */
2671
+
2672
+ /**
2673
+ * Environment/deployment status for resources
2674
+ */
2675
+ type ResourceStatus = 'dev' | 'prod';
2676
+ /**
2677
+ * All resource types in the platform
2678
+ * Used as the discriminator field in ResourceDefinition
2679
+ */
2680
+ type ResourceType = 'agent' | 'workflow' | 'trigger' | 'integration' | 'external' | 'human';
2681
+ type ResourceSystemSummary = Pick<SystemEntry, 'id' | 'title' | 'description' | 'kind' | 'lifecycle'>;
2682
+ /**
2683
+ * Base interface for ALL platform resources
2684
+ * Shared by both executable (agents, workflows) and non-executable (triggers, integrations, etc.) resources
2685
+ */
2686
+ interface ResourceDefinition {
2687
+ /** Unique resource identifier */
2688
+ resourceId: string;
2689
+ /** Display name */
2690
+ name: string;
2691
+ /** Purpose and functionality description */
2692
+ description: string;
2693
+ /** Version for change tracking and evolution */
2694
+ version: string;
2695
+ /** Resource type discriminator */
2696
+ type: ResourceType;
2697
+ /** Environment/deployment status */
2698
+ status: ResourceStatus;
2699
+ /** Graph links to Organization Model nodes */
2700
+ links?: ResourceLink[];
2701
+ /** Infrastructure category for filtering */
2702
+ category?: ResourceCategory;
2703
+ /** Whether the agent supports multi-turn sessions (agents only) */
2704
+ sessionCapable?: boolean;
2705
+ /** Whether the resource is local (monorepo) or remote (externally deployed) */
2706
+ origin?: 'local' | 'remote';
2707
+ /** OM System membership — dot-separated system path (e.g. "sys.lead-gen"), when backed by a Resource descriptor */
2708
+ systemPath?: string;
2709
+ /** Display metadata for the owning OM System */
2710
+ system?: ResourceSystemSummary;
2711
+ /** Governance lifecycle status from the OM Resource descriptor */
2712
+ governanceStatus?: ResourceGovernanceStatus;
2713
+ /** Whether this resource is archived and should be excluded from registration and deployment */
2714
+ archived?: boolean;
2715
+ }
2716
+ /** Webhook provider identifiers */
2717
+ type WebhookProviderType = 'cal-com' | 'stripe' | 'signature-api' | 'instantly' | 'apify' | 'test';
2718
+ /** Webhook trigger configuration */
2719
+ interface WebhookTriggerConfig {
2720
+ /** Provider identifier */
2721
+ provider: WebhookProviderType;
2722
+ /** Event type for documentation (not used for matching - workflow handles routing) */
2723
+ event?: string;
2724
+ /** Optional filtering (e.g., specific form ID for Fillout) */
2725
+ filter?: Record<string, string>;
2726
+ /** References credential in credentials table for per-org webhook secrets */
2727
+ credentialName?: string;
2728
+ }
2729
+ /** Schedule trigger configuration */
2730
+ interface ScheduleTriggerConfig {
2731
+ /** Cron expression (e.g., '0 6 * * *') */
2732
+ cron: string;
2733
+ /** Optional timezone (default: UTC) */
2734
+ timezone?: string;
2735
+ }
2736
+ /** Event trigger configuration */
2737
+ interface EventTriggerConfig {
2738
+ /** Internal event type */
2739
+ eventType: string;
2740
+ /** Event source */
2741
+ source?: string;
2742
+ }
2743
+ /** Union of all trigger configs */
2744
+ type TriggerConfig = WebhookTriggerConfig | ScheduleTriggerConfig | EventTriggerConfig;
2745
+ /**
2746
+ * Trigger metadata - entry points that initiate resource execution
2747
+ *
2748
+ * Triggers represent how executions start: webhooks from external services,
2749
+ * scheduled cron jobs, platform events, or manual user actions.
2750
+ *
2751
+ * BREAKING CHANGES (2025-11-30):
2752
+ * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
2753
+ * - Field renames: `id` -> `resourceId` (inherited), `type` -> `triggerType`
2754
+ * - Relationship rename: `invokes` -> `triggers` (unified vocabulary)
2755
+ * - New required fields: `version` (inherited), `type: 'trigger'` (inherited)
2756
+ * - triggers object now includes `externalResources` option
2757
+ *
2758
+ * @example
2759
+ * // TriggerDefinition - metadata only
2760
+ * {
2761
+ * resourceId: 'trigger-new-order',
2762
+ * type: 'trigger',
2763
+ * triggerType: 'webhook',
2764
+ * name: 'New Order',
2765
+ * description: 'Webhook from Shopify on new orders',
2766
+ * version: '1.0.0',
2767
+ * status: 'prod',
2768
+ * webhookPath: '/webhooks/shopify/orders'
2769
+ * }
2770
+ *
2771
+ * // Relationships declared in ResourceRelationships (not on TriggerDefinition):
2772
+ * // relationships: {
2773
+ * // 'trigger-new-order': { triggers: { workflows: ['order-fulfillment-workflow'] } }
2774
+ * // }
2775
+ */
2776
+ interface TriggerDefinition extends ResourceDefinition {
2777
+ /** Resource type discriminator (narrowed from base union) */
2778
+ type: 'trigger';
2779
+ /** Trigger mechanism type (renamed from 'type' to avoid collision with base type discriminator) */
2780
+ triggerType: 'webhook' | 'schedule' | 'manual' | 'event';
2781
+ /** Type-specific configuration */
2782
+ config?: TriggerConfig;
2783
+ /** For webhook triggers: path like '/webhooks/shopify/orders' */
2784
+ webhookPath?: string;
2785
+ /** For schedule triggers: cron expression like '0 6 * * *' */
2786
+ schedule?: string;
2787
+ /** For event triggers: event type like 'low-stock-alert' */
2788
+ eventType?: string;
2789
+ }
2790
+ /**
2791
+ * Integration metadata - external service connections
2792
+ *
2793
+ * References credentials table for actual connection. No connection status
2794
+ * stored here (queried at runtime from credentials table).
2795
+ *
2796
+ * BREAKING CHANGES (2025-11-30):
2797
+ * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
2798
+ * - Field renames: `id` -> `resourceId` (inherited)
2799
+ * - New required field: `status` (inherited) - organizations must add status to all integrations
2800
+ * - New required field: `version` (inherited) - organizations must add version to all integrations
2801
+ * - New required field: `type: 'integration'` (inherited) - resource type discriminator
2802
+ *
2803
+ * @example
2804
+ * {
2805
+ * resourceId: 'integration-shopify-prod',
2806
+ * type: 'integration',
2807
+ * provider: 'shopify',
2808
+ * credentialName: 'shopify-prod',
2809
+ * name: 'Shopify Production',
2810
+ * description: 'E-commerce platform',
2811
+ * version: '1.0.0',
2812
+ * status: 'prod'
2813
+ * }
2814
+ */
2815
+ interface IntegrationDefinition extends ResourceDefinition {
2816
+ /** Resource type discriminator (narrowed from base union) */
2817
+ type: 'integration';
2818
+ /** OM descriptor that owns canonical identity and governance metadata. */
2819
+ resource?: Extract<ResourceEntry, {
2820
+ kind: 'integration';
2821
+ }>;
2822
+ /** Integration provider type */
2823
+ provider: IntegrationType;
2824
+ /** References credentials table (e.g., 'shopify-prod', 'zendesk-api') */
2825
+ credentialName: string;
2826
+ }
2827
+ /**
2828
+ * Explicit resource relationship declaration
2829
+ *
2830
+ * Single-direction only - Command View derives reverse relationships.
2831
+ * Agents/workflows declare what they trigger and use.
2832
+ *
2833
+ * @example
2834
+ * {
2835
+ * triggers: { workflows: ['order-fulfillment-workflow'] },
2836
+ * uses: { integrations: ['integration-shopify-prod', 'integration-postgres'] }
2837
+ * }
2838
+ */
2839
+ interface RelationshipDeclaration {
2840
+ /** Resources this resource triggers */
2841
+ triggers?: {
2842
+ /** Agent resourceIds this resource triggers */
2843
+ agents?: string[];
2844
+ /** Workflow resourceIds this resource triggers */
2845
+ workflows?: string[];
2846
+ };
2847
+ /** Integrations this resource uses */
2848
+ uses?: {
2849
+ /** Integration IDs this resource uses */
2850
+ integrations?: string[];
2851
+ };
2852
+ }
2853
+ /**
2854
+ * Resource relationships map
2855
+ * Maps resourceId to its relationship declarations
2856
+ *
2857
+ * @example
2858
+ * {
2859
+ * 'order-processor-agent': {
2860
+ * triggers: { workflows: ['order-fulfillment-workflow'] },
2861
+ * uses: { integrations: ['integration-shopify-prod'] }
2862
+ * }
2863
+ * }
2864
+ */
2865
+ type ResourceRelationships = Record<string, RelationshipDeclaration>;
2866
+ /**
2867
+ * External platform type
2868
+ * Supported third-party automation platforms
2869
+ */
2870
+ type ExternalPlatform = 'n8n' | 'make' | 'zapier' | 'other';
2871
+ /**
2872
+ * External automation resource metadata
2873
+ *
2874
+ * Represents workflows/automations running on third-party platforms
2875
+ * (n8n, Make, Zapier, etc.) for visualization in Command View.
2876
+ *
2877
+ * NOTE: This is metadata ONLY for visualization. No execution logic,
2878
+ * no API integration with external platforms, no status syncing.
2879
+ *
2880
+ * BREAKING CHANGES (2025-11-30):
2881
+ * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
2882
+ * - Field renames: `id` -> `resourceId` (inherited)
2883
+ * - New required field: `version` (inherited) - organizations must add version to all external resources
2884
+ * - New required field: `type: 'external'` (inherited) - resource type discriminator
2885
+ * - REMOVED FIELD: `triggeredBy` - per relationship-consolidation design, all relationships are forward-only declarations
2886
+ *
2887
+ * @example
2888
+ * {
2889
+ * resourceId: 'external-n8n-order-sync',
2890
+ * type: 'external',
2891
+ * version: '1.0.0',
2892
+ * platform: 'n8n',
2893
+ * name: 'Shopify Order Sync',
2894
+ * description: 'Legacy n8n workflow for syncing Shopify orders',
2895
+ * status: 'prod',
2896
+ * platformUrl: 'https://n8n.client.com/workflow/123',
2897
+ * triggers: { workflows: ['order-fulfillment-workflow'] },
2898
+ * uses: { integrations: ['integration-shopify-prod'] }
2899
+ * }
2900
+ */
2901
+ interface ExternalResourceDefinition extends ResourceDefinition {
2902
+ /** Resource type discriminator (narrowed from base union) */
2903
+ type: 'external';
2904
+ /** Platform type */
2905
+ platform: ExternalPlatform;
2906
+ /** Link to external platform (e.g., n8n workflow editor URL) */
2907
+ platformUrl?: string;
2908
+ /** Platform's internal ID/reference */
2909
+ externalId?: string;
2910
+ /** What this external resource triggers (external -> internal) */
2911
+ triggers?: {
2912
+ /** Elevasis workflow resourceIds this external automation triggers */
2913
+ workflows?: string[];
2914
+ /** Elevasis agent resourceIds this external automation triggers */
2915
+ agents?: string[];
2916
+ };
2917
+ /** Integrations this external resource uses (shared credentials) */
2918
+ uses?: {
2919
+ /** Integration IDs this external automation uses */
2920
+ integrations?: string[];
2921
+ };
2922
+ }
2923
+ /**
2924
+ * Human Checkpoint definition - human decision points in automation
2925
+ *
2926
+ * Represents where human judgment is deployed in the automation landscape.
2927
+ * Tasks with matching command_queue_group are routed to this checkpoint.
2928
+ *
2929
+ * BREAKING CHANGES (2025-11-30):
2930
+ * - Now extends ResourceDefinition (inherits: resourceId, name, description, version, type, status, links, category)
2931
+ * - Field renames: `id` -> `resourceId` (inherited)
2932
+ * - description is now REQUIRED (was optional) - organizations must add description to all human checkpoints
2933
+ * - New required field: `version` (inherited) - organizations must add version to all human checkpoints
2934
+ * - New required field: `type: 'human'` (inherited) - resource type discriminator
2935
+ *
2936
+ * @example
2937
+ * {
2938
+ * resourceId: 'sales-approval',
2939
+ * type: 'human',
2940
+ * name: 'Sales Approval Queue',
2941
+ * description: 'High-value order approvals for sales team',
2942
+ * version: '1.0.0',
2943
+ * status: 'prod',
2944
+ * requestedBy: { agents: ['order-processor-agent'] },
2945
+ * routesTo: { agents: ['order-fulfillment-agent'] }
2946
+ * }
2947
+ */
2948
+ interface HumanCheckpointDefinition extends ResourceDefinition {
2949
+ /** Resource type discriminator (narrowed from base union) */
2950
+ type: 'human';
2951
+ /** Resources that create tasks for this checkpoint */
2952
+ requestedBy?: {
2953
+ /** Agent resourceIds that request approval here */
2954
+ agents?: string[];
2955
+ /** Workflow resourceIds that request approval here */
2956
+ workflows?: string[];
2957
+ };
2958
+ /** Resources that receive approved decisions */
2959
+ routesTo?: {
2960
+ /** Agent resourceIds that handle approved tasks */
2961
+ agents?: string[];
2962
+ /** Workflow resourceIds that handle approved tasks */
2963
+ workflows?: string[];
2964
+ };
2965
+ }
2966
2966
 
2967
2967
  declare const ResourceCategorySchema: z.ZodEnum<{
2968
2968
  diagnostic: "diagnostic";
@@ -3089,670 +3089,7 @@ declare const IntegrationResourceEntrySchema = ResourceEntryBaseSchema.extend({
3089
3089
  provider: z.string().trim().min(1).max(100)
3090
3090
  })
3091
3091
 
3092
- declare const OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
3093
- // Collect ALL system entries recursively — top-level systems plus any nested subsystems.
3094
- // Wave 2 canonical OM authors nested subsystems (e.g. sys → subsystems → 'lead-gen' with id
3095
- // 'sys.lead-gen'). Resource systemPath cross-refs must resolve against the full flattened set.
3096
- type SystemWithPath = { path: string; schemaPath: Array<string | number>; system: SystemEntry }
3097
-
3098
- function collectAllSystems(
3099
- systems: Record<string, SystemEntry>,
3100
- prefix = '',
3101
- schemaPath: Array<string | number> = ['systems']
3102
- ): SystemWithPath[] {
3103
- const result: SystemWithPath[] = []
3104
- for (const [key, system] of Object.entries(systems)) {
3105
- const path = prefix ? `${prefix}.${key}` : key
3106
- const currentSchemaPath = [...schemaPath, key]
3107
- result.push({ path, schemaPath: currentSchemaPath, system })
3108
- const childSystems = system.systems ?? system.subsystems
3109
- if (childSystems !== undefined) {
3110
- result.push(
3111
- ...collectAllSystems(childSystems, path, [
3112
- ...currentSchemaPath,
3113
- system.systems !== undefined ? 'systems' : 'subsystems'
3114
- ])
3115
- )
3116
- }
3117
- }
3118
- return result
3119
- }
3120
-
3121
- const allSystems = collectAllSystems(model.systems)
3122
- const systemsById = new Map<string, SystemEntry>()
3123
- for (const { path, system } of allSystems) {
3124
- systemsById.set(path, system)
3125
- systemsById.set(system.id, system)
3126
- }
3127
-
3128
- const systemIdsByEffectivePath = new Map<string, string>()
3129
- allSystems.forEach(({ path, schemaPath, system }) => {
3130
- if (system.parentSystemId !== undefined && !systemsById.has(system.parentSystemId)) {
3131
- addIssue(
3132
- ctx,
3133
- [...schemaPath, 'parentSystemId'],
3134
- `System "${system.id}" references unknown parent "${system.parentSystemId}"`
3135
- )
3136
- }
3137
-
3138
- const hasChildren =
3139
- Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 ||
3140
- allSystems.some(
3141
- (candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes('.')
3142
- )
3143
- const contributesRoutePath = system.ui?.path !== undefined || system.path !== undefined || !hasChildren
3144
- if (contributesRoutePath) {
3145
- const effectivePath = system.ui?.path ?? system.path ?? defaultSystemPathFor(path)
3146
- const existingSystemId = systemIdsByEffectivePath.get(effectivePath)
3147
- if (existingSystemId !== undefined) {
3148
- addIssue(
3149
- ctx,
3150
- [...schemaPath, system.ui?.path !== undefined ? 'ui' : 'path'],
3151
- `System "${path}" effective path "${effectivePath}" duplicates system "${existingSystemId}"`
3152
- )
3153
- } else {
3154
- systemIdsByEffectivePath.set(effectivePath, path)
3155
- }
3156
- }
3157
-
3158
- if (hasChildren && isLifecycleEnabled(system.lifecycle, system.enabled)) {
3159
- const hasEnabledDescendant =
3160
- Object.values(system.systems ?? system.subsystems ?? {}).some((candidate) =>
3161
- isLifecycleEnabled(candidate.lifecycle, candidate.enabled)
3162
- ) ||
3163
- allSystems.some(
3164
- (candidate) =>
3165
- candidate.path.startsWith(`${path}.`) &&
3166
- !candidate.path.slice(path.length + 1).includes('.') &&
3167
- isLifecycleEnabled(candidate.system.lifecycle, candidate.system.enabled)
3168
- )
3169
- if (!hasEnabledDescendant) {
3170
- addIssue(ctx, [...schemaPath, 'lifecycle'], `System "${path}" is active but has no active descendants`)
3171
- }
3172
- }
3173
- })
3174
-
3175
- allSystems.forEach(({ schemaPath, system }) => {
3176
- const visited = new Set<string>()
3177
- let currentParentId = system.parentSystemId
3178
-
3179
- while (currentParentId !== undefined) {
3180
- if (currentParentId === system.id || visited.has(currentParentId)) {
3181
- addIssue(ctx, [...schemaPath, 'parentSystemId'], `System "${system.id}" has a parent cycle`)
3182
- return
3183
- }
3184
-
3185
- visited.add(currentParentId)
3186
- currentParentId = systemsById.get(currentParentId)?.parentSystemId
3187
- }
3188
- })
3189
-
3190
- type CollectedSidebarSurface = {
3191
- id: string
3192
- node: Extract<SidebarNode, { type: 'surface' }>
3193
- path: Array<string | number>
3194
- }
3195
-
3196
- function normalizeRoutePath(path: string): string {
3197
- return path.length > 1 ? path.replace(/\/+$/, '') : path
3198
- }
3199
-
3200
- const sidebarNodeIds = new Map<string, Array<string | number>>()
3201
- const sidebarSurfacePaths = new Map<string, string>()
3202
- const sidebarSurfaces: CollectedSidebarSurface[] = []
3203
-
3204
- function collectSidebarNodes(nodes: Record<string, SidebarNode>, schemaPath: Array<string | number>): void {
3205
- Object.entries(nodes).forEach(([nodeId, node]) => {
3206
- const nodePath = [...schemaPath, nodeId]
3207
- const existingNodePath = sidebarNodeIds.get(nodeId)
3208
- if (existingNodePath !== undefined) {
3209
- addIssue(ctx, nodePath, `Sidebar node id "${nodeId}" duplicates another sidebar node`)
3210
- } else {
3211
- sidebarNodeIds.set(nodeId, nodePath)
3212
- }
3213
-
3214
- if (node.type === 'group') {
3215
- collectSidebarNodes(node.children, [...nodePath, 'children'])
3216
- return
3217
- }
3218
-
3219
- sidebarSurfaces.push({ id: nodeId, node, path: nodePath })
3220
- const normalizedPath = normalizeRoutePath(node.path)
3221
- const existingSurfaceId = sidebarSurfacePaths.get(normalizedPath)
3222
- if (existingSurfaceId !== undefined) {
3223
- addIssue(
3224
- ctx,
3225
- [...nodePath, 'path'],
3226
- `Sidebar surface path "${node.path}" duplicates surface "${existingSurfaceId}"`
3227
- )
3228
- } else {
3229
- sidebarSurfacePaths.set(normalizedPath, nodeId)
3230
- }
3231
-
3232
- node.targets?.systems?.forEach((systemId, systemIndex) => {
3233
- if (!systemsById.has(systemId)) {
3234
- addIssue(
3235
- ctx,
3236
- [...nodePath, 'targets', 'systems', systemIndex],
3237
- `Sidebar surface "${nodeId}" references unknown system "${systemId}"`
3238
- )
3239
- }
3240
- })
3241
- })
3242
- }
3243
-
3244
- collectSidebarNodes(model.navigation.sidebar.primary, ['navigation', 'sidebar', 'primary'])
3245
- collectSidebarNodes(model.navigation.sidebar.bottom, ['navigation', 'sidebar', 'bottom'])
3246
-
3247
- // Offerings -> CustomerSegment cross-ref: targetSegmentIds must resolve
3248
- const segmentsById = new Map(Object.entries(model.customers))
3249
- Object.values(model.offerings).forEach((product) => {
3250
- product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
3251
- if (!segmentsById.has(segmentId)) {
3252
- addIssue(
3253
- ctx,
3254
- ['offerings', product.id, 'targetSegmentIds', segmentIndex],
3255
- `Product "${product.id}" references unknown customer segment "${segmentId}"`
3256
- )
3257
- }
3258
- })
3259
-
3260
- // Offerings -> System cross-ref: deliveryFeatureId must resolve (when present)
3261
- if (product.deliveryFeatureId !== undefined && !systemsById.has(product.deliveryFeatureId)) {
3262
- addIssue(
3263
- ctx,
3264
- ['offerings', product.id, 'deliveryFeatureId'],
3265
- `Product "${product.id}" references unknown delivery system "${product.deliveryFeatureId}"`
3266
- )
3267
- }
3268
- })
3269
-
3270
- // Goals -> period-range validation: periodEnd must be strictly after periodStart
3271
- Object.values(model.goals).forEach((objective) => {
3272
- if (objective.periodEnd <= objective.periodStart) {
3273
- addIssue(
3274
- ctx,
3275
- ['goals', objective.id, 'periodEnd'],
3276
- `Goal "${objective.id}" has periodEnd "${objective.periodEnd}" which must be strictly after periodStart "${objective.periodStart}"`
3277
- )
3278
- }
3279
- })
3280
-
3281
- const goalsById = new Map(Object.entries(model.goals))
3282
- // Phase 4: knowledge is now a flat Record<id, OrgKnowledgeNode> — no .nodes array
3283
- const knowledgeById = new Map(Object.entries(model.knowledge))
3284
- const actionsById = new Map(Object.entries(model.actions))
3285
- const entitiesById = new Map(Object.entries(model.entities))
3286
- const policiesById = new Map(Object.entries(model.policies))
3287
-
3288
- sidebarSurfaces.forEach(({ id, node, path }) => {
3289
- node.targets?.entities?.forEach((entityId, entityIndex) => {
3290
- if (!entitiesById.has(entityId)) {
3291
- addIssue(
3292
- ctx,
3293
- [...path, 'targets', 'entities', entityIndex],
3294
- `Sidebar surface "${id}" references unknown entity "${entityId}"`
3295
- )
3296
- }
3297
- })
3298
-
3299
- node.targets?.actions?.forEach((actionId, actionIndex) => {
3300
- if (!actionsById.has(actionId)) {
3301
- addIssue(
3302
- ctx,
3303
- [...path, 'targets', 'actions', actionIndex],
3304
- `Sidebar surface "${id}" references unknown action "${actionId}"`
3305
- )
3306
- }
3307
- })
3308
- })
3309
-
3310
- Object.values(model.entities).forEach((entity) => {
3311
- if (!systemsById.has(entity.ownedBySystemId)) {
3312
- addIssue(
3313
- ctx,
3314
- ['entities', entity.id, 'ownedBySystemId'],
3315
- `Entity "${entity.id}" references unknown ownedBySystemId "${entity.ownedBySystemId}"`
3316
- )
3317
- }
3318
-
3319
- entity.links?.forEach((link, linkIndex) => {
3320
- if (!entitiesById.has(link.toEntity)) {
3321
- addIssue(
3322
- ctx,
3323
- ['entities', entity.id, 'links', linkIndex, 'toEntity'],
3324
- `Entity "${entity.id}" links to unknown entity "${link.toEntity}"`
3325
- )
3326
- }
3327
- })
3328
- })
3329
-
3330
- // Roles -> reportsToId cross-ref: each reportsToId must resolve to another role in the same collection
3331
- const rolesById = new Map(Object.entries(model.roles))
3332
- Object.values(model.roles).forEach((role) => {
3333
- if (role.reportsToId !== undefined && !rolesById.has(role.reportsToId)) {
3334
- addIssue(
3335
- ctx,
3336
- ['roles', role.id, 'reportsToId'],
3337
- `Role "${role.id}" references unknown reportsToId "${role.reportsToId}"`
3338
- )
3339
- }
3340
- })
3341
-
3342
- Object.values(model.roles).forEach((role) => {
3343
- const visited = new Set<string>()
3344
- let currentReportsToId = role.reportsToId
3345
-
3346
- while (currentReportsToId !== undefined) {
3347
- if (currentReportsToId === role.id || visited.has(currentReportsToId)) {
3348
- addIssue(ctx, ['roles', role.id, 'reportsToId'], `Role "${role.id}" has a reportsToId cycle`)
3349
- return
3350
- }
3351
-
3352
- visited.add(currentReportsToId)
3353
- currentReportsToId = rolesById.get(currentReportsToId)?.reportsToId
3354
- }
3355
- })
3356
-
3357
- Object.values(model.roles).forEach((role) => {
3358
- role.responsibleFor?.forEach((systemId, systemIndex) => {
3359
- if (!systemsById.has(systemId)) {
3360
- addIssue(
3361
- ctx,
3362
- ['roles', role.id, 'responsibleFor', systemIndex],
3363
- `Role "${role.id}" references unknown responsibleFor system "${systemId}"`
3364
- )
3365
- }
3366
- })
3367
- })
3368
-
3369
- allSystems.forEach(({ schemaPath, system }) => {
3370
- if (system.responsibleRoleId !== undefined && !rolesById.has(system.responsibleRoleId)) {
3371
- addIssue(
3372
- ctx,
3373
- [...schemaPath, 'responsibleRoleId'],
3374
- `System "${system.id}" references unknown responsibleRoleId "${system.responsibleRoleId}"`
3375
- )
3376
- }
3377
-
3378
- system.governedByKnowledge?.forEach((nodeId, nodeIndex) => {
3379
- if (!knowledgeById.has(nodeId)) {
3380
- addIssue(
3381
- ctx,
3382
- [...schemaPath, 'governedByKnowledge', nodeIndex],
3383
- `System "${system.id}" references unknown knowledge node "${nodeId}"`
3384
- )
3385
- }
3386
- })
3387
-
3388
- system.drivesGoals?.forEach((goalId, goalIndex) => {
3389
- if (!goalsById.has(goalId)) {
3390
- addIssue(
3391
- ctx,
3392
- [...schemaPath, 'drivesGoals', goalIndex],
3393
- `System "${system.id}" references unknown goal "${goalId}"`
3394
- )
3395
- }
3396
- })
3397
-
3398
- system.actions?.forEach((actionRef, actionIndex) => {
3399
- if (!actionsById.has(actionRef.actionId)) {
3400
- addIssue(
3401
- ctx,
3402
- [...schemaPath, 'actions', actionIndex, 'actionId'],
3403
- `System "${system.id}" references unknown action "${actionRef.actionId}"`
3404
- )
3405
- }
3406
- })
3407
-
3408
- system.policies?.forEach((policyId, policyIndex) => {
3409
- if (!policiesById.has(policyId)) {
3410
- addIssue(
3411
- ctx,
3412
- [...schemaPath, 'policies', policyIndex],
3413
- `System "${system.id}" references unknown policy "${policyId}"`
3414
- )
3415
- }
3416
- })
3417
- })
3418
-
3419
- Object.values(model.actions).forEach((action) => {
3420
- action.affects?.forEach((entityId, entityIndex) => {
3421
- if (!entitiesById.has(entityId)) {
3422
- addIssue(
3423
- ctx,
3424
- ['actions', action.id, 'affects', entityIndex],
3425
- `Action "${action.id}" affects unknown entity "${entityId}"`
3426
- )
3427
- }
3428
- })
3429
- })
3430
-
3431
- // Phase 4: sales / prospecting / projects compound-domain entity cross-ref checks removed.
3432
- // Those entity bindings now live in System.ontology catalog scopes.
3433
-
3434
- const resourcesById = new Map(Object.entries(model.resources))
3435
- sidebarSurfaces.forEach(({ id, node, path }) => {
3436
- node.targets?.resources?.forEach((resourceId, resourceIndex) => {
3437
- if (!resourcesById.has(resourceId)) {
3438
- addIssue(
3439
- ctx,
3440
- [...path, 'targets', 'resources', resourceIndex],
3441
- `Sidebar surface "${id}" references unknown resource "${resourceId}"`
3442
- )
3443
- }
3444
- })
3445
- })
3446
- const actionIds = new Set(Object.keys(model.actions))
3447
- const offeringsById = new Map(Object.entries(model.offerings))
3448
- const ontologyCompilation = compileOrganizationOntology(model)
3449
- const stageIds = new Set<string>()
3450
- for (const catalog of Object.values(ontologyCompilation.ontology.catalogTypes)) {
3451
- if (catalog.kind !== 'stage') continue
3452
- for (const stageId of Object.keys(catalog.entries ?? {})) {
3453
- stageIds.add(stageId)
3454
- }
3455
- }
3456
- const ontologyIndexByKind = {
3457
- object: ontologyCompilation.ontology.objectTypes,
3458
- link: ontologyCompilation.ontology.linkTypes,
3459
- action: ontologyCompilation.ontology.actionTypes,
3460
- catalog: ontologyCompilation.ontology.catalogTypes,
3461
- event: ontologyCompilation.ontology.eventTypes,
3462
- interface: ontologyCompilation.ontology.interfaceTypes,
3463
- 'value-type': ontologyCompilation.ontology.valueTypes,
3464
- property: ontologyCompilation.ontology.sharedProperties,
3465
- group: ontologyCompilation.ontology.groups,
3466
- surface: ontologyCompilation.ontology.surfaces
3467
- } satisfies Record<OntologyKind, Record<string, unknown>>
3468
- const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)))
3469
-
3470
- function topologyTargetExists(ref: OmTopologyNodeRef): boolean {
3471
- if (ref.kind === 'system') return systemsById.has(ref.id)
3472
- if (ref.kind === 'resource') return resourcesById.has(ref.id)
3473
- if (ref.kind === 'ontology') return ontologyIds.has(ref.id)
3474
- if (ref.kind === 'policy') return policiesById.has(ref.id)
3475
- if (ref.kind === 'role') return rolesById.has(ref.id)
3476
-
3477
- // Trigger, human checkpoint, and external resource refs are projected
3478
- // topology nodes during the bridge period; their owning runtime indexes are
3479
- // validated by deployment projection in later waves.
3480
- return true
3481
- }
3482
-
3483
- Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
3484
- ;(['from', 'to'] as const).forEach((side) => {
3485
- const ref = relationship[side]
3486
- if (topologyTargetExists(ref)) return
3487
-
3488
- addIssue(
3489
- ctx,
3490
- ['topology', 'relationships', relationshipId, side],
3491
- `Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
3492
- )
3493
- })
3494
- })
3495
-
3496
- const ontologyReferenceKeyKinds = {
3497
- valueType: 'value-type',
3498
- catalogType: 'catalog',
3499
- objectType: 'object',
3500
- eventType: 'event',
3501
- actionType: 'action',
3502
- linkType: 'link',
3503
- interfaceType: 'interface',
3504
- propertyType: 'property',
3505
- groupType: 'group',
3506
- surfaceType: 'surface',
3507
- stepCatalog: 'catalog'
3508
- } satisfies Record<string, OntologyKind>
3509
-
3510
- function validateKnownOntologyReferences(
3511
- ownerId: string,
3512
- value: unknown,
3513
- path: Array<string | number>,
3514
- seen = new WeakSet<object>()
3515
- ): void {
3516
- if (Array.isArray(value)) {
3517
- value.forEach((entry, index) => validateKnownOntologyReferences(ownerId, entry, [...path, index], seen))
3518
- return
3519
- }
3520
-
3521
- if (!isRecord(value)) return
3522
- if (seen.has(value)) return
3523
- seen.add(value)
3524
-
3525
- Object.entries(value).forEach(([key, entry]) => {
3526
- const expectedKind = ontologyReferenceKeyKinds[key as keyof typeof ontologyReferenceKeyKinds]
3527
- if (expectedKind !== undefined) {
3528
- if (typeof entry !== 'string') {
3529
- addIssue(ctx, [...path, key], `Ontology record "${ownerId}" ${key} must be an ontology ID string`)
3530
- } else if (ontologyIndexByKind[expectedKind][entry] === undefined) {
3531
- addIssue(
3532
- ctx,
3533
- [...path, key],
3534
- `Ontology record "${ownerId}" ${key} references unknown ${expectedKind} ontology ID "${entry}"`
3535
- )
3536
- }
3537
- }
3538
-
3539
- validateKnownOntologyReferences(ownerId, entry, [...path, key], seen)
3540
- })
3541
- }
3542
-
3543
- for (const { id, record } of listResolvedOntologyRecords(ontologyCompilation.ontology)) {
3544
- validateKnownOntologyReferences(id, record, record.origin.path)
3545
- }
3546
-
3547
- Object.values(model.policies).forEach((policy) => {
3548
- policy.appliesTo.systemIds.forEach((systemId, systemIndex) => {
3549
- if (!systemsById.has(systemId)) {
3550
- addIssue(
3551
- ctx,
3552
- ['policies', policy.id, 'appliesTo', 'systemIds', systemIndex],
3553
- `Policy "${policy.id}" applies to unknown system "${systemId}"`
3554
- )
3555
- }
3556
- })
3557
-
3558
- policy.appliesTo.actionIds.forEach((actionId, actionIndex) => {
3559
- if (!actionsById.has(actionId)) {
3560
- addIssue(
3561
- ctx,
3562
- ['policies', policy.id, 'appliesTo', 'actionIds', actionIndex],
3563
- `Policy "${policy.id}" applies to unknown action "${actionId}"`
3564
- )
3565
- }
3566
- })
3567
-
3568
- policy.actions.forEach((action, actionIndex) => {
3569
- if (action.kind === 'invoke-action' && !actionsById.has(action.actionId)) {
3570
- addIssue(
3571
- ctx,
3572
- ['policies', policy.id, 'actions', actionIndex, 'actionId'],
3573
- `Policy "${policy.id}" invokes unknown action "${action.actionId}"`
3574
- )
3575
- }
3576
- if (
3577
- (action.kind === 'notify-role' || action.kind === 'require-approval') &&
3578
- action.roleId !== undefined &&
3579
- !rolesById.has(action.roleId)
3580
- ) {
3581
- addIssue(
3582
- ctx,
3583
- ['policies', policy.id, 'actions', actionIndex, 'roleId'],
3584
- `Policy "${policy.id}" references unknown role "${action.roleId}"`
3585
- )
3586
- }
3587
- })
3588
-
3589
- if (policy.trigger.kind === 'action-invocation' && !actionsById.has(policy.trigger.actionId)) {
3590
- addIssue(
3591
- ctx,
3592
- ['policies', policy.id, 'trigger', 'actionId'],
3593
- `Policy "${policy.id}" references unknown trigger action "${policy.trigger.actionId}"`
3594
- )
3595
- }
3596
- })
3597
-
3598
- function knowledgeTargetExists(kind: string, id: string): boolean {
3599
- if (kind === 'system') return systemsById.has(id)
3600
- if (kind === 'resource') return resourcesById.has(id)
3601
- if (kind === 'knowledge') return knowledgeById.has(id)
3602
- if (kind === 'stage') return stageIds.has(id)
3603
- if (kind === 'action') return actionIds.has(id)
3604
- if (kind === 'role') return rolesById.has(id)
3605
- if (kind === 'goal') return goalsById.has(id)
3606
- if (kind === 'customer-segment') return segmentsById.has(id)
3607
- if (kind === 'offering') return offeringsById.has(id)
3608
- if (kind === 'ontology') return ontologyIds.has(id)
3609
- return false
3610
- }
3611
-
3612
- // Phase 4: model.knowledge is now Record<id, OrgKnowledgeNode> — iterate Object.values
3613
- Object.entries(model.knowledge).forEach(([nodeId, node]) => {
3614
- node.links.forEach((link, linkIndex) => {
3615
- if (!knowledgeTargetExists(link.target.kind, link.target.id)) {
3616
- addIssue(
3617
- ctx,
3618
- ['knowledge', nodeId, 'links', linkIndex, 'target'],
3619
- `Knowledge node "${node.id}" references unknown ${link.target.kind} target "${link.target.id}"`
3620
- )
3621
- }
3622
-
3623
- if (!isKnowledgeKindCompatibleWithTarget(node.kind, link.target.kind)) {
3624
- addIssue(
3625
- ctx,
3626
- ['knowledge', nodeId, 'links', linkIndex, 'target', 'kind'],
3627
- `Knowledge node "${node.id}" kind "${node.kind}" cannot govern ${link.target.kind} targets`
3628
- )
3629
- }
3630
-
3631
- // `governedByKnowledge` is validated one-way on target nodes above. Knowledge
3632
- // links may be authored first and remain valid as forward references.
3633
- })
3634
- })
3635
-
3636
- Object.values(model.resources).forEach((resource) => {
3637
- if (!systemsById.has(resource.systemPath)) {
3638
- addIssue(
3639
- ctx,
3640
- ['resources', resource.id, 'systemPath'],
3641
- `Resource "${resource.id}" references unknown system path "${resource.systemPath}"`
3642
- )
3643
- }
3644
-
3645
- if (resource.ownerRoleId !== undefined && !rolesById.has(resource.ownerRoleId)) {
3646
- addIssue(
3647
- ctx,
3648
- ['resources', resource.id, 'ownerRoleId'],
3649
- `Resource "${resource.id}" references unknown ownerRoleId "${resource.ownerRoleId}"`
3650
- )
3651
- }
3652
-
3653
- if (resource.kind === 'agent' && resource.actsAsRoleId !== undefined && !rolesById.has(resource.actsAsRoleId)) {
3654
- addIssue(
3655
- ctx,
3656
- ['resources', resource.id, 'actsAsRoleId'],
3657
- `Agent resource "${resource.id}" references unknown actsAsRoleId "${resource.actsAsRoleId}"`
3658
- )
3659
- }
3660
- })
3661
-
3662
- function validateResourceOntologyBinding(
3663
- resourceId: string,
3664
- bindingKey: 'actions' | 'primaryAction' | 'reads' | 'writes' | 'usesCatalogs' | 'emits',
3665
- expectedKind: OntologyKind,
3666
- ids: string[] | string | undefined
3667
- ): void {
3668
- const ontologyIds = ids === undefined ? [] : Array.isArray(ids) ? ids : [ids]
3669
-
3670
- ontologyIds.forEach((ontologyId, ontologyIndex) => {
3671
- if (ontologyIndexByKind[expectedKind][ontologyId] === undefined) {
3672
- addIssue(
3673
- ctx,
3674
- ['resources', resourceId, 'ontology', bindingKey, ...(Array.isArray(ids) ? [ontologyIndex] : [])],
3675
- `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
3676
- )
3677
- }
3678
- })
3679
- }
3680
-
3681
- Object.values(model.resources).forEach((resource) => {
3682
- const binding = resource.ontology
3683
- if (binding === undefined) return
3684
-
3685
- validateResourceOntologyBinding(resource.id, 'actions', 'action', binding.actions)
3686
- validateResourceOntologyBinding(resource.id, 'primaryAction', 'action', binding.primaryAction)
3687
- validateResourceOntologyBinding(resource.id, 'reads', 'object', binding.reads)
3688
- validateResourceOntologyBinding(resource.id, 'writes', 'object', binding.writes)
3689
- validateResourceOntologyBinding(resource.id, 'usesCatalogs', 'catalog', binding.usesCatalogs)
3690
- validateResourceOntologyBinding(resource.id, 'emits', 'event', binding.emits)
3691
-
3692
- // Tier-1: validate contract ref SHAPE only — no module resolution (browser-safe).
3693
- // Tier-2 intra-package resolution runs in om:verify (packages/cli/src/knowledge/verify.ts).
3694
- if (binding.contract !== undefined) {
3695
- const contractEntries = [
3696
- ['input', binding.contract.input],
3697
- ['output', binding.contract.output]
3698
- ] as const
3699
- for (const [side, ref] of contractEntries) {
3700
- if (ref === undefined) continue
3701
- const result = ContractRefSchema.safeParse(ref)
3702
- if (!result.success) {
3703
- addIssue(
3704
- ctx,
3705
- ['resources', resource.id, 'ontology', 'contract', side],
3706
- `Resource "${resource.id}" contract.${side} "${ref}" is not a valid ContractRef (expected "package/subpath#ExportName")`
3707
- )
3708
- }
3709
- }
3710
- }
3711
- })
3712
-
3713
- Object.values(model.roles).forEach((role) => {
3714
- if (role.heldBy === undefined) return
3715
-
3716
- asRoleHolderArray(role.heldBy).forEach((holder, holderIndex) => {
3717
- if (holder.kind !== 'agent') return
3718
-
3719
- const resource = resourcesById.get(holder.agentId)
3720
- if (resource === undefined) {
3721
- addIssue(
3722
- ctx,
3723
- ['roles', role.id, 'heldBy', Array.isArray(role.heldBy) ? holderIndex : 'agentId'],
3724
- `Role "${role.id}" references unknown agent holder resource "${holder.agentId}"`
3725
- )
3726
- return
3727
- }
3728
-
3729
- if (resource.kind !== 'agent') {
3730
- addIssue(
3731
- ctx,
3732
- ['roles', role.id, 'heldBy', Array.isArray(role.heldBy) ? holderIndex : 'agentId'],
3733
- `Role "${role.id}" agent holder "${holder.agentId}" must reference an agent resource`
3734
- )
3735
- }
3736
- })
3737
- })
3738
-
3739
- // Phase 4: model.knowledge is now Record<id, OrgKnowledgeNode>
3740
- Object.entries(model.knowledge).forEach(([nodeId, node]) => {
3741
- node.ownerIds.forEach((roleId, ownerIndex) => {
3742
- if (!rolesById.has(roleId)) {
3743
- addIssue(
3744
- ctx,
3745
- ['knowledge', nodeId, 'ownerIds', ownerIndex],
3746
- `Knowledge node "${node.id}" references unknown owner role "${roleId}"`
3747
- )
3748
- }
3749
- })
3750
- })
3751
-
3752
- for (const diagnostic of ontologyCompilation.diagnostics) {
3753
- addIssue(ctx, diagnostic.path, diagnostic.message)
3754
- }
3755
- })
3092
+ declare const OrganizationModelSchema = OrganizationModelSchemaBase.superRefine(refineOrganizationModel)
3756
3093
 
3757
3094
  type OrganizationModel = z.infer<typeof OrganizationModelSchema>
3758
3095
  type OrganizationModelResourceOntologyBinding = z.infer<typeof ResourceOntologyBindingSchema>