@ixo/editor 6.32.0 → 6.33.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.
@@ -1,8 +1,11 @@
1
- import { a6 as FlowNode, a7 as FlowNodeAuthzExtension, F as FlowRuntimeStateManager, g as UcanService, I as InvocationStore, a8 as EvaluationStatus, a9 as IxoEditorType, aa as PendingInvocation, ab as ActionServices, ac as ActionHandlers, ad as RunEventAppender, ae as ActionResult, af as ActionDefinition, j as UcanCapability, ag as FlowNodeRuntimeState, U as UcanDelegationStore, S as StoredDelegation } from './index-Up8gA_E9.js';
1
+ import { a6 as FlowNodeAuthzExtension, a7 as FlowNode, a8 as EvaluationStatus, F as FlowRuntimeStateManager, G as UcanService, g as InvocationStore, a9 as IxoEditorType, aa as PendingInvocation, ab as ActionServices, ac as ActionHandlers, ad as RunEventAppender, ae as TopicExecutionContext, af as TopicActionBridge, ag as ActionResult, ah as TopicActionWriteBackResult, U as UcanCapability, ai as FlowNodeRuntimeState, z as UcanDelegationStore, v as StoredDelegation, aj as ActionDefinition } from './runtime-BFwvCQDF.js';
2
2
  import * as Y from 'yjs';
3
3
  import { Doc, Map } from 'yjs';
4
4
  import { MatrixClient } from 'matrix-js-sdk';
5
5
 
6
+ declare const buildAuthzFromProps: (props: Record<string, any>) => FlowNodeAuthzExtension;
7
+ declare const buildFlowNodeFromBlock: (block: any) => FlowNode;
8
+
6
9
  /** Condition that gates when a capability activates. */
7
10
  interface ConditionRef {
8
11
  /** ID of the upstream capability whose output is checked. */
@@ -111,14 +114,28 @@ interface TriggerSpec {
111
114
  * - `flow.start`: block runs when the flow execution begins.
112
115
  * - `block.event`: block runs each time another block emits a matching event.
113
116
  * - `block.event.all`: block runs once ALL listed sources have emitted (barrier/join).
117
+ * - `schedule`: block runs when a sovereign schedule fires (Sovereign
118
+ * Scheduling, IXO-4429). The block carries only a reference — the five
119
+ * time kinds (time.at/cron/interval/delay/relative), timezone and
120
+ * recurrence live in the referenced ScheduleSpec, never in block props,
121
+ * so editing a schedule does not force a flow recompile and the timing
122
+ * provider never sees flow content.
114
123
  */
115
- type: 'manual' | 'flow.start' | 'block.event' | 'block.event.all';
124
+ type: 'manual' | 'flow.start' | 'block.event' | 'block.event.all' | 'schedule';
116
125
  /** Required when `type === 'block.event'`. ID of the block that emits the event. */
117
126
  sourceBlockId?: string;
118
127
  /** Required when `type === 'block.event'`. Name of the event (must match an event declared on the source action's `events` vocabulary). */
119
128
  eventName?: string;
120
129
  /** Required when `type === 'block.event.all'`. Array of event sources — ALL must fire before the listener is queued. */
121
130
  sources?: TriggerSource[];
131
+ /** Required when `type === 'schedule'`. Stable ID of the ScheduleSpec this block is bound to. */
132
+ scheduleRef?: string;
133
+ /**
134
+ * Optional when `type === 'schedule'`: pin to one schedule revision.
135
+ * Cloning a flow as a template must strip `scheduleRef` — an active
136
+ * schedule ID names one authorized binding, not a reusable default.
137
+ */
138
+ scheduleRevision?: number;
122
139
  }
123
140
  /**
124
141
  * The Base UCAN flow plan — the intermediate representation between
@@ -207,9 +224,6 @@ interface CompiledFlow {
207
224
  /** Strategy for how a compiled flow is applied to an existing document. */
208
225
  type FlowStrategy = 'full' | 'merge' | 'patch';
209
226
 
210
- declare const buildAuthzFromProps: (props: Record<string, any>) => FlowNodeAuthzExtension;
211
- declare const buildFlowNodeFromBlock: (block: any) => FlowNode;
212
-
213
227
  /**
214
228
  * Context passed to resolveRuntimeRefs when resolving inputs for a triggered
215
229
  * listener block. The runtime constructs this from a PendingInvocation when
@@ -351,6 +365,14 @@ interface ExecuteActionBlockParams extends BuildActionRunInputsParams {
351
365
  flowId?: string;
352
366
  flowOwnerDid?: string;
353
367
  schemaVersion?: string;
368
+ /** Optional revision-bound Topic context; never substitutes for Flow authority. */
369
+ topic?: TopicExecutionContext;
370
+ /** Durable receipt bridge, supplied only after independent Topic UCAN verification. */
371
+ topicBridge?: TopicActionBridge;
372
+ /** DID of the runtime provider/controller issuing Topic receipts. */
373
+ executorDid?: string;
374
+ /** Pinned Flow revision or digest used by Topic bindings and receipts. */
375
+ flowRevision?: string;
354
376
  }
355
377
  interface ExecuteActionBlockResult {
356
378
  success: boolean;
@@ -386,6 +408,7 @@ interface ExecuteActionBlockResult {
386
408
  pendingInvocationRemoved?: boolean;
387
409
  completionState: ActionExecutionCompletionState;
388
410
  pendingInvocation?: PendingInvocation;
411
+ topicWriteBack?: TopicActionWriteBackResult;
389
412
  }
390
413
  declare function buildActionRunInputs(params: BuildActionRunInputsParams): BuildActionRunInputsResult;
391
414
  declare function executeActionBlock(params: ExecuteActionBlockParams): Promise<ExecuteActionBlockResult>;
@@ -406,81 +429,329 @@ interface AuthorizationResult {
406
429
  */
407
430
  declare const isAuthorized: (blockId: string, actorDid: string, ucanService: UcanService | undefined, flowUri: string, schemaVersion?: string) => Promise<AuthorizationResult>;
408
431
 
409
- /** Registry interface expected by the compiler (keeps it pure / testable). */
410
- interface CompilerRegistry {
411
- getActionByCan(can: string): ActionDefinition | undefined;
432
+ type FlowAgentPublicNodeState = 'Pending' | 'Blocked' | 'Overdue' | 'Done';
433
+ type FlowAgentRunPhase = 'Running' | 'Validating' | 'Failed' | 'Archived';
434
+ type FlowAgentBlockerCause = 'missing_input' | 'failed_upstream' | 'missing_ucan' | 'stale_config' | 'service_error' | 'external_confirmation_pending' | 'validation_mismatch' | 'unverified_completion' | 'awaiting_verification' | 'unknown';
435
+ type FlowAgentCommandType = 'diagnose_blocker' | 'assign_actor' | 'notify_actor' | 'execute_action' | 'validate_external_state' | 'archive_flow' | 'propose_config_change';
436
+ type FlowAgentCommandStatus = 'queued' | 'leased' | 'running' | 'confirmed' | 'awaiting_readback' | 'failed' | 'skipped';
437
+ type FlowAgentLedgerEventType = 'agent.decision' | 'agent.command' | 'agent.validation' | 'agent.escalation' | 'agent.memory';
438
+ interface FlowAgentActor {
439
+ did: string;
440
+ matrixUserId?: string;
441
+ displayName?: string;
442
+ skills?: string[];
443
+ }
444
+ interface FlowAgentLease {
445
+ id: string;
446
+ commandId: string;
447
+ sessionRunId: string;
448
+ nodeId: string;
449
+ actorDid: string;
450
+ acquiredAt: number;
451
+ expiresAt: number;
452
+ epoch: number;
453
+ }
454
+ interface FlowAgentNodeSnapshot {
455
+ nodeId: string;
456
+ blockType: string;
457
+ actionType?: string;
458
+ title?: string;
459
+ runtime: FlowNodeRuntimeState;
460
+ publicState: FlowAgentPublicNodeState;
461
+ blockerCause?: FlowAgentBlockerCause;
462
+ assigneeDid?: string;
463
+ dueAt?: number;
464
+ pendingInvocationCount: number;
465
+ }
466
+ interface FlowAgentCommandBase {
467
+ id: string;
468
+ type: FlowAgentCommandType;
469
+ flowId: string;
470
+ sessionRunId: string;
471
+ flowUri: string;
472
+ nodeId: string;
473
+ actorDid: string;
474
+ status: FlowAgentCommandStatus;
475
+ capability: UcanCapability;
476
+ idempotencyKey: string;
477
+ createdAt: number;
478
+ updatedAt: number;
479
+ reason: string;
480
+ payload: Record<string, unknown>;
481
+ lease?: FlowAgentLease;
482
+ error?: string;
483
+ }
484
+ type FlowAgentCommand = FlowAgentCommandBase;
485
+ interface FlowAgentLedgerEvent {
486
+ id: string;
487
+ type: FlowAgentLedgerEventType;
488
+ flowId: string;
489
+ sessionRunId: string;
490
+ nodeId?: string;
491
+ commandId?: string;
492
+ actorDid: string;
493
+ timestamp: number;
494
+ details: Record<string, unknown>;
495
+ }
496
+ interface FlowAgentMaps {
497
+ outbox: Map<FlowAgentCommand>;
498
+ leases: Map<FlowAgentLease>;
499
+ }
500
+ interface FlowAgentPolicyDecision {
501
+ allowed: boolean;
502
+ reason: string;
503
+ capability: UcanCapability;
504
+ proofCids: string[];
505
+ }
506
+ interface FlowAgentContext {
507
+ yDoc: Doc;
508
+ editor?: IxoEditorType;
509
+ /** Planner targets, including executable actions and manual work nodes. */
510
+ blocks?: unknown[];
511
+ /** Full recursive document used to resolve condition source blocks. */
512
+ documentBlocks?: unknown[];
513
+ flowId: string;
514
+ sessionRunId: string;
515
+ flowUri: string;
516
+ actor: FlowAgentActor;
517
+ now?: () => number;
518
+ }
519
+ interface FlowAgentCommandResult {
520
+ commandId: string;
521
+ success: boolean;
522
+ output?: Record<string, unknown>;
523
+ confirmed?: boolean;
524
+ completionState?: ActionExecutionCompletionState;
525
+ status?: FlowAgentCommandStatus;
526
+ error?: string;
527
+ }
528
+ interface FlowAgentExecutor {
529
+ executeAction?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
530
+ assignActor?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
531
+ notifyActor?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
532
+ validateExternalState?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
533
+ archiveFlow?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
534
+ proposeConfigChange?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
535
+ diagnoseBlocker?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
536
+ }
537
+ interface FlowAgentTickResult {
538
+ flowDone: boolean;
539
+ snapshots: FlowAgentNodeSnapshot[];
540
+ queuedCommands: FlowAgentCommand[];
541
+ executedCommands: FlowAgentCommandResult[];
542
+ }
543
+
544
+ interface CreateAgentCommandParams {
545
+ type: FlowAgentCommandType;
546
+ flowId: string;
547
+ sessionRunId: string;
548
+ flowUri: string;
549
+ nodeId: string;
550
+ actor: FlowAgentActor;
551
+ reason: string;
552
+ payload?: Record<string, unknown>;
553
+ now?: number;
554
+ }
555
+ declare function createAgentCommand({ type, flowId, sessionRunId, flowUri, nodeId, actor, reason, payload, now }: CreateAgentCommandParams): FlowAgentCommand;
556
+ declare function validateAgentCommand(command: FlowAgentCommand): {
557
+ valid: boolean;
558
+ error?: string;
559
+ };
560
+ declare function isExternalMutation(type: FlowAgentCommandType): boolean;
561
+
562
+ interface BuildFlowAgentContextParams {
563
+ yDoc: Doc;
564
+ flowId: string;
565
+ sessionRunId: string;
566
+ flowUri?: string;
567
+ actor: FlowAgentActor;
568
+ blocks?: unknown[];
569
+ documentBlocks?: unknown[];
570
+ editor?: IxoEditorType;
571
+ now?: () => number;
412
572
  }
413
573
  /**
414
- * Compile a Base UCAN flow plan into blocks, graph state, and metadata.
574
+ * Builds the host-facing runtime context expected by the Flow Agent.
415
575
  *
416
- * This is a **pure function** no React, no Yjs, no side effects.
417
- * The output is consumed by `hydrateFlowFromPlan()`.
576
+ * Headless hosts own Matrix login, room joins, and Y.Doc sync. Once a host has
577
+ * a live room document and an agent identity, this helper gives it the stable
578
+ * context shape to pass into `tickFlowAgent` or `FlowAgentService`.
418
579
  */
419
- declare function compileBaseUcanFlow(plan: BaseUcanFlow, registry: CompilerRegistry): CompiledFlow;
580
+ declare function buildFlowAgentContext({ yDoc, flowId, sessionRunId, flowUri, actor, blocks, documentBlocks, editor, now, }: BuildFlowAgentContextParams): FlowAgentContext;
420
581
 
421
- /** Describes what changed when merging two compiled flows. */
422
- interface MergeResult {
423
- /** The merged compiled flow (full state). */
424
- merged: CompiledFlow;
425
- /** Node IDs that were added (new in incoming, not in existing). */
426
- added: string[];
427
- /** Node IDs that were replaced (patch only — existed and was overwritten). */
428
- replaced: string[];
429
- /** Node IDs that were kept unchanged from existing. */
430
- kept: string[];
582
+ interface AcquireFlowAgentLeaseParams {
583
+ leases: Map<FlowAgentLease>;
584
+ commandId: string;
585
+ sessionRunId: string;
586
+ nodeId: string;
587
+ actorDid: string;
588
+ now?: number;
589
+ ttlMs?: number;
431
590
  }
591
+ declare function acquireFlowAgentLease({ leases, commandId, sessionRunId, nodeId, actorDid, now, ttlMs, }: AcquireFlowAgentLeaseParams): FlowAgentLease | null;
592
+ declare function validateFlowAgentLease(leases: Map<FlowAgentLease>, lease: FlowAgentLease, now?: number): boolean;
593
+ declare function releaseFlowAgentLease(leases: Map<FlowAgentLease>, lease: FlowAgentLease): boolean;
594
+ declare function cleanupExpiredFlowAgentLeases(leases: Map<FlowAgentLease>, now?: number): FlowAgentLease[];
595
+
596
+ declare function requiredCapabilityForCommand(type: FlowAgentCommandType, flowUri: string, nodeId: string): UcanCapability;
597
+ declare function isCapabilityMatch(granted: UcanCapability, required: UcanCapability): boolean;
432
598
  /**
433
- * Merge an incoming compiled flow into an existing one.
434
- *
435
- * This is a **pure function** — no Yjs, no side effects.
599
+ * Match a granted capability pattern against a required `can`.
436
600
  *
437
- * Strategies:
438
- * - `merge`: existing nodes win on ID collision. Incoming nodes with new IDs
439
- * are added. Existing nodes are never modified.
440
- * - `patch`: incoming nodes overwrite existing nodes on ID collision. Incoming
441
- * nodes with new IDs are added. Existing nodes not in incoming are kept.
601
+ * ⚠️ This is the **trusted flow-agent policy** matcher: it allows the global
602
+ * `'*'` wildcard, so a delegation granting `can: '*'` matches every ability.
603
+ * It is re-exported from `src/core/index.ts` do not use it to gate public or
604
+ * untrusted matching. For that, call `capabilityPatternCoversCan` directly and
605
+ * leave `allowGlobalWildcard` off (the default), which rejects `'*'`.
442
606
  *
443
- * Edges in the merged result are the union of edges from both sides, filtered
444
- * to those whose source and target both exist in the merged node set, with
445
- * duplicates collapsed by edge id. Order is the merged node insertion order
446
- * (existing first, then newly added) — there is no topological sort because
447
- * there is no inferred dependency relationship.
607
+ * Note: the granted side is normalized (`normalizeCan`), so dotted legacy
608
+ * grants such as `flow.notify` / `flow.*` now match `flow/notify` where they
609
+ * were previously inert.
448
610
  */
449
- declare function mergeCompiledFlows(existing: CompiledFlow, incoming: CompiledFlow, strategy: 'merge' | 'patch'): MergeResult;
450
-
451
- interface SetupFlowOptions {
452
- /** The Base UCAN flow plan to compile. */
453
- plan: BaseUcanFlow;
454
- /** Matrix room ID to hydrate the flow into. */
455
- roomId: string;
456
- /** Authenticated Matrix client. */
457
- matrixClient: MatrixClient;
458
- /** DID of the user setting up the flow. */
459
- creatorDid: string;
460
- /** Optional doc ID override (defaults to plan.flowId). */
461
- docId?: string;
462
- /**
463
- * Room ID of the template this flow was instantiated from, if any.
464
- * Recorded into the root map as `source_template_id` for lineage tracking.
465
- */
466
- templateId?: string;
467
- /**
468
- * How to apply the plan to the existing document.
469
- * - `full` (default): wipe existing flow state and rebuild entirely.
470
- * - `merge`: keep existing blocks, add new capabilities from the plan.
471
- * - `patch`: replace matching nodes, add new ones, keep the rest.
472
- */
473
- strategy?: FlowStrategy;
611
+ declare function canMatches(granted: string, required: string): boolean;
612
+ declare function resourceMatches(granted: string, required: string): boolean;
613
+ interface EvaluateFlowAgentPolicyParams {
614
+ actorDid: string;
615
+ commandType: FlowAgentCommandType;
616
+ flowUri: string;
617
+ nodeId: string;
618
+ delegationStore?: UcanDelegationStore;
619
+ delegations?: StoredDelegation[];
620
+ now?: number;
474
621
  }
475
- interface SetupFlowResult {
476
- /** The compiled flow artifacts. */
477
- compiled: CompiledFlow;
478
- /** The room ID (same as input, for convenience). */
479
- roomId: string;
480
- /** The flow ID from the plan. */
481
- flowId: string;
622
+ declare function evaluateFlowAgentPolicy({ actorDid, commandType, flowUri, nodeId, delegationStore, delegations, now, }: EvaluateFlowAgentPolicyParams): FlowAgentPolicyDecision;
623
+
624
+ interface FlowAgentOrchestratorOptions {
625
+ delegationStore?: UcanDelegationStore;
626
+ delegations?: StoredDelegation[];
627
+ candidateActors?: FlowAgentActor[];
628
+ executor?: FlowAgentExecutor;
629
+ leaseTtlMs?: number;
630
+ archiveWhenDone?: boolean;
482
631
  }
483
- interface ReadFlowOptions {
632
+ declare function planRalphLoopCommands(context: FlowAgentContext, options?: FlowAgentOrchestratorOptions): {
633
+ snapshots: FlowAgentNodeSnapshot[];
634
+ queuedCommands: FlowAgentCommand[];
635
+ flowDone: boolean;
636
+ };
637
+ declare function executeQueuedAgentCommands(context: FlowAgentContext, options?: FlowAgentOrchestratorOptions): Promise<FlowAgentCommandResult[]>;
638
+ declare function tickFlowAgent(context: FlowAgentContext, options?: FlowAgentOrchestratorOptions): Promise<FlowAgentTickResult>;
639
+
640
+ interface FlowAgentServiceOptions extends FlowAgentOrchestratorOptions {
641
+ intervalMs?: number;
642
+ onTick?: (result: FlowAgentTickResult) => void | Promise<void>;
643
+ onError?: (error: unknown) => void;
644
+ }
645
+ /**
646
+ * Headless-service adapter boundary.
647
+ *
648
+ * Host applications own Matrix login, room joins, and Y.Doc sync. Once they
649
+ * have a live Y.Doc/editor snapshot, this service provides the deterministic
650
+ * Ralph-loop tick and command execution cycle.
651
+ */
652
+ declare class FlowAgentService {
653
+ private readonly context;
654
+ private readonly options;
655
+ private timer;
656
+ private running;
657
+ constructor(context: FlowAgentContext, options?: FlowAgentServiceOptions);
658
+ tick(): Promise<FlowAgentTickResult>;
659
+ start(): void;
660
+ stop(): void;
661
+ }
662
+
663
+ declare function getFlowAgentMaps(yDoc: Doc): FlowAgentMaps;
664
+ declare function computeAgentCommandId(params: {
665
+ flowId: string;
666
+ sessionRunId: string;
667
+ nodeId: string;
668
+ type: string;
669
+ payload: Record<string, unknown>;
670
+ }): string;
671
+ declare function queueAgentCommand(yDoc: Doc, command: FlowAgentCommand): {
672
+ command: FlowAgentCommand;
673
+ created: boolean;
674
+ };
675
+ /** Read every command for one session without creating the outbox map. */
676
+ declare function readAgentCommands(yDoc: Doc, sessionRunId?: string): FlowAgentCommand[];
677
+ declare function readQueuedAgentCommands(yDoc: Doc, sessionRunId?: string): FlowAgentCommand[];
678
+ /** Read every lease for one session without creating the leases map. */
679
+ declare function readFlowAgentLeases(yDoc: Doc, sessionRunId?: string): FlowAgentLease[];
680
+ declare function updateAgentCommand(yDoc: Doc, commandId: string, patch: Partial<FlowAgentCommand>): FlowAgentCommand | null;
681
+ declare function appendAgentLedgerEvent(yDoc: Doc, event: Omit<FlowAgentLedgerEvent, 'id'> & {
682
+ id?: string;
683
+ }): FlowAgentLedgerEvent;
684
+ declare function readAgentLedgerEvents(yDoc: Doc, eventType?: FlowAgentLedgerEventType, sessionRunId?: string): FlowAgentLedgerEvent[];
685
+
686
+ /** Registry interface expected by the compiler (keeps it pure / testable). */
687
+ interface CompilerRegistry {
688
+ getActionByCan(can: string): ActionDefinition | undefined;
689
+ }
690
+ declare function compileBaseUcanFlow(plan: BaseUcanFlow, registry: CompilerRegistry): CompiledFlow;
691
+
692
+ /** Describes what changed when merging two compiled flows. */
693
+ interface MergeResult {
694
+ /** The merged compiled flow (full state). */
695
+ merged: CompiledFlow;
696
+ /** Node IDs that were added (new in incoming, not in existing). */
697
+ added: string[];
698
+ /** Node IDs that were replaced (patch only — existed and was overwritten). */
699
+ replaced: string[];
700
+ /** Node IDs that were kept unchanged from existing. */
701
+ kept: string[];
702
+ }
703
+ /**
704
+ * Merge an incoming compiled flow into an existing one.
705
+ *
706
+ * This is a **pure function** — no Yjs, no side effects.
707
+ *
708
+ * Strategies:
709
+ * - `merge`: existing nodes win on ID collision. Incoming nodes with new IDs
710
+ * are added. Existing nodes are never modified.
711
+ * - `patch`: incoming nodes overwrite existing nodes on ID collision. Incoming
712
+ * nodes with new IDs are added. Existing nodes not in incoming are kept.
713
+ *
714
+ * Edges in the merged result are the union of edges from both sides, filtered
715
+ * to those whose source and target both exist in the merged node set, with
716
+ * duplicates collapsed by edge id. Order is the merged node insertion order
717
+ * (existing first, then newly added) — there is no topological sort because
718
+ * there is no inferred dependency relationship.
719
+ */
720
+ declare function mergeCompiledFlows(existing: CompiledFlow, incoming: CompiledFlow, strategy: 'merge' | 'patch'): MergeResult;
721
+
722
+ interface SetupFlowOptions {
723
+ /** The Base UCAN flow plan to compile. */
724
+ plan: BaseUcanFlow;
725
+ /** Matrix room ID to hydrate the flow into. */
726
+ roomId: string;
727
+ /** Authenticated Matrix client. */
728
+ matrixClient: MatrixClient;
729
+ /** DID of the user setting up the flow. */
730
+ creatorDid: string;
731
+ /** Optional doc ID override (defaults to plan.flowId). */
732
+ docId?: string;
733
+ /**
734
+ * Room ID of the template this flow was instantiated from, if any.
735
+ * Recorded into the root map as `source_template_id` for lineage tracking.
736
+ */
737
+ templateId?: string;
738
+ /**
739
+ * How to apply the plan to the existing document.
740
+ * - `full` (default): wipe existing flow state and rebuild entirely.
741
+ * - `merge`: keep existing blocks, add new capabilities from the plan.
742
+ * - `patch`: replace matching nodes, add new ones, keep the rest.
743
+ */
744
+ strategy?: FlowStrategy;
745
+ }
746
+ interface SetupFlowResult {
747
+ /** The compiled flow artifacts. */
748
+ compiled: CompiledFlow;
749
+ /** The room ID (same as input, for convenience). */
750
+ roomId: string;
751
+ /** The flow ID from the plan. */
752
+ flowId: string;
753
+ }
754
+ interface ReadFlowOptions {
484
755
  /** Matrix room ID to read from. */
485
756
  roomId: string;
486
757
  /** Authenticated Matrix client. */
@@ -782,258 +1053,4 @@ declare function upsertFlowConnectionBinding(yDoc: Doc, binding: FlowConnectionB
782
1053
  /** Remove a binding. No-op when the flow has no binding for `toolkit`. */
783
1054
  declare function removeFlowConnectionBinding(yDoc: Doc, toolkit: string): void;
784
1055
 
785
- type FlowAgentPublicNodeState = 'Pending' | 'Blocked' | 'Overdue' | 'Done';
786
- type FlowAgentRunPhase = 'Running' | 'Validating' | 'Failed' | 'Archived';
787
- type FlowAgentBlockerCause = 'missing_input' | 'failed_upstream' | 'missing_ucan' | 'stale_config' | 'service_error' | 'external_confirmation_pending' | 'validation_mismatch' | 'unverified_completion' | 'awaiting_verification' | 'unknown';
788
- type FlowAgentCommandType = 'diagnose_blocker' | 'assign_actor' | 'notify_actor' | 'execute_action' | 'validate_external_state' | 'archive_flow' | 'propose_config_change';
789
- type FlowAgentCommandStatus = 'queued' | 'leased' | 'running' | 'confirmed' | 'awaiting_readback' | 'failed' | 'skipped';
790
- type FlowAgentLedgerEventType = 'agent.decision' | 'agent.command' | 'agent.validation' | 'agent.escalation' | 'agent.memory';
791
- interface FlowAgentActor {
792
- did: string;
793
- matrixUserId?: string;
794
- displayName?: string;
795
- skills?: string[];
796
- }
797
- interface FlowAgentLease {
798
- id: string;
799
- commandId: string;
800
- sessionRunId: string;
801
- nodeId: string;
802
- actorDid: string;
803
- acquiredAt: number;
804
- expiresAt: number;
805
- epoch: number;
806
- }
807
- interface FlowAgentNodeSnapshot {
808
- nodeId: string;
809
- blockType: string;
810
- actionType?: string;
811
- title?: string;
812
- runtime: FlowNodeRuntimeState;
813
- publicState: FlowAgentPublicNodeState;
814
- blockerCause?: FlowAgentBlockerCause;
815
- assigneeDid?: string;
816
- dueAt?: number;
817
- pendingInvocationCount: number;
818
- }
819
- interface FlowAgentCommandBase {
820
- id: string;
821
- type: FlowAgentCommandType;
822
- flowId: string;
823
- sessionRunId: string;
824
- flowUri: string;
825
- nodeId: string;
826
- actorDid: string;
827
- status: FlowAgentCommandStatus;
828
- capability: UcanCapability;
829
- idempotencyKey: string;
830
- createdAt: number;
831
- updatedAt: number;
832
- reason: string;
833
- payload: Record<string, unknown>;
834
- lease?: FlowAgentLease;
835
- error?: string;
836
- }
837
- type FlowAgentCommand = FlowAgentCommandBase;
838
- interface FlowAgentLedgerEvent {
839
- id: string;
840
- type: FlowAgentLedgerEventType;
841
- flowId: string;
842
- sessionRunId: string;
843
- nodeId?: string;
844
- commandId?: string;
845
- actorDid: string;
846
- timestamp: number;
847
- details: Record<string, unknown>;
848
- }
849
- interface FlowAgentMaps {
850
- outbox: Map<FlowAgentCommand>;
851
- leases: Map<FlowAgentLease>;
852
- }
853
- interface FlowAgentPolicyDecision {
854
- allowed: boolean;
855
- reason: string;
856
- capability: UcanCapability;
857
- proofCids: string[];
858
- }
859
- interface FlowAgentContext {
860
- yDoc: Doc;
861
- editor?: IxoEditorType;
862
- /** Planner targets, including executable actions and manual work nodes. */
863
- blocks?: unknown[];
864
- /** Full recursive document used to resolve condition source blocks. */
865
- documentBlocks?: unknown[];
866
- flowId: string;
867
- sessionRunId: string;
868
- flowUri: string;
869
- actor: FlowAgentActor;
870
- now?: () => number;
871
- }
872
- interface FlowAgentCommandResult {
873
- commandId: string;
874
- success: boolean;
875
- output?: Record<string, unknown>;
876
- confirmed?: boolean;
877
- completionState?: ActionExecutionCompletionState;
878
- status?: FlowAgentCommandStatus;
879
- error?: string;
880
- }
881
- interface FlowAgentExecutor {
882
- executeAction?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
883
- assignActor?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
884
- notifyActor?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
885
- validateExternalState?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
886
- archiveFlow?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
887
- proposeConfigChange?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
888
- diagnoseBlocker?: (command: FlowAgentCommand, context: FlowAgentContext) => Promise<FlowAgentCommandResult>;
889
- }
890
- interface FlowAgentTickResult {
891
- flowDone: boolean;
892
- snapshots: FlowAgentNodeSnapshot[];
893
- queuedCommands: FlowAgentCommand[];
894
- executedCommands: FlowAgentCommandResult[];
895
- }
896
-
897
- interface CreateAgentCommandParams {
898
- type: FlowAgentCommandType;
899
- flowId: string;
900
- sessionRunId: string;
901
- flowUri: string;
902
- nodeId: string;
903
- actor: FlowAgentActor;
904
- reason: string;
905
- payload?: Record<string, unknown>;
906
- now?: number;
907
- }
908
- declare function createAgentCommand({ type, flowId, sessionRunId, flowUri, nodeId, actor, reason, payload, now }: CreateAgentCommandParams): FlowAgentCommand;
909
- declare function validateAgentCommand(command: FlowAgentCommand): {
910
- valid: boolean;
911
- error?: string;
912
- };
913
- declare function isExternalMutation(type: FlowAgentCommandType): boolean;
914
-
915
- interface BuildFlowAgentContextParams {
916
- yDoc: Doc;
917
- flowId: string;
918
- sessionRunId: string;
919
- flowUri?: string;
920
- actor: FlowAgentActor;
921
- blocks?: unknown[];
922
- documentBlocks?: unknown[];
923
- editor?: IxoEditorType;
924
- now?: () => number;
925
- }
926
- /**
927
- * Builds the host-facing runtime context expected by the Flow Agent.
928
- *
929
- * Headless hosts own Matrix login, room joins, and Y.Doc sync. Once a host has
930
- * a live room document and an agent identity, this helper gives it the stable
931
- * context shape to pass into `tickFlowAgent` or `FlowAgentService`.
932
- */
933
- declare function buildFlowAgentContext({ yDoc, flowId, sessionRunId, flowUri, actor, blocks, documentBlocks, editor, now, }: BuildFlowAgentContextParams): FlowAgentContext;
934
-
935
- interface AcquireFlowAgentLeaseParams {
936
- leases: Map<FlowAgentLease>;
937
- commandId: string;
938
- sessionRunId: string;
939
- nodeId: string;
940
- actorDid: string;
941
- now?: number;
942
- ttlMs?: number;
943
- }
944
- declare function acquireFlowAgentLease({ leases, commandId, sessionRunId, nodeId, actorDid, now, ttlMs, }: AcquireFlowAgentLeaseParams): FlowAgentLease | null;
945
- declare function validateFlowAgentLease(leases: Map<FlowAgentLease>, lease: FlowAgentLease, now?: number): boolean;
946
- declare function releaseFlowAgentLease(leases: Map<FlowAgentLease>, lease: FlowAgentLease): boolean;
947
- declare function cleanupExpiredFlowAgentLeases(leases: Map<FlowAgentLease>, now?: number): FlowAgentLease[];
948
-
949
- declare function requiredCapabilityForCommand(type: FlowAgentCommandType, flowUri: string, nodeId: string): UcanCapability;
950
- declare function isCapabilityMatch(granted: UcanCapability, required: UcanCapability): boolean;
951
- /**
952
- * Match a granted capability pattern against a required `can`.
953
- *
954
- * ⚠️ This is the **trusted flow-agent policy** matcher: it allows the global
955
- * `'*'` wildcard, so a delegation granting `can: '*'` matches every ability.
956
- * It is re-exported from `src/core/index.ts` — do not use it to gate public or
957
- * untrusted matching. For that, call `capabilityPatternCoversCan` directly and
958
- * leave `allowGlobalWildcard` off (the default), which rejects `'*'`.
959
- *
960
- * Note: the granted side is normalized (`normalizeCan`), so dotted legacy
961
- * grants such as `flow.notify` / `flow.*` now match `flow/notify` where they
962
- * were previously inert.
963
- */
964
- declare function canMatches(granted: string, required: string): boolean;
965
- declare function resourceMatches(granted: string, required: string): boolean;
966
- interface EvaluateFlowAgentPolicyParams {
967
- actorDid: string;
968
- commandType: FlowAgentCommandType;
969
- flowUri: string;
970
- nodeId: string;
971
- delegationStore?: UcanDelegationStore;
972
- delegations?: StoredDelegation[];
973
- now?: number;
974
- }
975
- declare function evaluateFlowAgentPolicy({ actorDid, commandType, flowUri, nodeId, delegationStore, delegations, now, }: EvaluateFlowAgentPolicyParams): FlowAgentPolicyDecision;
976
-
977
- interface FlowAgentOrchestratorOptions {
978
- delegationStore?: UcanDelegationStore;
979
- delegations?: StoredDelegation[];
980
- candidateActors?: FlowAgentActor[];
981
- executor?: FlowAgentExecutor;
982
- leaseTtlMs?: number;
983
- archiveWhenDone?: boolean;
984
- }
985
- declare function planRalphLoopCommands(context: FlowAgentContext, options?: FlowAgentOrchestratorOptions): {
986
- snapshots: FlowAgentNodeSnapshot[];
987
- queuedCommands: FlowAgentCommand[];
988
- flowDone: boolean;
989
- };
990
- declare function executeQueuedAgentCommands(context: FlowAgentContext, options?: FlowAgentOrchestratorOptions): Promise<FlowAgentCommandResult[]>;
991
- declare function tickFlowAgent(context: FlowAgentContext, options?: FlowAgentOrchestratorOptions): Promise<FlowAgentTickResult>;
992
-
993
- interface FlowAgentServiceOptions extends FlowAgentOrchestratorOptions {
994
- intervalMs?: number;
995
- onTick?: (result: FlowAgentTickResult) => void | Promise<void>;
996
- onError?: (error: unknown) => void;
997
- }
998
- /**
999
- * Headless-service adapter boundary.
1000
- *
1001
- * Host applications own Matrix login, room joins, and Y.Doc sync. Once they
1002
- * have a live Y.Doc/editor snapshot, this service provides the deterministic
1003
- * Ralph-loop tick and command execution cycle.
1004
- */
1005
- declare class FlowAgentService {
1006
- private readonly context;
1007
- private readonly options;
1008
- private timer;
1009
- private running;
1010
- constructor(context: FlowAgentContext, options?: FlowAgentServiceOptions);
1011
- tick(): Promise<FlowAgentTickResult>;
1012
- start(): void;
1013
- stop(): void;
1014
- }
1015
-
1016
- declare function getFlowAgentMaps(yDoc: Doc): FlowAgentMaps;
1017
- declare function computeAgentCommandId(params: {
1018
- flowId: string;
1019
- sessionRunId: string;
1020
- nodeId: string;
1021
- type: string;
1022
- payload: Record<string, unknown>;
1023
- }): string;
1024
- declare function queueAgentCommand(yDoc: Doc, command: FlowAgentCommand): {
1025
- command: FlowAgentCommand;
1026
- created: boolean;
1027
- };
1028
- /** Read every command for one session without creating the outbox map. */
1029
- declare function readAgentCommands(yDoc: Doc, sessionRunId?: string): FlowAgentCommand[];
1030
- declare function readQueuedAgentCommands(yDoc: Doc, sessionRunId?: string): FlowAgentCommand[];
1031
- /** Read every lease for one session without creating the leases map. */
1032
- declare function readFlowAgentLeases(yDoc: Doc, sessionRunId?: string): FlowAgentLease[];
1033
- declare function updateAgentCommand(yDoc: Doc, commandId: string, patch: Partial<FlowAgentCommand>): FlowAgentCommand | null;
1034
- declare function appendAgentLedgerEvent(yDoc: Doc, event: Omit<FlowAgentLedgerEvent, 'id'> & {
1035
- id?: string;
1036
- }): FlowAgentLedgerEvent;
1037
- declare function readAgentLedgerEvents(yDoc: Doc, eventType?: FlowAgentLedgerEventType, sessionRunId?: string): FlowAgentLedgerEvent[];
1038
-
1039
- export { buildFlowAgentContext as $, type AuthorizationResult as A, readFlowConnectionBindings as B, upsertFlowConnectionBinding as C, removeFlowConnectionBinding as D, type ExecuteNodeParams as E, FLOW_PARTICIPANTS_MAP_KEY as F, FLOW_CONNECTIONS_MAP_KEY as G, FLOW_CONNECTION_BINDINGS_MAP_KEY as H, type SetupFlowResult as I, type ReadFlowResult as J, type ReadableEditor as K, type CompilerRegistry as L, type MergeResult as M, type NodeActionResult as N, type FlowParticipant as O, type FlowConnection as P, type FlowConnectionBinding as Q, type ReadFlowOptions as R, type SetupFlowOptions as S, type FlowConnectionRequirementKey as T, type BaseUcanFlow as U, type FlowCapability as V, type CompiledFlow as W, type FlowStrategy as X, FlowAgentService as Y, acquireFlowAgentLease as Z, appendAgentLedgerEvent as _, buildAuthzFromProps as a, type TriggerSpec as a$, cleanupExpiredFlowAgentLeases as a0, createAgentCommand as a1, evaluateFlowAgentPolicy as a2, executeQueuedAgentCommands as a3, getFlowAgentMaps as a4, planRalphLoopCommands as a5, queueAgentCommand as a6, readAgentLedgerEvents as a7, readQueuedAgentCommands as a8, releaseFlowAgentLease as a9, isCapabilityMatch as aA, isExternalMutation as aB, readAgentCommands as aC, readFlowAgentLeases as aD, requiredCapabilityForCommand as aE, resourceMatches as aF, updateAgentCommand as aG, type AcquireFlowAgentLeaseParams as aH, type CreateAgentCommandParams as aI, type EvaluateFlowAgentPolicyParams as aJ, type FlowAgentOrchestratorOptions as aK, type FlowAgentServiceOptions as aL, type FlowAgentCommandBase as aM, type FlowAgentCommandStatus as aN, type FlowAgentCommandType as aO, type FlowAgentLedgerEvent as aP, type FlowAgentLedgerEventType as aQ, type FlowAgentMaps as aR, type FlowAgentPolicyDecision as aS, type FlowAgentRunPhase as aT, resolveRuntimeRefs as aU, type TriggerResolutionContext as aV, type ConditionRef as aW, type ActorConstraint as aX, type TTLConstraint as aY, type RuntimeRef as aZ, type CompiledFlowNode as a_, tickFlowAgent as aa, validateAgentCommand as ab, validateFlowAgentLease as ac, type BuildFlowAgentContextParams as ad, type FlowAgentActor as ae, type FlowAgentCommand as af, type FlowAgentCommandResult as ag, type FlowAgentContext as ah, type FlowAgentExecutor as ai, type FlowAgentLease as aj, type FlowAgentNodeSnapshot as ak, type FlowAgentPublicNodeState as al, type FlowAgentTickResult as am, type CompiledBlock as an, type CompiledEdge as ao, type FlowAgentBlockerCause as ap, buildActionRunInputs as aq, executeActionBlock as ar, type ActionBlockLike as as, type ActionExecutionCompletionState as at, type BuildActionRunInputsParams as au, type BuildActionRunInputsResult as av, type ExecuteActionBlockParams as aw, type ExecuteActionBlockResult as ax, canMatches as ay, computeAgentCommandId as az, buildFlowNodeFromBlock as b, isRuntimeRef as b0, type ExecutionOutcome as c, type ExecutionContext as d, executeNode as e, readFlowFromEditor as f, readFlow as g, setActiveEditor as h, isAuthorized as i, getActiveEditor as j, compileBaseUcanFlow as k, readCompiledFlowFromYDoc as l, mergeCompiledFlows as m, decompileToBaseUcanFlow as n, readFlowParticipants as o, removeFlowParticipant as p, setFlowParticipantPowerLevel as q, readFlowAsBaseUcan as r, setupFlowFromBaseUcan as s, setFlowParticipantRequirements as t, upsertFlowParticipant as u, readFlowConnections as v, upsertFlowConnection as w, removeFlowConnection as x, setFlowConnectionOptional as y, setFlowConnectionRequires as z };
1056
+ export { readCompiledFlowFromYDoc as $, type AuthorizationResult as A, type BaseUcanFlow as B, type CompiledFlow as C, appendAgentLedgerEvent as D, type ExecuteNodeParams as E, FLOW_CONNECTIONS_MAP_KEY as F, buildAuthzFromProps as G, buildFlowAgentContext as H, buildFlowNodeFromBlock as I, cleanupExpiredFlowAgentLeases as J, compileBaseUcanFlow as K, createAgentCommand as L, type MergeResult as M, type NodeActionResult as N, decompileToBaseUcanFlow as O, evaluateFlowAgentPolicy as P, executeNode as Q, type ReadFlowOptions as R, type SetupFlowOptions as S, executeQueuedAgentCommands as T, getActiveEditor as U, getFlowAgentMaps as V, isAuthorized as W, mergeCompiledFlows as X, planRalphLoopCommands as Y, queueAgentCommand as Z, readAgentLedgerEvents as _, type BuildFlowAgentContextParams as a, resourceMatches as a$, readFlow as a0, readFlowAsBaseUcan as a1, readFlowConnectionBindings as a2, readFlowConnections as a3, readFlowFromEditor as a4, readFlowParticipants as a5, readQueuedAgentCommands as a6, releaseFlowAgentLease as a7, removeFlowConnection as a8, removeFlowConnectionBinding as a9, type ExecuteActionBlockParams as aA, type ExecuteActionBlockResult as aB, type FlowAgentCommandBase as aC, type FlowAgentCommandStatus as aD, type FlowAgentCommandType as aE, type FlowAgentLedgerEvent as aF, type FlowAgentLedgerEventType as aG, type FlowAgentMaps as aH, type FlowAgentOrchestratorOptions as aI, type FlowAgentPolicyDecision as aJ, type FlowAgentRunPhase as aK, type FlowAgentServiceOptions as aL, type RuntimeRef as aM, type TTLConstraint as aN, type TriggerResolutionContext as aO, type TriggerSpec as aP, buildActionRunInputs as aQ, canMatches as aR, computeAgentCommandId as aS, executeActionBlock as aT, isCapabilityMatch as aU, isExternalMutation as aV, isRuntimeRef as aW, readAgentCommands as aX, readFlowAgentLeases as aY, requiredCapabilityForCommand as aZ, resolveRuntimeRefs as a_, removeFlowParticipant as aa, setActiveEditor as ab, setFlowConnectionOptional as ac, setFlowConnectionRequires as ad, setFlowParticipantPowerLevel as ae, setFlowParticipantRequirements as af, setupFlowFromBaseUcan as ag, tickFlowAgent as ah, upsertFlowConnection as ai, upsertFlowConnectionBinding as aj, upsertFlowParticipant as ak, validateAgentCommand as al, validateFlowAgentLease as am, type FlowAgentBlockerCause as an, type CompiledBlock as ao, type CompiledEdge as ap, type AcquireFlowAgentLeaseParams as aq, type ActionBlockLike as ar, type ActionExecutionCompletionState as as, type ActorConstraint as at, type BuildActionRunInputsParams as au, type BuildActionRunInputsResult as av, type CompiledFlowNode as aw, type ConditionRef as ax, type CreateAgentCommandParams as ay, type EvaluateFlowAgentPolicyParams as az, type CompilerRegistry as b, updateAgentCommand as b0, type ExecutionContext as c, type ExecutionOutcome as d, FLOW_CONNECTION_BINDINGS_MAP_KEY as e, FLOW_PARTICIPANTS_MAP_KEY as f, type FlowAgentActor as g, type FlowAgentCommand as h, type FlowAgentCommandResult as i, type FlowAgentContext as j, type FlowAgentExecutor as k, type FlowAgentLease as l, type FlowAgentNodeSnapshot as m, type FlowAgentPublicNodeState as n, FlowAgentService as o, type FlowAgentTickResult as p, type FlowCapability as q, type FlowConnection as r, type FlowConnectionBinding as s, type FlowConnectionRequirementKey as t, type FlowParticipant as u, type FlowStrategy as v, type ReadFlowResult as w, type ReadableEditor as x, type SetupFlowResult as y, acquireFlowAgentLease as z };