@timeax/digital-service-engine 0.0.5 → 0.0.7

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.
@@ -1,6 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { ReactNode } from 'react';
3
3
  import * as react_jsx_runtime from 'react/jsx-runtime';
4
+ import { Node, Edge } from '@xyflow/react';
4
5
 
5
6
  type TimeRangeEstimate = {
6
7
  min_seconds?: number;
@@ -58,7 +59,7 @@ type NodeRef$1 = {
58
59
  };
59
60
  type NodeMap = Map<string, NodeRef$1>;
60
61
 
61
- type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context";
62
+ type ValidationCode = "root_missing" | "cycle_in_tags" | "bad_bind_reference" | "duplicate_id" | "duplicate_tag_label" | "duplicate_field_name" | "label_missing" | "duplicate_visible_label" | "bad_option_key" | "option_include_exclude_conflict" | "service_field_missing_service_id" | "user_input_field_has_service_option" | "rate_mismatch_across_base" | "rate_coherence_violation" | "utility_without_base" | "unsupported_constraint" | "constraint_contradiction" | "custom_component_missing" | "policy_violation" | "field_unbound" | "constraint_overridden" | "unsupported_constraint_option" | "custom_component_unresolvable" | "quantity_multiple_markers" | "utility_with_service_id" | "utility_missing_rate" | "utility_invalid_mode" | "fallback_bad_node" | "fallback_unknown_service" | "fallback_cycle" | "fallback_no_primary" | "fallback_rate_violation" | "fallback_constraint_mismatch" | "fallback_no_tag_context" | "field_validation_invalid_rule" | "field_validation_invalid_op" | "field_validation_eval_missing_code" | "field_validation_between_missing_bounds" | "field_validation_match_missing_pattern";
62
63
  type ValidationError = {
63
64
  code: ValidationCode;
64
65
  message: string;
@@ -114,7 +115,10 @@ type ValidatorOptions = {
114
115
  fallbackSettings?: FallbackSettings;
115
116
  };
116
117
  type RatePolicy = {
118
+ kind: "eq_primary";
119
+ } | {
117
120
  kind: "lte_primary";
121
+ pct: number;
118
122
  } | {
119
123
  kind: "within_pct";
120
124
  pct: number;
@@ -125,7 +129,7 @@ type RatePolicy = {
125
129
  type FallbackSettings = {
126
130
  /** Require fallbacks to satisfy tag constraints (dripfeed/refill/cancel) when a tag context is known. Default: true */
127
131
  requireConstraintFit?: boolean;
128
- /** Rate rule policy. Default: { kind: 'lte_primary' } i.e. candidate.rate <= primary.rate */
132
+ /** Rate rule policy. Default: { kind: 'lte_primary', pct: 5 }. */
129
133
  ratePolicy?: RatePolicy;
130
134
  /** When multiple candidates remain, choose first (priority) or cheapest. Default: 'priority' */
131
135
  selectionStrategy?: "priority" | "cheapest";
@@ -133,7 +137,6 @@ type FallbackSettings = {
133
137
  mode?: "strict" | "dev";
134
138
  };
135
139
 
136
- type ServiceIdRef = number | string;
137
140
  type NodeIdRef = string;
138
141
  type ServiceFallback = {
139
142
  /** Node-scoped fallbacks: prefer these when that node’s primary service fails */
@@ -142,6 +145,7 @@ type ServiceFallback = {
142
145
  global?: Record<ServiceIdRef, ServiceIdRef[]>;
143
146
  };
144
147
 
148
+ type ServiceIdRef = IdType;
145
149
  type PricingRole = "base" | "utility";
146
150
  type FieldType = "custom" | (string & {});
147
151
  /** ── Marker types (live inside meta; non-breaking) ───────────────────── */
@@ -177,11 +181,25 @@ interface BaseFieldUI {
177
181
  /** Host-defined prop names → runtime default values (untyped base) */
178
182
  defaults?: Record<string, unknown>;
179
183
  }
184
+ type FieldValidationValueBy = "value" | "length" | "eval";
185
+ type FieldValidationOp = "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "between" | "in" | "nin" | "truthy" | "falsy" | "match";
186
+ type FieldValidationRule = {
187
+ valueBy?: FieldValidationValueBy;
188
+ op: FieldValidationOp;
189
+ value?: unknown;
190
+ min?: number;
191
+ max?: number;
192
+ values?: unknown[];
193
+ pattern?: string;
194
+ flags?: string;
195
+ code?: string;
196
+ message?: string;
197
+ };
180
198
  type FieldOption = {
181
199
  id: string;
182
200
  label: string;
183
201
  value?: string | number;
184
- service_id?: number;
202
+ service_id?: ServiceIdRef;
185
203
  pricing_role?: PricingRole;
186
204
  meta?: Record<string, unknown> & UtilityMark & WithQuantityDefault;
187
205
  };
@@ -194,6 +212,7 @@ type Field = BaseFieldUI & {
194
212
  description?: string;
195
213
  component?: string;
196
214
  pricing_role?: PricingRole;
215
+ validation?: FieldValidationRule[];
197
216
  meta?: Record<string, unknown> & QuantityMark & UtilityMark & {
198
217
  multi?: boolean;
199
218
  };
@@ -202,14 +221,14 @@ type Field = BaseFieldUI & {
202
221
  service_id?: undefined;
203
222
  } | ({
204
223
  button: true;
205
- service_id?: number;
224
+ service_id?: ServiceIdRef;
206
225
  } & WithQuantityDefault));
207
226
  type ConstraintKey = string;
208
227
  type Tag = {
209
228
  id: string;
210
229
  label: string;
211
230
  bind_id?: string;
212
- service_id?: number;
231
+ service_id?: ServiceIdRef;
213
232
  includes?: string[];
214
233
  excludes?: string[];
215
234
  meta?: Record<string, unknown> & WithQuantityDefault;
@@ -330,140 +349,9 @@ type CommentThread = {
330
349
  _sync?: "pending" | "synced" | "error";
331
350
  };
332
351
 
333
- type Viewport = {
334
- x: number;
335
- y: number;
336
- zoom: number;
337
- };
338
- type NodePos = {
339
- x: number;
340
- y: number;
341
- };
342
- type NodePositions = Record<string, NodePos>;
343
- type DraftWire = {
344
- from: string;
345
- kind: EdgeKind;
346
- };
347
- type CanvasState = {
348
- graph: GraphSnapshot;
349
- positions: NodePositions;
350
- selection: Set<string>;
351
- highlighted: Set<string>;
352
- hoverId?: string;
353
- viewport: Viewport;
354
- draftWire?: DraftWire;
355
- version: number;
356
- };
357
- type CanvasEvents = {
358
- "graph:update": GraphSnapshot;
359
- "state:change": CanvasState;
360
- "selection:change": {
361
- ids: string[];
362
- };
363
- "viewport:change": Viewport;
364
- "hover:change": {
365
- id?: string;
366
- };
367
- "wire:preview": {
368
- from: string;
369
- to?: string;
370
- kind: EdgeKind;
371
- };
372
- "wire:commit": {
373
- from: string;
374
- to: string;
375
- kind: EdgeKind;
376
- };
377
- "wire:cancel": {
378
- from: string;
379
- };
380
- error: {
381
- message: string;
382
- code?: string;
383
- meta?: any;
384
- };
385
- "comment:thread:create": {
386
- thread: CommentThread;
387
- };
388
- "comment:thread:update": {
389
- thread: CommentThread;
390
- };
391
- "comment:thread:delete": {
392
- threadId: string;
393
- };
394
- "comment:message:create": {
395
- threadId: string;
396
- message: CommentMessage;
397
- };
398
- "comment:resolve": {
399
- thread: CommentThread;
400
- resolved: boolean;
401
- };
402
- "comment:move": {
403
- thread: CommentThread;
404
- };
405
- "comment:select": {
406
- threadId?: string;
407
- };
408
- "edge:change": EdgeKind;
409
- "comment:sync": {
410
- op: "create_thread" | "add_message" | "edit_message" | "delete_message" | "move_thread" | "resolve_thread" | "delete_thread";
411
- threadId: string;
412
- messageId?: string;
413
- status: "scheduled" | "retrying" | "succeeded" | "failed" | "cancelled";
414
- attempt: number;
415
- nextDelayMs?: number;
416
- error?: any;
417
- };
418
- };
419
- type CanvasOptions = {
420
- initialViewport?: Partial<Viewport>;
421
- autoEmitState?: boolean;
422
- };
423
-
424
- type CommentNode = {
425
- id: string;
426
- text: string;
427
- status: "open" | "resolved";
428
- anchor?: {
429
- kind: "tag" | "field" | "option";
430
- id: string;
431
- };
432
- replies?: Array<{
433
- id: string;
434
- text: string;
435
- created_at: string;
436
- author?: string;
437
- }>;
438
- xy?: {
439
- x: number;
440
- y: number;
441
- };
442
- meta?: Record<string, unknown>;
443
- };
444
- type EdgeRoute = {
445
- id: string;
446
- points: Array<{
447
- x: number;
448
- y: number;
449
- }>;
450
- };
451
- type LayoutState = {
452
- canvas: CanvasState;
453
- edges?: EdgeRoute[];
454
- };
455
- type EditorSnapshot = {
456
- props: ServiceProps;
457
- layout?: LayoutState;
458
- comments?: CommentNode[];
459
- meta?: Record<string, unknown>;
460
- };
461
-
462
352
  /** Options you can set on the builder (used for validation/visibility) */
463
353
  type BuilderOptions = Omit<ValidatorOptions, "serviceMap"> & {
464
354
  serviceMap?: DgpServiceMap;
465
- /** max history entries for undo/redo */
466
- historyLimit?: number;
467
355
  /**
468
356
  * Field ids whose options should be shown as nodes in the graph.
469
357
  * If a field id is NOT in this set, its options are not materialized as nodes:
@@ -488,9 +376,6 @@ interface Builder {
488
376
  visibleFields(tagId: string, selectedOptionKeys?: string[]): string[];
489
377
  /** Update builder options (validator context etc.) */
490
378
  setOptions(patch: Partial<BuilderOptions>): void;
491
- /** History */
492
- undo(): boolean;
493
- redo(): boolean;
494
379
  /** Access the current props (already normalised) */
495
380
  getProps(): ServiceProps;
496
381
  /** Service map for validation/rules */
@@ -582,6 +467,27 @@ interface NodeIndex {
582
467
  getOption(id: string): OptionNode | undefined;
583
468
  }
584
469
 
470
+ type PolicyDiagnostic = {
471
+ ruleIndex: number;
472
+ ruleId?: string;
473
+ severity: "error" | "warning";
474
+ message: string;
475
+ path?: string;
476
+ };
477
+
478
+ type ServiceCheck = {
479
+ id: ServiceIdRef;
480
+ ok: boolean;
481
+ fitsConstraints: boolean;
482
+ passesRate: boolean;
483
+ passesPolicies: boolean;
484
+ policyErrors?: string[];
485
+ policyWarnings?: string[];
486
+ reasons: Array<"constraint_mismatch" | "rate_policy" | "policy_error" | "missing_capability">;
487
+ cap?: DgpServiceCapability;
488
+ rate?: number;
489
+ };
490
+
585
491
  type Env = "client" | "workspace";
586
492
  type VisibleGroup = {
587
493
  tagId?: string;
@@ -664,6 +570,92 @@ declare class Selection {
664
570
  private findOptionById;
665
571
  }
666
572
 
573
+ type CatalogId = string;
574
+ type CatalogServiceId = string | number;
575
+ type CatalogSmartRule = {
576
+ type: "service-field";
577
+ field: string;
578
+ op: "eq" | "neq" | "in" | "contains" | "startsWith" | "endsWith" | "gt" | "gte" | "lt" | "lte" | "between" | "exists";
579
+ value?: unknown;
580
+ min?: number;
581
+ max?: number;
582
+ } | {
583
+ type: "policy-family";
584
+ key: string;
585
+ value?: unknown;
586
+ } | {
587
+ type: "compatibility";
588
+ scope: "tag" | "field" | "option" | "visible-group";
589
+ targetId?: string;
590
+ mode: "safe" | "assignable" | "same-family" | "conflicts";
591
+ };
592
+ type CatalogNodeBase = {
593
+ id: CatalogId;
594
+ label: string;
595
+ parentId?: CatalogId;
596
+ description?: string;
597
+ order?: number;
598
+ color?: string;
599
+ icon?: string;
600
+ collapsed?: boolean;
601
+ meta?: Record<string, unknown>;
602
+ };
603
+ type CatalogGroupNode = CatalogNodeBase & {
604
+ kind: "group";
605
+ serviceIds: CatalogServiceId[];
606
+ };
607
+ type CatalogSmartGroupNode = CatalogNodeBase & {
608
+ kind: "smart-group";
609
+ rules: CatalogSmartRule[];
610
+ match: "all" | "any";
611
+ resolvedServiceIds?: CatalogServiceId[];
612
+ resolvedAt?: number;
613
+ };
614
+ type CatalogNode = CatalogGroupNode | CatalogSmartGroupNode;
615
+ type CatalogViewMode = "all" | "grouped" | "smart" | "assigned";
616
+ interface ServiceCatalogState {
617
+ version: 1;
618
+ nodes: CatalogNode[];
619
+ activeNodeId?: CatalogId;
620
+ expandedIds?: CatalogId[];
621
+ pinnedNodeIds?: CatalogId[];
622
+ selectedServiceId?: CatalogServiceId;
623
+ viewMode?: CatalogViewMode;
624
+ meta?: Record<string, unknown>;
625
+ }
626
+
627
+ type EditorEvents = {
628
+ "editor:command": {
629
+ name: string;
630
+ payload?: any;
631
+ };
632
+ "editor:change": {
633
+ props: ServiceProps;
634
+ reason: string;
635
+ command?: string;
636
+ snapshot: EditorSnapshot;
637
+ };
638
+ "editor:undo": {
639
+ stackSize: number;
640
+ index: number;
641
+ };
642
+ "editor:redo": {
643
+ stackSize: number;
644
+ index: number;
645
+ };
646
+ "editor:error": {
647
+ message: string;
648
+ code?: string;
649
+ meta?: any;
650
+ };
651
+ "catalog:change": {
652
+ catalog?: ServiceCatalogState;
653
+ reason: string;
654
+ };
655
+ "catalog:active-change": {
656
+ activeNodeId?: string;
657
+ };
658
+ };
667
659
  type Command = {
668
660
  name: string;
669
661
  do(): void;
@@ -681,12 +673,134 @@ type EditorOptions = {
681
673
  selectionProps?: SelectionOptions;
682
674
  };
683
675
 
684
- type PolicyDiagnostic = {
685
- ruleIndex: number;
686
- ruleId?: string;
687
- severity: "error" | "warning";
688
- message: string;
689
- path?: string;
676
+ type Viewport = {
677
+ x: number;
678
+ y: number;
679
+ zoom: number;
680
+ };
681
+ type NodePos = {
682
+ x: number;
683
+ y: number;
684
+ };
685
+ type NodePositions = Record<string, NodePos>;
686
+ type DraftWire = {
687
+ from: string;
688
+ kind: EdgeKind;
689
+ };
690
+ type CanvasState = {
691
+ graph: GraphSnapshot;
692
+ positions: NodePositions;
693
+ selection: Set<string>;
694
+ highlighted: Set<string>;
695
+ hoverId?: string;
696
+ viewport: Viewport;
697
+ draftWire?: DraftWire;
698
+ version: number;
699
+ };
700
+ type CanvasEvents = {
701
+ "graph:update": GraphSnapshot;
702
+ "state:change": CanvasState;
703
+ "selection:change": {
704
+ ids: string[];
705
+ };
706
+ "viewport:change": Viewport;
707
+ "hover:change": {
708
+ id?: string;
709
+ };
710
+ "wire:preview": {
711
+ from: string;
712
+ to?: string;
713
+ kind: EdgeKind;
714
+ };
715
+ "wire:commit": {
716
+ from: string;
717
+ to: string;
718
+ kind: EdgeKind;
719
+ };
720
+ "wire:cancel": {
721
+ from: string;
722
+ };
723
+ error: {
724
+ message: string;
725
+ code?: string;
726
+ meta?: any;
727
+ };
728
+ "comment:thread:create": {
729
+ thread: CommentThread;
730
+ };
731
+ "comment:thread:update": {
732
+ thread: CommentThread;
733
+ };
734
+ "comment:thread:delete": {
735
+ threadId: string;
736
+ };
737
+ "comment:message:create": {
738
+ threadId: string;
739
+ message: CommentMessage;
740
+ };
741
+ "comment:resolve": {
742
+ thread: CommentThread;
743
+ resolved: boolean;
744
+ };
745
+ "comment:move": {
746
+ thread: CommentThread;
747
+ };
748
+ "comment:select": {
749
+ threadId?: string;
750
+ };
751
+ "edge:change": EdgeKind;
752
+ "comment:sync": {
753
+ op: "create_thread" | "add_message" | "edit_message" | "delete_message" | "move_thread" | "resolve_thread" | "delete_thread";
754
+ threadId: string;
755
+ messageId?: string;
756
+ status: "scheduled" | "retrying" | "succeeded" | "failed" | "cancelled";
757
+ attempt: number;
758
+ nextDelayMs?: number;
759
+ error?: any;
760
+ };
761
+ } & EditorEvents;
762
+ type CanvasOptions = {
763
+ initialViewport?: Partial<Viewport>;
764
+ autoEmitState?: boolean;
765
+ };
766
+
767
+ type CommentNode = {
768
+ id: string;
769
+ text: string;
770
+ status: "open" | "resolved";
771
+ anchor?: {
772
+ kind: "tag" | "field" | "option";
773
+ id: string;
774
+ };
775
+ replies?: Array<{
776
+ id: string;
777
+ text: string;
778
+ created_at: string;
779
+ author?: string;
780
+ }>;
781
+ xy?: {
782
+ x: number;
783
+ y: number;
784
+ };
785
+ meta?: Record<string, unknown>;
786
+ };
787
+ type EdgeRoute = {
788
+ id: string;
789
+ points: Array<{
790
+ x: number;
791
+ y: number;
792
+ }>;
793
+ };
794
+ type LayoutState = {
795
+ canvas: CanvasState;
796
+ edges?: EdgeRoute[];
797
+ };
798
+ type EditorSnapshot = {
799
+ props: ServiceProps;
800
+ layout?: LayoutState;
801
+ comments?: CommentNode[];
802
+ catalog?: ServiceCatalogState;
803
+ meta?: Record<string, unknown>;
690
804
  };
691
805
 
692
806
  interface BackendError {
@@ -1192,7 +1306,7 @@ interface CommentsSliceApi {
1192
1306
  readonly threads: Loadable<readonly CommentThread[]>;
1193
1307
  readonly refreshThreads: (params?: Readonly<{
1194
1308
  branchId?: string;
1195
- }>) => Promise<void>;
1309
+ }>) => Promise<BackendResult<readonly CommentThread[]>>;
1196
1310
  readonly createThread: (input: Readonly<{
1197
1311
  anchor?: CommentAnchor;
1198
1312
  body: string;
@@ -1242,7 +1356,7 @@ type PoliciesSlice = {
1242
1356
  readonly refreshPolicies: (params?: Readonly<{
1243
1357
  since?: number | string;
1244
1358
  branchId?: string;
1245
- }>) => Promise<void>;
1359
+ }>) => Promise<BackendResult<readonly DynamicRule[]>>;
1246
1360
  readonly savePolicies: (rules: readonly DynamicRule[], params?: Readonly<{
1247
1361
  branchId?: string;
1248
1362
  }>) => Result<Readonly<{
@@ -1270,6 +1384,32 @@ type RunErr = {
1270
1384
  errors: BackendError[];
1271
1385
  };
1272
1386
  type RunResult = RunOk | RunErr;
1387
+ type WorkspaceBootSection = "authors" | "permissions" | "branches" | "services" | "participants" | "templates" | "snapshotPointers" | "snapshotBody" | "policies" | "comments";
1388
+ type WorkspaceBootSectionStatus = "idle" | "loading" | "success" | "error";
1389
+ interface WorkspaceBootSectionState {
1390
+ readonly status: WorkspaceBootSectionStatus;
1391
+ readonly error?: BackendError;
1392
+ readonly updatedAt?: number;
1393
+ }
1394
+ interface WorkspaceBootState {
1395
+ readonly sections: Readonly<Record<WorkspaceBootSection, WorkspaceBootSectionState>>;
1396
+ readonly isBooting: boolean;
1397
+ readonly isReady: boolean;
1398
+ readonly hasErrors: boolean;
1399
+ readonly hasPartialFailure: boolean;
1400
+ readonly lastError?: BackendError;
1401
+ readonly errorsBySection: Readonly<Partial<Record<WorkspaceBootSection, BackendError>>>;
1402
+ readonly isSeededView: boolean;
1403
+ readonly isLiveConfirmed: boolean;
1404
+ readonly completedSections: number;
1405
+ readonly succeededSections: number;
1406
+ readonly failedSections: number;
1407
+ readonly totalSections: number;
1408
+ retryAll(opts?: {
1409
+ strict?: boolean;
1410
+ }): Promise<RunResult>;
1411
+ retrySection(section: WorkspaceBootSection): Promise<BackendResult<void>>;
1412
+ }
1273
1413
  interface WorkspaceProviderProps {
1274
1414
  readonly backend: WorkspaceBackend;
1275
1415
  readonly actor: Actor;
@@ -1325,6 +1465,7 @@ interface SnapshotSlice {
1325
1465
  interface WorkspaceAPI {
1326
1466
  readonly info: WorkspaceInfo;
1327
1467
  readonly actor: Actor;
1468
+ readonly boot: WorkspaceBootState;
1328
1469
  readonly authors: Loadable<readonly Author[]>;
1329
1470
  readonly permissions: Loadable<PermissionsMap>;
1330
1471
  readonly branches: BranchesSlice;
@@ -1343,7 +1484,11 @@ interface WorkspaceAPI {
1343
1484
  branches(): Promise<void>;
1344
1485
  services(): Promise<void>;
1345
1486
  /** Current branch-scoped refreshers */
1346
- branchContext(): Promise<void>;
1487
+ branchContext(opts?: Readonly<{
1488
+ branchId?: string;
1489
+ strict?: boolean;
1490
+ includeWorkspaceData?: boolean;
1491
+ }>): Promise<void>;
1347
1492
  templates(params?: Partial<Pick<TemplatesListParams, "branchId" | "since">>): Promise<void>;
1348
1493
  participants(params?: Partial<{
1349
1494
  branchId: string;
@@ -1413,6 +1558,7 @@ interface WorkspaceAPI {
1413
1558
  declare const WorkspaceContext: React.Context<WorkspaceAPI | null>;
1414
1559
  declare function useWorkspace(): WorkspaceAPI;
1415
1560
  declare function useWorkspaceMaybe(): WorkspaceAPI | null;
1561
+ declare function useWorkspaceBoot(): WorkspaceBootState;
1416
1562
 
1417
1563
  declare function WorkspaceProvider(props: WorkspaceProviderProps): React.JSX.Element;
1418
1564
 
@@ -1497,9 +1643,39 @@ type DuplicateOptions = {
1497
1643
  nameStrategy?: (old?: string) => string | undefined;
1498
1644
  optionIdStrategy?: (old: string) => string;
1499
1645
  };
1646
+ type EditorNodeLookup = {
1647
+ kind: "tag";
1648
+ data?: Tag;
1649
+ owners: {
1650
+ parentTagId?: string;
1651
+ };
1652
+ } | {
1653
+ kind: "field";
1654
+ data?: Field;
1655
+ owners: {
1656
+ bindTagIds: string[];
1657
+ };
1658
+ } | {
1659
+ kind: "option";
1660
+ data?: any;
1661
+ owners: {
1662
+ fieldId?: string;
1663
+ };
1664
+ };
1665
+ type QuantityRule = {
1666
+ valueBy: "value" | "length" | "eval";
1667
+ code?: string;
1668
+ multiply?: number;
1669
+ clamp?: {
1670
+ min?: number;
1671
+ max?: number;
1672
+ };
1673
+ fallback?: number;
1674
+ };
1675
+
1500
1676
  declare class Editor {
1501
- private builder;
1502
- private api;
1677
+ private readonly builder;
1678
+ private readonly api;
1503
1679
  private readonly opts;
1504
1680
  private history;
1505
1681
  private index;
@@ -1507,6 +1683,7 @@ declare class Editor {
1507
1683
  private txnLabel?;
1508
1684
  private stagedBefore?;
1509
1685
  private _lastPolicyDiagnostics?;
1686
+ private catalog?;
1510
1687
  constructor(builder: Builder, api: CanvasAPI, opts?: EditorOptions);
1511
1688
  isTagId(id: string): boolean;
1512
1689
  isFieldId(id: string): boolean;
@@ -1518,31 +1695,9 @@ declare class Editor {
1518
1695
  redo(): boolean;
1519
1696
  clearService(id: string): void;
1520
1697
  duplicate(ref: NodeRef, opts?: DuplicateOptions): string;
1521
- /**
1522
- * Update the display label for a node and refresh the graph so node labels stay in sync.
1523
- * Supports: tag ("t:*"), field ("f:*"), option ("o:*").
1524
- * IDs are NOT changed; only the human-readable label.
1525
- */
1526
1698
  reLabel(id: string, nextLabel: string): void;
1527
- /**
1528
- * Assign or change a field's `name`. Only allowed when the field (and its options) have NO service mapping.
1529
- * - If `nextName` is empty/blank → removes the `name`.
1530
- * - Emits an error if the field or any of its options carry a `service_id`.
1531
- * - Emits an error if `nextName` collides with an existing field's name (case-sensitive).
1532
- */
1533
1699
  setFieldName(fieldId: string, nextName: string | null | undefined): void;
1534
1700
  getLastPolicyDiagnostics(): PolicyDiagnostic[] | undefined;
1535
- private duplicateTag;
1536
- private duplicateField;
1537
- private duplicateOption;
1538
- private uniqueId;
1539
- private uniqueOptionId;
1540
- /**
1541
- * Reorder a node:
1542
- * - Tag: among its siblings (same bind_id) inside filters[]
1543
- * - Field: inside order_for_tags[scopeTagId] (you must pass scopeTagId)
1544
- * - Option: use placeOption() instead
1545
- */
1546
1701
  placeNode(id: string, opts: {
1547
1702
  scopeTagId?: string;
1548
1703
  beforeId?: string;
@@ -1557,20 +1712,20 @@ declare class Editor {
1557
1712
  addOption(fieldId: string, input: {
1558
1713
  id?: string;
1559
1714
  label: string;
1560
- service_id?: number;
1715
+ service_id?: ServiceIdRef;
1561
1716
  pricing_role?: "base" | "utility" | "addon";
1562
1717
  [k: string]: any;
1563
1718
  }): string;
1564
1719
  updateOption(optionId: string, patch: Partial<{
1565
1720
  label: string;
1566
- service_id: number;
1721
+ service_id: ServiceIdRef;
1567
1722
  pricing_role: "base" | "utility" | "addon";
1568
1723
  } & Record<string, any>>): void;
1569
1724
  removeOption(optionId: string): void;
1570
1725
  editLabel(id: string, label: string): void;
1571
1726
  editName(fieldId: string, name: string | undefined): void;
1572
1727
  setService(id: string, input: {
1573
- service_id?: number;
1728
+ service_id?: ServiceIdRef;
1574
1729
  pricing_role?: "base" | "utility";
1575
1730
  }): void;
1576
1731
  addTag(partial: Omit<Tag, "id" | "label"> & {
@@ -1579,6 +1734,11 @@ declare class Editor {
1579
1734
  }): void;
1580
1735
  updateTag(id: string, patch: Partial<Tag>): void;
1581
1736
  removeTag(id: string): void;
1737
+ addNotice(input: Omit<ServicePropsNotice, "id"> & {
1738
+ id?: string;
1739
+ }): string;
1740
+ updateNotice(id: string, patch: Partial<ServicePropsNotice>): void;
1741
+ removeNotice(id: string): void;
1582
1742
  addField(partial: Omit<Field, "id" | "label" | "type"> & {
1583
1743
  id?: string;
1584
1744
  label: string;
@@ -1587,45 +1747,76 @@ declare class Editor {
1587
1747
  updateField(id: string, patch: Partial<Field>): void;
1588
1748
  removeField(id: string): void;
1589
1749
  remove(id: string): void;
1590
- getNode(id: string): {
1591
- kind: "tag";
1592
- data?: Tag;
1593
- owners: {
1594
- parentTagId?: string;
1595
- };
1596
- } | {
1597
- kind: "field";
1598
- data?: Field;
1599
- owners: {
1600
- bindTagIds: string[];
1601
- };
1602
- } | {
1603
- kind: "option";
1604
- data?: any;
1605
- owners: {
1606
- fieldId?: string;
1607
- };
1608
- };
1750
+ getNode(id: string): EditorNodeLookup;
1609
1751
  getFieldQuantityRule(id: string): QuantityRule | undefined;
1610
1752
  setFieldQuantityRule(id: string, rule: unknown): void;
1611
1753
  clearFieldQuantityRule(id: string): void;
1612
- /** Walk ancestors for a tag and detect if parent→child would create a cycle */
1613
- private wouldCreateTagCycle;
1614
- private wouldCreateIncludeExcludeCycle;
1615
1754
  include(receiverId: string, idOrIds: string | string[]): void;
1616
1755
  exclude(receiverId: string, idOrIds: string | string[]): void;
1617
1756
  connect(kind: WireKind, fromId: string, toId: string): void;
1618
1757
  disconnect(kind: WireKind, fromId: string, toId: string): void;
1619
1758
  setConstraint(tagId: string, flag: string, value: boolean | undefined): void;
1620
- /**
1621
- * Clear a constraint override by removing the local constraint that conflicts with an ancestor.
1622
- */
1623
1759
  clearConstraintOverride(tagId: string, flag: string): void;
1624
- /**
1625
- * Clear a constraint from a tag and its descendants.
1626
- * If a descendant has an override, it assigns that override's value as local.
1627
- */
1628
1760
  clearConstraint(tagId: string, flag: string): void;
1761
+ getFieldValidation(id: string): FieldValidationRule[] | undefined;
1762
+ setFieldValidation(id: string, rules: unknown): void;
1763
+ clearFieldValidation(id: string): void;
1764
+ getCatalog(): ServiceCatalogState | undefined;
1765
+ setCatalog(next?: ServiceCatalogState): void;
1766
+ clearCatalog(): void;
1767
+ ensureCatalog(): ServiceCatalogState;
1768
+ createCatalogGroup(input: {
1769
+ id?: string;
1770
+ label: string;
1771
+ parentId?: string;
1772
+ description?: string;
1773
+ serviceIds?: CatalogServiceId[];
1774
+ collapsed?: boolean;
1775
+ order?: number;
1776
+ color?: string;
1777
+ icon?: string;
1778
+ }): string;
1779
+ createSmartCatalogGroup(input: {
1780
+ id?: string;
1781
+ label: string;
1782
+ parentId?: string;
1783
+ description?: string;
1784
+ rules: CatalogSmartRule[];
1785
+ match?: "all" | "any";
1786
+ collapsed?: boolean;
1787
+ order?: number;
1788
+ color?: string;
1789
+ icon?: string;
1790
+ }): string;
1791
+ updateCatalogNode(id: CatalogId, patch: Partial<Omit<CatalogNode, "id" | "kind">>): void;
1792
+ removeCatalogNode(id: CatalogId, opts?: {
1793
+ cascade?: boolean;
1794
+ }): void;
1795
+ moveCatalogNode(nodeId: CatalogId, opts: {
1796
+ parentId?: CatalogId;
1797
+ beforeId?: CatalogId;
1798
+ afterId?: CatalogId;
1799
+ index?: number;
1800
+ }): void;
1801
+ assignServicesToCatalogGroup(nodeId: CatalogId, serviceIds: CatalogServiceId[], mode?: "append" | "replace" | "remove"): void;
1802
+ setActiveCatalogNode(id?: CatalogId): void;
1803
+ setCatalogViewMode(mode: ServiceCatalogState["viewMode"]): void;
1804
+ setSelectedCatalogService(serviceId?: CatalogServiceId): void;
1805
+ toggleCatalogExpanded(id: CatalogId): void;
1806
+ setCatalogExpanded(id: CatalogId, expanded: boolean): void;
1807
+ toggleCatalogPinned(id: CatalogId): void;
1808
+ resolveSmartCatalogGroup(nodeId: CatalogId, candidates: CatalogServiceId[], matchers: {
1809
+ serviceField?: (candidate: CatalogServiceId, rule: Extract<CatalogSmartRule, {
1810
+ type: "service-field";
1811
+ }>) => boolean;
1812
+ policyFamily?: (candidate: CatalogServiceId, rule: Extract<CatalogSmartRule, {
1813
+ type: "policy-family";
1814
+ }>) => boolean;
1815
+ compatibility?: (candidate: CatalogServiceId, rule: Extract<CatalogSmartRule, {
1816
+ type: "compatibility";
1817
+ }>) => boolean;
1818
+ }): CatalogServiceId[];
1819
+ private replaceCatalog;
1629
1820
  private replaceProps;
1630
1821
  private patchProps;
1631
1822
  private afterMutation;
@@ -1633,47 +1824,17 @@ declare class Editor {
1633
1824
  private makeSnapshot;
1634
1825
  private loadSnapshot;
1635
1826
  private pushHistory;
1636
- private genId;
1637
1827
  private emit;
1638
- /**
1639
- * Suggest/filter candidate services against the current visible-group
1640
- * (single tag) context.
1641
- *
1642
- * - Excludes services already used in this group.
1643
- * - Applies capability presence, tag constraints, rate policy, and compiled policies.
1644
- *
1645
- * @param candidates service ids to evaluate
1646
- * @param ctx
1647
- * @param ctx.tagId active visible-group tag id
1648
- * @param ctx.usedServiceIds services already selected for this visible group (first is treated as "primary" for rate policy)
1649
- * @param ctx.effectiveConstraints effective constraints for the active tag (dripfeed/refill/cancel)
1650
- * @param ctx.policies raw JSON policies (will be compiled via compilePolicies)
1651
- * @param ctx.fallback fallback/rate settings (defaults applied if omitted)
1652
- */
1653
1828
  filterServicesForVisibleGroup(candidates: Array<number | string>, ctx: {
1654
1829
  tagId: string;
1830
+ selectedButtons?: string[];
1655
1831
  usedServiceIds: Array<number | string>;
1656
1832
  effectiveConstraints?: Partial<Record<"refill" | "cancel" | "dripfeed", boolean>>;
1657
1833
  policies?: unknown;
1658
1834
  fallback?: FallbackSettings;
1659
1835
  }): ServiceCheck[];
1836
+ private moduleCtx;
1660
1837
  }
1661
- type QuantityRule = {
1662
- valueBy: "value" | "length" | "eval";
1663
- code?: string;
1664
- };
1665
- type ServiceCheck = {
1666
- id: number | string;
1667
- ok: boolean;
1668
- fitsConstraints: boolean;
1669
- passesRate: boolean;
1670
- passesPolicies: boolean;
1671
- policyErrors?: string[];
1672
- policyWarnings?: string[];
1673
- reasons: Array<"constraint_mismatch" | "rate_policy" | "policy_error" | "missing_capability">;
1674
- cap?: DgpServiceCapability;
1675
- rate?: number;
1676
- };
1677
1838
 
1678
1839
  declare class CanvasAPI {
1679
1840
  private bus;
@@ -1684,8 +1845,8 @@ declare class CanvasAPI {
1684
1845
  readonly comments: CommentsAPI;
1685
1846
  readonly selection: Selection;
1686
1847
  constructor(builder: Builder, opts?: CanvasOptions & CanvasBackendOptions);
1687
- on: <K extends keyof CanvasEvents>(event: K, handler: (payload: CanvasEvents[K]) => void) => () => void;
1688
- once: <K extends keyof CanvasEvents>(event: K, handler: (payload: CanvasEvents[K]) => void) => () => void;
1848
+ on: <K extends "error" | "graph:update" | "state:change" | "selection:change" | "viewport:change" | "hover:change" | "wire:preview" | "wire:commit" | "wire:cancel" | "comment:thread:create" | "comment:thread:update" | "comment:thread:delete" | "comment:message:create" | "comment:resolve" | "comment:move" | "comment:select" | "edge:change" | "comment:sync" | keyof EditorEvents>(event: K, handler: (payload: CanvasEvents[K]) => void) => () => void;
1849
+ once: <K extends "error" | "graph:update" | "state:change" | "selection:change" | "viewport:change" | "hover:change" | "wire:preview" | "wire:commit" | "wire:cancel" | "comment:thread:create" | "comment:thread:update" | "comment:thread:delete" | "comment:message:create" | "comment:resolve" | "comment:move" | "comment:select" | "edge:change" | "comment:sync" | keyof EditorEvents>(event: K, handler: (payload: CanvasEvents[K]) => void) => () => void;
1689
1850
  emit<K extends keyof CanvasEvents>(event: K, payload: CanvasEvents[K]): void;
1690
1851
  snapshot(): CanvasState;
1691
1852
  getGraph(): GraphSnapshot;
@@ -1694,7 +1855,7 @@ declare class CanvasAPI {
1694
1855
  refreshGraph(): void;
1695
1856
  setPositions(pos: NodePositions): void;
1696
1857
  setPosition(id: string, x: number, y: number): void;
1697
- select(ids: string[] | Set<string>): void;
1858
+ select(ids: string[] | Set<string>, primary?: string): void;
1698
1859
  addToSelection(ids: string[] | Set<string>): void;
1699
1860
  toggleSelection(id: string): void;
1700
1861
  clearSelection(): void;
@@ -1708,7 +1869,6 @@ declare class CanvasAPI {
1708
1869
  cancelWire(): void;
1709
1870
  private bump;
1710
1871
  dispose(): void;
1711
- undo(): void;
1712
1872
  private edgeRel;
1713
1873
  getEdgeRel(): EdgeKind;
1714
1874
  setEdgeRel(rel: EdgeKind): void;
@@ -1739,46 +1899,25 @@ declare class CanvasAPI {
1739
1899
  getServiceProps(): ServiceProps;
1740
1900
  }
1741
1901
 
1742
- /** Managed props (back-compat): host provides the API instance. */
1743
1902
  type CanvasProviderManagedProps = {
1744
1903
  api: CanvasAPI;
1745
1904
  children: ReactNode;
1746
1905
  };
1747
- /** Workspace-aware props: host omits `api`, we attach to Workspace on demand. */
1748
1906
  type CanvasProviderWorkspaceProps = {
1749
1907
  children: ReactNode;
1750
- /** Optional Builder options (e.g., historyLimit, serviceMap if you already have one). */
1751
1908
  builderOpts?: BuilderOptions;
1752
- /** Canvas view/backend options for CanvasAPI ctor. */
1753
1909
  canvasOpts?: CanvasOptions & CanvasBackendOptions;
1754
- /** If false, we won’t attempt to read Workspace; will throw if no api is provided. */
1755
1910
  attachToWorkspace?: boolean;
1756
1911
  };
1757
1912
  type CanvasProviderProps = CanvasProviderManagedProps | CanvasProviderWorkspaceProps;
1758
- /**
1759
- * CanvasProvider
1760
- * - Managed mode (existing): <CanvasProvider api={api}>{...}</CanvasProvider>
1761
- * - Workspace-aware mode (new): if no `api` and inside a Workspace, auto-create Builder+CanvasAPI and load snapshot props.
1762
- */
1763
1913
  declare function CanvasProvider(props: CanvasProviderProps): react_jsx_runtime.JSX.Element;
1764
1914
  declare function useCanvasAPI(): CanvasAPI;
1765
- /**
1766
- * Create & memoize a CanvasAPI from a Builder.
1767
- * - Disposes the previous API when builder changes.
1768
- * - Accepts both view/state options and backend options.
1769
- * - Warns (DEV only) if `opts` identity is changing every render.
1770
- */
1771
1915
  declare function useCanvasFromBuilder(builder: Builder, opts?: CanvasOptions & CanvasBackendOptions): CanvasAPI;
1772
- /**
1773
- * Use an existing CanvasAPI instance without creating/disposing anything.
1774
- * Useful when the host fully manages the API lifecycle (e.g., from a parent).
1775
- */
1776
1916
  declare function useCanvasFromExisting(api: CanvasAPI): CanvasAPI;
1777
1917
  type UseCanvasOwnedReturn = {
1778
1918
  api: CanvasAPI;
1779
1919
  builder: Builder;
1780
1920
  };
1781
- /** Creates a Builder once, loads initial props, and owns the CanvasAPI lifecycle. */
1782
1921
  declare function useCanvasOwned(initialProps?: ServiceProps, canvasOpts?: CanvasOptions & CanvasBackendOptions, builderOpts?: BuilderOptions): UseCanvasOwnedReturn;
1783
1922
 
1784
1923
  /** Tree node */
@@ -1937,6 +2076,34 @@ interface CreateMemoryWorkspaceBackendOptions {
1937
2076
 
1938
2077
  declare function createMemoryWorkspaceBackend(opts: CreateMemoryWorkspaceBackendOptions): WorkspaceBackend;
1939
2078
 
2079
+ type AdapterOptions = {
2080
+ beforeConnect?: (arg: {
2081
+ from: string;
2082
+ to: string;
2083
+ kind: EdgeKind;
2084
+ api: CanvasAPI;
2085
+ }) => {
2086
+ ok: boolean;
2087
+ reason?: string;
2088
+ };
2089
+ afterConnect?: (arg: {
2090
+ from: string;
2091
+ to: string;
2092
+ kind: EdgeKind;
2093
+ created: boolean;
2094
+ api: CanvasAPI;
2095
+ }) => void;
2096
+ allowEdgeDelete?: boolean;
2097
+ enableShortcuts?: boolean;
2098
+ snapToGrid?: boolean | {
2099
+ x: number;
2100
+ y: number;
2101
+ };
2102
+ throttleMs?: number;
2103
+ nodeDecorators?: (nodeId: string) => Partial<Node>;
2104
+ edgeDecorators?: (edgeId: string) => Partial<Edge>;
2105
+ };
2106
+
1940
2107
  type ToolKind = 'command' | 'toggle' | 'mode' | 'menu';
1941
2108
  type ToolGroup = 'relation' | 'viewport' | 'view' | 'edit' | (string & {});
1942
2109
  type EnabledState = boolean | {
@@ -1944,6 +2111,7 @@ type EnabledState = boolean | {
1944
2111
  reason?: string;
1945
2112
  };
1946
2113
  type ToolbarIcon = string | ((active: boolean, disabled: boolean) => React__default.ReactNode);
2114
+ type LabelPlacement = 'tooltip' | 'inline' | 'below' | 'none';
1947
2115
  type ToolDescriptor = {
1948
2116
  id: string;
1949
2117
  kind: ToolKind;
@@ -1992,6 +2160,69 @@ type ToolsConfig = {
1992
2160
  hidden?: string[];
1993
2161
  };
1994
2162
 
2163
+ type ToolbarProps = {
2164
+ api: CanvasAPI;
2165
+ mode?: "dev" | "prod";
2166
+ showGrid: boolean;
2167
+ setShowGrid: (v: boolean) => void;
2168
+ showMiniMap: boolean;
2169
+ setShowMiniMap: (v: boolean) => void;
2170
+ tools?: ToolsConfig;
2171
+ /** Default: 'tooltip' (hidden label, shown as native tooltip) */
2172
+ labelPlacement?: LabelPlacement;
2173
+ /** Optional custom button renderer */
2174
+ renderButton?: (t: ToolRender, key: string) => React__default.ReactNode;
2175
+ };
2176
+ type ToolRender = {
2177
+ id: string;
2178
+ label?: string;
2179
+ icon?: React__default.ReactNode;
2180
+ active: boolean;
2181
+ disabled: boolean;
2182
+ disabledReason?: string;
2183
+ onClick: () => void;
2184
+ group?: string;
2185
+ hasMenu?: boolean;
2186
+ open?: boolean;
2187
+ onToggleMenu?: () => void;
2188
+ children?: ToolRender[];
2189
+ };
2190
+ declare function Toolbar({ api, mode, showGrid, setShowGrid, showMiniMap, setShowMiniMap, tools, labelPlacement, renderButton, }: ToolbarProps): react_jsx_runtime.JSX.Element;
2191
+
2192
+ type ReactFlowCanvasProps = {
2193
+ api: CanvasAPI;
2194
+ options?: AdapterOptions;
2195
+ showToolbar?: boolean;
2196
+ tools?: ToolsConfig;
2197
+ labelPlacement?: LabelPlacement;
2198
+ renderTool?: Parameters<typeof Toolbar>[0]["renderButton"];
2199
+ initialShowGrid?: boolean;
2200
+ initialShowMiniMap?: boolean;
2201
+ /** absolute position classes relative to the ReactFlow canvas */
2202
+ toolbarPositionClassName?: string;
2203
+ children?: React__default.ReactNode;
2204
+ };
2205
+ declare function Canvas({ api, options, showToolbar, tools, labelPlacement, renderTool, initialShowGrid, initialShowMiniMap, toolbarPositionClassName, children, }: ReactFlowCanvasProps): react_jsx_runtime.JSX.Element;
2206
+
2207
+ type FlowCanvasProps = {
2208
+ tools?: ToolsConfig;
2209
+ /** 'dev' enables richer UX; 'prod' can hide some helpers */
2210
+ mode?: "dev" | "prod";
2211
+ /** Show/position the toolbar (inside the ReactFlow surface) */
2212
+ showToolbar?: boolean;
2213
+ toolbarPositionClassName?: string;
2214
+ /** How labels render on buttons: tooltip | inline | below | none */
2215
+ labelPlacement?: LabelPlacement;
2216
+ /** Pass custom renderer for individual tool buttons */
2217
+ renderTool?: React__default.ComponentProps<typeof Canvas>["renderTool"];
2218
+ /** Initial layer toggles */
2219
+ initialShowGrid?: boolean;
2220
+ initialShowMiniMap?: boolean;
2221
+ /** Adapter options (snapping etc.) */
2222
+ options?: AdapterOptions;
2223
+ children?: React__default.ReactNode;
2224
+ };
2225
+
1995
2226
  /**
1996
2227
  * Props for the Workspace wrapper. Mirrors WorkspaceProvider options.
1997
2228
  */
@@ -2021,4 +2252,4 @@ interface WorkspaceProps {
2021
2252
  */
2022
2253
  declare function Workspace(props: WorkspaceProps): React.JSX.Element;
2023
2254
 
2024
- export { type Actor, type Author, type AuthorsBackend, type BackendError, type BackendResult, type BackendScope, type Branch, type BranchAccessBackend, type BranchParticipant, type BranchesBackend, type BranchesSlice, CanvasProvider, type CanvasSelection, type ClearTarget, type CommentsBackend, type Commit, type CreateMemoryWorkspaceBackendOptions, type Draft, type ErrorKind, type ErrorLog, type FieldTemplate, type LiveOptions, type Loadable, type MemoryBackendSeed, type MemorySeedBranchSnapshots, type MemorySeedComments, type MemorySeedParticipants, type MergeResult, type MergedErrors, type PermissionsBackend, type PermissionsMap, type PoliciesBackend, type PoliciesLoadResult, type PolicyScope, type Result, type ServiceSnapshot, type ServicesBackend, type ServicesInput, type SnapshotSlice, type SnapshotsBackend, type SnapshotsLoadResult, type TemplateCreateInput, type TemplateUpdatePatch, type TemplateValidator, type TemplatesBackend, type TemplatesListParams, type TreeNode, type UseCanvasReturn, type UseErrorsOptions, type UseErrorsReturn, type ValidationRow, Workspace, type WorkspaceAPI, type WorkspaceBackend, WorkspaceContext, type WorkspaceEvent, type WorkspaceInfo, type WorkspaceLiveAdapter, type WorkspaceLiveAdapterContext, type WorkspaceLiveAdapterHandlers, type WorkspaceLiveAdapterRegistry, type WorkspaceLiveStatus, type WorkspaceLiveTick, type WorkspaceProps, WorkspaceProvider, type WorkspaceProviderProps, createMemoryWorkspaceBackend, createPollAdapter, useCanvas, useCanvasAPI, useCanvasFromBuilder, useCanvasFromExisting, useCanvasOwned, useErrors, useWorkspace, useWorkspaceMaybe };
2255
+ export { type Actor, type AdapterOptions, type Author, type AuthorsBackend, type BackendError, type BackendResult, type BackendScope, type Branch, type BranchAccessBackend, type BranchParticipant, type BranchesBackend, type BranchesSlice, Canvas, CanvasProvider, type CanvasSelection, type ClearTarget, type CommentsBackend, type Commit, type CreateMemoryWorkspaceBackendOptions, type Draft, type ErrorKind, type ErrorLog, type FieldTemplate, type FlowCanvasProps, type LabelPlacement, type LiveOptions, type Loadable, type MemoryBackendSeed, type MemorySeedBranchSnapshots, type MemorySeedComments, type MemorySeedParticipants, type MergeResult, type MergedErrors, type PermissionsBackend, type PermissionsMap, type PoliciesBackend, type PoliciesLoadResult, type PolicyScope, type Result, type ServiceSnapshot, type ServicesBackend, type ServicesInput, type SnapshotSlice, type SnapshotsBackend, type SnapshotsLoadResult, type TemplateCreateInput, type TemplateUpdatePatch, type TemplateValidator, type TemplatesBackend, type TemplatesListParams, type ToolsConfig, type TreeNode, type UseCanvasReturn, type UseErrorsOptions, type UseErrorsReturn, type ValidationRow, Workspace, type WorkspaceAPI, type WorkspaceBackend, type WorkspaceBootSection, type WorkspaceBootSectionState, type WorkspaceBootSectionStatus, type WorkspaceBootState, WorkspaceContext, type WorkspaceEvent, type WorkspaceInfo, type WorkspaceLiveAdapter, type WorkspaceLiveAdapterContext, type WorkspaceLiveAdapterHandlers, type WorkspaceLiveAdapterRegistry, type WorkspaceLiveStatus, type WorkspaceLiveTick, type WorkspaceProps, WorkspaceProvider, type WorkspaceProviderProps, createMemoryWorkspaceBackend, createPollAdapter, useCanvas, useCanvasAPI, useCanvasFromBuilder, useCanvasFromExisting, useCanvasOwned, useErrors, useWorkspace, useWorkspaceBoot, useWorkspaceMaybe };