@ixo/editor 3.6.0 → 3.8.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,6 +1,6 @@
1
- import { n as ActionDefinition, o as ActionServices } from '../setup-mrrJlbcA.mjs';
2
- export { q as ActionContext, r as ActionResult, h as ActivationResult, u as ActorConstraint, A as AuthorizationResult, B as BaseUcanFlow, v as CompiledBlock, w as CompiledEdge, m as CompiledFlow, x as CompiledFlowNode, C as CompilerRegistry, t as ConditionRef, E as ExecuteNodeParams, g as ExecutionContext, f as ExecutionOutcome, l as FlowCapability, F as FlowRuntimeStateManager, N as NodeActionResult, O as OutputSchemaField, R as RuntimeRef, S as SetupFlowOptions, k as SetupFlowResult, T as TTLConstraint, d as buildAuthzFromProps, b as buildFlowNodeFromBlock, p as clearRuntimeForTemplateClone, j as compileBaseUcanFlow, c as createRuntimeStateManager, e as executeNode, i as isAuthorized, a as isNodeActive, y as isRuntimeRef, s as setupFlowFromBaseUcan } from '../setup-mrrJlbcA.mjs';
3
- export { A as ActivationCondition, C as ClaimCollectionURI, G as CreateDelegationParams, H as CreateInvocationParams, B as CreateRootDelegationParams, s as DID, D as DelegationChainValidationResult, k as DelegationGrant, E as EvaluationStatus, y as ExecutionWithInvocationResult, z as FindProofsResult, v as FlowNode, F as FlowNodeAuthzExtension, u as FlowNodeBase, t as FlowNodeRuntimeState, w as InvocationRequest, x as InvocationResult, I as InvocationStore, L as LinkedClaim, N as NodeState, S as StoredDelegation, j as StoredInvocation, i as UcanCapability, U as UcanDelegationStore, f as UcanService, g as UcanServiceConfig, h as UcanServiceHandlers, b as createInvocationStore, d as createMemoryInvocationStore, a as createMemoryUcanDelegationStore, c as createUcanDelegationStore, e as createUcanService } from '../index-MLwb3a2P.mjs';
1
+ import { x as ActionDefinition, y as ActionServices } from '../decompile-BroSNv1q.mjs';
2
+ export { D as ActionContext, G as ActionResult, I as ActorConstraint, A as AuthorizationResult, B as BaseUcanFlow, K as CompiledBlock, L as CompiledEdge, v as CompiledFlow, P as CompiledFlowNode, C as CompilerRegistry, H as ConditionRef, E as ExecuteNodeParams, f as ExecutionContext, d as ExecutionOutcome, u as FlowCapability, F as FlowRuntimeStateManager, w as FlowStrategy, M as MergeResult, N as NodeActionResult, O as OutputSchemaField, R as ReadFlowOptions, q as ReadFlowResult, J as RuntimeRef, S as SetupFlowOptions, p as SetupFlowResult, T as TTLConstraint, a as buildAuthzFromProps, b as buildFlowNodeFromBlock, z as clearRuntimeForTemplateClone, l as compileBaseUcanFlow, c as createRuntimeStateManager, o as decompileToBaseUcanFlow, e as executeNode, k as getActiveEditor, i as isAuthorized, Q as isRuntimeRef, n as mergeCompiledFlows, m as readCompiledFlowFromYDoc, h as readFlow, r as readFlowAsBaseUcan, g as readFlowFromEditor, j as setActiveEditor, s as setupFlowFromBaseUcan } from '../decompile-BroSNv1q.mjs';
3
+ export { C as ClaimCollectionURI, B as CreateDelegationParams, G as CreateInvocationParams, A as CreateRootDelegationParams, s as DID, D as DelegationChainValidationResult, k as DelegationGrant, E as EvaluationStatus, y as ExecutionWithInvocationResult, z as FindProofsResult, v as FlowNode, F as FlowNodeAuthzExtension, u as FlowNodeBase, t as FlowNodeRuntimeState, w as InvocationRequest, x as InvocationResult, I as InvocationStore, L as LinkedClaim, N as NodeState, S as StoredDelegation, j as StoredInvocation, i as UcanCapability, U as UcanDelegationStore, f as UcanService, g as UcanServiceConfig, h as UcanServiceHandlers, b as createInvocationStore, d as createMemoryInvocationStore, a as createMemoryUcanDelegationStore, c as createUcanDelegationStore, e as createUcanService } from '../index-BEoftwDZ.mjs';
4
4
  import 'yjs';
5
5
  import 'matrix-js-sdk';
6
6
  import '@blocknote/core';
@@ -37,6 +37,21 @@ declare function getAllCanMappings(): ReadonlyArray<{
37
37
  */
38
38
  declare function buildServicesFromHandlers(handlers: any): ActionServices;
39
39
 
40
+ /**
41
+ * Context passed to resolveRuntimeRefs when resolving inputs for a triggered
42
+ * listener block. The runtime constructs this from a PendingInvocation when
43
+ * the assignee invokes the listener.
44
+ *
45
+ * - `payload`: the frozen event payload, used to resolve `trigger.payload.*` refs
46
+ * - `refSnapshots`: frozen `nodeId.output.*` values captured at queue time,
47
+ * used to resolve those refs against the moment of emission rather than
48
+ * current state. See docs/events-and-triggers-plan.md §3.5.1 for the
49
+ * Sally → Mike scenario this fixes.
50
+ */
51
+ interface TriggerResolutionContext {
52
+ payload: Record<string, unknown>;
53
+ refSnapshots: Record<string, unknown>;
54
+ }
40
55
  /**
41
56
  * Resolve runtime references in an nb (caveats) object.
42
57
  *
@@ -44,11 +59,24 @@ declare function buildServicesFromHandlers(handlers: any): ActionServices;
44
59
  * as-is into the block's `inputs` JSON string. At execution time, this function
45
60
  * replaces them with actual output values from upstream nodes.
46
61
  *
62
+ * Two ref namespaces are supported:
63
+ * - `nodeId.output.fieldPath` — looked up via `getNodeOutput`. When a
64
+ * `triggerContext` is provided AND `refSnapshots[ref]` exists, the
65
+ * snapshot is preferred over the live lookup. This is the load-bearing
66
+ * fix for the lag-time scenario where multiple pending invocations are
67
+ * queued and the source block re-runs before the assignee acts on them.
68
+ * - `trigger.payload.fieldPath` — looked up in `triggerContext.payload`.
69
+ * Only valid when `triggerContext` is provided (i.e. resolving inputs
70
+ * for a triggered listener invocation). Compile-time validation in
71
+ * compiler.ts guarantees these only appear on `block.event`-triggered
72
+ * blocks.
73
+ *
47
74
  * @param nb - The caveats object (may contain nested RuntimeRef values)
48
75
  * @param getNodeOutput - Lookup function for upstream node outputs
76
+ * @param triggerContext - Optional, present only for triggered listener invocations
49
77
  * @returns A new object with all $ref values resolved
50
78
  */
51
- declare function resolveRuntimeRefs(nb: Record<string, unknown>, getNodeOutput: (nodeId: string) => Record<string, unknown> | undefined): Record<string, unknown>;
79
+ declare function resolveRuntimeRefs(nb: Record<string, unknown>, getNodeOutput: (nodeId: string) => Record<string, unknown> | undefined, triggerContext?: TriggerResolutionContext): Record<string, unknown>;
52
80
 
53
81
  /**
54
82
  * Compute an IPFS-compatible CID for arbitrary content.
@@ -1,32 +1,39 @@
1
1
  import {
2
- compileBaseUcanFlow,
3
- isRuntimeRef,
4
- resolveRuntimeRefs,
5
- setupFlowFromBaseUcan
6
- } from "../chunk-VG4NLEZB.mjs";
2
+ resolveRuntimeRefs
3
+ } from "../chunk-FXFKKA6L.mjs";
7
4
  import {
8
5
  buildAuthzFromProps,
9
6
  buildFlowNodeFromBlock,
10
7
  buildServicesFromHandlers,
11
8
  canToType,
12
9
  clearRuntimeForTemplateClone,
10
+ compileBaseUcanFlow,
13
11
  createInvocationStore,
14
12
  createMemoryInvocationStore,
15
13
  createMemoryUcanDelegationStore,
16
14
  createRuntimeStateManager,
17
15
  createUcanDelegationStore,
18
16
  createUcanService,
17
+ decompileToBaseUcanFlow,
19
18
  executeNode,
20
19
  getAction,
21
20
  getActionByCan,
21
+ getActiveEditor,
22
22
  getAllActions,
23
23
  getAllCanMappings,
24
24
  hasAction,
25
25
  isAuthorized,
26
- isNodeActive,
26
+ isRuntimeRef,
27
+ mergeCompiledFlows,
28
+ readCompiledFlowFromYDoc,
29
+ readFlow,
30
+ readFlowAsBaseUcan,
31
+ readFlowFromEditor,
27
32
  registerAction,
33
+ setActiveEditor,
34
+ setupFlowFromBaseUcan,
28
35
  typeToCan
29
- } from "../chunk-UBCN5SXM.mjs";
36
+ } from "../chunk-QIJA3CMG.mjs";
30
37
  import {
31
38
  computeCID,
32
39
  computeJsonCID
@@ -46,17 +53,24 @@ export {
46
53
  createRuntimeStateManager,
47
54
  createUcanDelegationStore,
48
55
  createUcanService,
56
+ decompileToBaseUcanFlow,
49
57
  executeNode,
50
58
  getAction,
51
59
  getActionByCan,
60
+ getActiveEditor,
52
61
  getAllActions,
53
62
  getAllCanMappings,
54
63
  hasAction,
55
64
  isAuthorized,
56
- isNodeActive,
57
65
  isRuntimeRef,
66
+ mergeCompiledFlows,
67
+ readCompiledFlowFromYDoc,
68
+ readFlow,
69
+ readFlowAsBaseUcan,
70
+ readFlowFromEditor,
58
71
  registerAction,
59
72
  resolveRuntimeRefs,
73
+ setActiveEditor,
60
74
  setupFlowFromBaseUcan,
61
75
  typeToCan
62
76
  };
@@ -1,4 +1,5 @@
1
- import { v as FlowNode, F as FlowNodeAuthzExtension, t as FlowNodeRuntimeState, J as IxoEditorType, f as UcanService, I as InvocationStore, E as EvaluationStatus } from './index-MLwb3a2P.mjs';
1
+ import { v as FlowNode, F as FlowNodeAuthzExtension, t as FlowNodeRuntimeState, H as IxoEditorType, f as UcanService, I as InvocationStore, E as EvaluationStatus } from './index-BEoftwDZ.mjs';
2
+ import * as Y from 'yjs';
2
3
  import { Doc } from 'yjs';
3
4
  import { MatrixClient } from 'matrix-js-sdk';
4
5
 
@@ -43,7 +44,7 @@ interface TTLConstraint {
43
44
  * nb = typed caveats, inputs, parameters
44
45
  *
45
46
  * Workflow semantics (kept separate from nb):
46
- * dependsOn, condition, parallelGroup, phase
47
+ * condition, trigger, parallelGroup, phase
47
48
  */
48
49
  interface FlowCapability {
49
50
  /** Stable node identifier for this step. */
@@ -54,8 +55,6 @@ interface FlowCapability {
54
55
  with: string;
55
56
  /** Typed caveats / input parameters. Shape is dictated by the action registry. */
56
57
  nb?: Record<string, unknown>;
57
- /** IDs of upstream capabilities this depends on. */
58
- dependsOn?: string[];
59
58
  /** Condition that must be met for this capability to activate. */
60
59
  condition?: ConditionRef;
61
60
  /** Capabilities sharing a parallelGroup run concurrently. */
@@ -66,6 +65,20 @@ interface FlowCapability {
66
65
  actor?: ActorConstraint;
67
66
  /** Time-to-live constraints. */
68
67
  ttl?: TTLConstraint;
68
+ /**
69
+ * When and how this block fires. Defaults to `{ type: 'manual' }` if absent
70
+ * (i.e. block runs only when a user explicitly invokes it).
71
+ *
72
+ * `block.event` triggers turn this block into a listener: when the source
73
+ * block emits an event matching `eventName`, a pending invocation is
74
+ * queued on this block and the assigned actor is DM'd to invoke it. See
75
+ * `docs/events-and-triggers-plan.md` §3.7 and §18 for the full model.
76
+ *
77
+ * Triggers are a NEW sibling field on FlowCapability (decided in eng review
78
+ * pass 2 phase 0 #1). They are NOT an extension of `condition`. The decompile
79
+ * branch's author needs to add `props.trigger` parsing when their work merges.
80
+ */
81
+ trigger?: TriggerSpec;
69
82
  /** Display title (falls back to can statement). */
70
83
  title?: string;
71
84
  /** Description of what this step does. */
@@ -73,6 +86,21 @@ interface FlowCapability {
73
86
  /** Icon identifier. */
74
87
  icon?: string;
75
88
  }
89
+ /**
90
+ * Trigger declaration for a block. When and how it fires.
91
+ */
92
+ interface TriggerSpec {
93
+ /**
94
+ * - `manual`: block runs only when a user explicitly invokes it (default).
95
+ * - `flow.start`: block runs when the flow execution begins.
96
+ * - `block.event`: block runs each time another block emits a matching event.
97
+ */
98
+ type: 'manual' | 'flow.start' | 'block.event';
99
+ /** Required when `type === 'block.event'`. ID of the block that emits the event. */
100
+ sourceBlockId?: string;
101
+ /** Required when `type === 'block.event'`. Name of the event (must match an event declared on the source action's `events` vocabulary). */
102
+ eventName?: string;
103
+ }
76
104
  /**
77
105
  * The Base UCAN flow plan — the intermediate representation between
78
106
  * user intent and the compiled flow graph.
@@ -107,12 +135,16 @@ interface CompiledBlock {
107
135
  /** Block props — all values are strings per BlockNote convention. */
108
136
  props: Record<string, string>;
109
137
  }
110
- /** A dependency edge in the flow graph. */
138
+ /**
139
+ * An edge in the flow graph. Currently only `kind: 'trigger'` edges are
140
+ * synthesized — they come from `block.event` triggers and represent the
141
+ * source → listener relationship visually on the canvas.
142
+ */
111
143
  interface CompiledEdge {
112
144
  id: string;
113
145
  source: string;
114
146
  target: string;
115
- kind: 'dependency';
147
+ kind: 'trigger';
116
148
  condition?: ConditionRef;
117
149
  }
118
150
  /** A compiled flow node stored in qi.flow.nodes. */
@@ -125,7 +157,6 @@ interface CompiledFlowNode {
125
157
  title: string;
126
158
  description: string;
127
159
  props: Record<string, string>;
128
- dependsOn: string[];
129
160
  phase?: string;
130
161
  parallelGroup?: string;
131
162
  actor?: ActorConstraint;
@@ -154,6 +185,8 @@ interface CompiledFlow {
154
185
  /** nodeId → blockId mapping. */
155
186
  blockIndex: Record<string, string>;
156
187
  }
188
+ /** Strategy for how a compiled flow is applied to an existing document. */
189
+ type FlowStrategy = 'full' | 'merge' | 'patch';
157
190
 
158
191
  declare const buildAuthzFromProps: (props: Record<string, any>) => FlowNodeAuthzExtension;
159
192
  declare const buildFlowNodeFromBlock: (block: any) => FlowNode;
@@ -164,9 +197,13 @@ interface FlowRuntimeStateManager {
164
197
  }
165
198
  declare const createRuntimeStateManager: (editor?: IxoEditorType | null) => FlowRuntimeStateManager;
166
199
  /**
167
- * Clears runtime and invocations from a Y.Doc.
200
+ * Clears runtime, invocations, and pending invocations from a Y.Doc.
168
201
  * Used when cloning a flow as a template — the new document should
169
202
  * carry only configuration (intent), not execution history.
203
+ *
204
+ * The audit trail (which now also holds run records as `type: 'block.run'`
205
+ * entries) and pending invocations are observation, not configuration —
206
+ * both are cleared on template clone.
170
207
  */
171
208
  declare function clearRuntimeForTemplateClone(yDoc: Doc): void;
172
209
 
@@ -191,7 +228,7 @@ interface ExecutionContext {
191
228
  }
192
229
  interface ExecutionOutcome {
193
230
  success: boolean;
194
- stage: 'activation' | 'authorization' | 'claim' | 'action' | 'complete';
231
+ stage: 'authorization' | 'claim' | 'action' | 'complete';
195
232
  error?: string;
196
233
  result?: NodeActionResult;
197
234
  capabilityId?: string;
@@ -235,12 +272,6 @@ interface AuthorizationResult {
235
272
  */
236
273
  declare const isAuthorized: (blockId: string, actorDid: string, ucanService: UcanService | undefined, flowUri: string, schemaVersion?: string) => Promise<AuthorizationResult>;
237
274
 
238
- interface ActivationResult {
239
- active: boolean;
240
- reason?: string;
241
- }
242
- declare const isNodeActive: (node: FlowNode, runtime: FlowRuntimeStateManager) => ActivationResult;
243
-
244
275
  interface ActionContext {
245
276
  actorDid: string;
246
277
  flowId: string;
@@ -386,6 +417,30 @@ interface OutputSchemaField {
386
417
  type: 'string' | 'number' | 'boolean' | 'object' | 'array';
387
418
  description?: string;
388
419
  }
420
+ /**
421
+ * A typed event that an action can emit when it runs.
422
+ *
423
+ * Events drive the trigger/listener model: another block can declare a
424
+ * `block.event` trigger on a (sourceBlockId, eventName) pair, and when this
425
+ * action emits a matching event, a pending invocation is queued on the
426
+ * listener block. See `docs/events-and-triggers-plan.md` for the full model.
427
+ */
428
+ interface ActionEventDefinition {
429
+ /** Stable identifier — used in trigger declarations and ref strings. */
430
+ name: string;
431
+ /** Human-readable label shown in the trigger picker UI. */
432
+ displayName: string;
433
+ /** Short description shown as inline hint in the trigger picker. */
434
+ description: string;
435
+ /** Schema of the event payload. Same shape as `outputSchema`. */
436
+ payloadSchema: OutputSchemaField[];
437
+ /**
438
+ * Field paths from `payloadSchema` (in order) shown inline in the
439
+ * pending-invocation list so the assignee can distinguish queued
440
+ * invocations at a glance. E.g. `['claimId', 'evaluatedAt']`.
441
+ */
442
+ pendingDisplayFields?: string[];
443
+ }
389
444
  interface ActionDefinition<TInputs extends Record<string, any> = Record<string, any>> {
390
445
  type: string;
391
446
  /** UCAN-style ability string used by the flow compiler, e.g., "bid/submit". */
@@ -397,10 +452,39 @@ interface ActionDefinition<TInputs extends Record<string, any> = Record<string,
397
452
  /** Static output schema for action types with predictable output (e.g. email.send).
398
453
  * For action types with dynamic output (e.g. http.request), the schema is user-defined in inputs. */
399
454
  outputSchema?: OutputSchemaField[];
455
+ /**
456
+ * Typed vocabulary of events this action can emit. Drives the trigger
457
+ * picker UI and compile-time validation of `block.event` triggers.
458
+ */
459
+ events?: ActionEventDefinition[];
460
+ /**
461
+ * Whether this action can be wired to a `block.event` trigger.
462
+ * False (the default) for user-interaction-driven actions like forms,
463
+ * claims, and evaluations — they always run as `manual`. True for actions
464
+ * where it makes sense for an event to nudge a human assignee to invoke
465
+ * them (email, http, notify).
466
+ *
467
+ * The trigger picker UI is hidden for blocks whose action type has this
468
+ * set to false.
469
+ */
470
+ eligibleForEventTrigger?: boolean;
400
471
  run: (inputs: TInputs, ctx: ActionContext) => Promise<ActionResult>;
401
472
  }
473
+ /**
474
+ * Result returned by an action's `run()` function.
475
+ *
476
+ * The optional `events` array is the explicit emission surface — actions
477
+ * declare which named events they're emitting on this particular run, with
478
+ * the payload by value. The runtime persists these as part of the run record
479
+ * and the reconciliation loop turns them into pending invocations on
480
+ * subscribed listener blocks.
481
+ */
402
482
  interface ActionResult {
403
483
  output: Record<string, any>;
484
+ events?: Array<{
485
+ name: string;
486
+ payload: Record<string, any>;
487
+ }>;
404
488
  }
405
489
 
406
490
  /** Registry interface expected by the compiler (keeps it pure / testable). */
@@ -415,6 +499,36 @@ interface CompilerRegistry {
415
499
  */
416
500
  declare function compileBaseUcanFlow(plan: BaseUcanFlow, registry: CompilerRegistry): CompiledFlow;
417
501
 
502
+ /** Describes what changed when merging two compiled flows. */
503
+ interface MergeResult {
504
+ /** The merged compiled flow (full state). */
505
+ merged: CompiledFlow;
506
+ /** Node IDs that were added (new in incoming, not in existing). */
507
+ added: string[];
508
+ /** Node IDs that were replaced (patch only — existed and was overwritten). */
509
+ replaced: string[];
510
+ /** Node IDs that were kept unchanged from existing. */
511
+ kept: string[];
512
+ }
513
+ /**
514
+ * Merge an incoming compiled flow into an existing one.
515
+ *
516
+ * This is a **pure function** — no Yjs, no side effects.
517
+ *
518
+ * Strategies:
519
+ * - `merge`: existing nodes win on ID collision. Incoming nodes with new IDs
520
+ * are added. Existing nodes are never modified.
521
+ * - `patch`: incoming nodes overwrite existing nodes on ID collision. Incoming
522
+ * nodes with new IDs are added. Existing nodes not in incoming are kept.
523
+ *
524
+ * Edges in the merged result are the union of edges from both sides, filtered
525
+ * to those whose source and target both exist in the merged node set, with
526
+ * duplicates collapsed by edge id. Order is the merged node insertion order
527
+ * (existing first, then newly added) — there is no topological sort because
528
+ * there is no inferred dependency relationship.
529
+ */
530
+ declare function mergeCompiledFlows(existing: CompiledFlow, incoming: CompiledFlow, strategy: 'merge' | 'patch'): MergeResult;
531
+
418
532
  interface SetupFlowOptions {
419
533
  /** The Base UCAN flow plan to compile. */
420
534
  plan: BaseUcanFlow;
@@ -426,6 +540,13 @@ interface SetupFlowOptions {
426
540
  creatorDid: string;
427
541
  /** Optional doc ID override (defaults to plan.flowId). */
428
542
  docId?: string;
543
+ /**
544
+ * How to apply the plan to the existing document.
545
+ * - `full` (default): wipe existing flow state and rebuild entirely.
546
+ * - `merge`: keep existing blocks, add new capabilities from the plan.
547
+ * - `patch`: replace matching nodes, add new ones, keep the rest.
548
+ */
549
+ strategy?: FlowStrategy;
429
550
  }
430
551
  interface SetupFlowResult {
431
552
  /** The compiled flow artifacts. */
@@ -435,24 +556,133 @@ interface SetupFlowResult {
435
556
  /** The flow ID from the plan. */
436
557
  flowId: string;
437
558
  }
559
+ interface ReadFlowOptions {
560
+ /** Matrix room ID to read from. */
561
+ roomId: string;
562
+ /** Authenticated Matrix client. */
563
+ matrixClient: MatrixClient;
564
+ }
565
+ interface ReadFlowResult {
566
+ /** The current flow plan in BaseUcanFlow format (what the agent reads/writes). */
567
+ plan: BaseUcanFlow;
568
+ /** The compiled flow state (lower-level representation). */
569
+ compiled: CompiledFlow;
570
+ /** The room ID (same as input, for convenience). */
571
+ roomId: string;
572
+ }
573
+ /**
574
+ * Read the current Base UCAN flow plan from a Matrix room.
575
+ *
576
+ * Connects to the room, reads the Y.Doc, decompiles the flow state
577
+ * back into a `BaseUcanFlow`, and disconnects. Returns `null` if the
578
+ * room has no flow state.
579
+ *
580
+ * **This is the lower-level API.** It exists for cases where you need
581
+ * to read a flow from a room you are NOT currently editing — e.g.
582
+ * cross-room operations or background reads. For the common case of
583
+ * "read the flow the user is currently looking at," use
584
+ * `readFlowFromEditor(editor)` instead. That function takes no
585
+ * parameters from the agent and reads from the editor's existing
586
+ * Y.Doc directly — no Matrix connection, no async, no room ID
587
+ * resolution. The browser tool that exposes `read_flow` to the AI
588
+ * agent should wrap `readFlowFromEditor`, not this function.
589
+ */
590
+ declare function readFlowAsBaseUcan(options: ReadFlowOptions): Promise<ReadFlowResult | null>;
591
+ /**
592
+ * Minimal editor shape required by `readFlowFromEditor` and the active
593
+ * editor registry. The full `IxoEditorType` is fine to pass — this is
594
+ * just a structural lower bound so test harnesses can construct fake
595
+ * editors without pulling in React dependencies.
596
+ */
597
+ interface ReadableEditor {
598
+ _yDoc?: Y.Doc;
599
+ getRoomId?: () => string;
600
+ }
601
+ /**
602
+ * Read the current flow from a specific editor instance, synchronously.
603
+ *
604
+ * Use this when you have an editor reference in hand (e.g. from inside a
605
+ * React component, a test, or a multi-editor host that needs to target a
606
+ * specific instance). For the common case of "read the flow the user is
607
+ * currently looking at," prefer the parameterless `readFlow()` below — it
608
+ * uses the active editor registry so you don't have to thread an editor
609
+ * reference through your call sites.
610
+ *
611
+ * Returns `null` ONLY when the editor's Y.Doc has no flow state at all
612
+ * (no nodes AND no meta). An empty `flowId` string is no longer treated
613
+ * as "no flow" — that was the historical bug where successful
614
+ * `setup_flow` calls authored with `flowId: ""` (the documented agent
615
+ * convention) showed up as null on subsequent reads.
616
+ */
617
+ declare function readFlowFromEditor(editor: ReadableEditor): ReadFlowResult | null;
618
+ /**
619
+ * Register an editor as the current active editor. Called by the editor's
620
+ * mount hook when the document is connected and ready. Pass `null` on
621
+ * unmount to clear the registry.
622
+ *
623
+ * If a different editor is already registered, it is replaced silently —
624
+ * the most recent registration wins. This matches the single-editor
625
+ * assumption above.
626
+ */
627
+ declare function setActiveEditor(editor: ReadableEditor | null): void;
628
+ /**
629
+ * Get the currently registered active editor, or null if none is set.
630
+ * Provided for cases where a caller wants to check the registry directly
631
+ * (e.g. for diagnostics) without going through `readFlow()`.
632
+ */
633
+ declare function getActiveEditor(): ReadableEditor | null;
634
+ /**
635
+ * Read the current flow from the active editor, with no parameters at all.
636
+ *
637
+ * This is the parameterless API the AI agent's `read_flow` browser tool
638
+ * should wrap. The browser tool literally becomes `read_flow: () => readFlow()`.
639
+ *
640
+ * Returns `null` if there is no active editor registered (e.g. the editor
641
+ * hasn't finished mounting yet, or no editor is open in this JS context),
642
+ * OR if the active editor's Y.Doc has no flow state at all.
643
+ *
644
+ * If `null` is returned and the user is referencing an existing flow, that
645
+ * is a hard signal to STOP and report to the user — never silently rebuild,
646
+ * because the duplicate-blocks bug is the inevitable consequence.
647
+ */
648
+ declare function readFlow(): ReadFlowResult | null;
438
649
  /**
439
650
  * One-shot function that compiles a Base UCAN flow plan and writes it
440
651
  * into a Matrix room's Y.Doc. After this completes, the room is a
441
652
  * normal flow that anyone can open via `useCreateCollaborativeIxoEditor`.
442
653
  *
443
- * Usage:
444
- * ```ts
445
- * const result = await setupFlowFromBaseUcan({
446
- * plan: myBaseUcanFlow,
447
- * roomId: '!abc:matrix.org',
448
- * matrixClient,
449
- * creatorDid: 'did:ixo:abc123',
450
- * });
451
- *
452
- * // Now open the flow through normal channels:
453
- * // useCreateCollaborativeIxoEditor({ roomId: result.roomId, ... })
454
- * ```
654
+ * Supports three strategies:
655
+ * - `full` (default): clears any existing flow and rebuilds from scratch.
656
+ * - `merge`: adds new capabilities alongside existing ones.
657
+ * - `patch`: replaces matching nodes and adds new ones.
455
658
  */
456
659
  declare function setupFlowFromBaseUcan(options: SetupFlowOptions): Promise<SetupFlowResult>;
457
660
 
458
- export { type AuthorizationResult as A, type BaseUcanFlow as B, type CompilerRegistry as C, type ExecuteNodeParams as E, type FlowRuntimeStateManager as F, type NodeActionResult as N, type OutputSchemaField as O, type RuntimeRef as R, type SetupFlowOptions as S, type TTLConstraint as T, isNodeActive as a, buildFlowNodeFromBlock as b, createRuntimeStateManager as c, buildAuthzFromProps as d, executeNode as e, type ExecutionOutcome as f, type ExecutionContext as g, type ActivationResult as h, isAuthorized as i, compileBaseUcanFlow as j, type SetupFlowResult as k, type FlowCapability as l, type CompiledFlow as m, type ActionDefinition as n, type ActionServices as o, clearRuntimeForTemplateClone as p, type ActionContext as q, type ActionResult as r, setupFlowFromBaseUcan as s, type ConditionRef as t, type ActorConstraint as u, type CompiledBlock as v, type CompiledEdge as w, type CompiledFlowNode as x, isRuntimeRef as y };
661
+ /**
662
+ * Read the current compiled flow state from a live Y.Doc.
663
+ *
664
+ * This is the inverse of `hydrateYDocFromCompiledFlow`. It extracts the flow
665
+ * graph state from Yjs maps so that the pure merge/patch logic can operate
666
+ * on plain objects.
667
+ *
668
+ * Returns `null` if the document has no flow state.
669
+ */
670
+ declare function readCompiledFlowFromYDoc(yDoc: Doc): CompiledFlow | null;
671
+
672
+ /**
673
+ * Reconstruct a BaseUcanFlow plan from a CompiledFlow.
674
+ *
675
+ * This is the inverse of `compileBaseUcanFlow`. It allows the AI agent to
676
+ * read the current flow in the same format it writes — a plain capability
677
+ * list it can reason about, modify, and pass back to the compiler.
678
+ *
679
+ * This is a **pure function** — no Yjs, no side effects.
680
+ *
681
+ * Note: some information is lossy (e.g. conditions are stored as a JSON
682
+ * string in props and are not fully round-tripped back to ConditionRef).
683
+ * The core capability data (can, with, nb, trigger, actor, ttl, metadata)
684
+ * is fully preserved.
685
+ */
686
+ declare function decompileToBaseUcanFlow(compiled: CompiledFlow): BaseUcanFlow;
687
+
688
+ export { type AuthorizationResult as A, type BaseUcanFlow as B, type CompilerRegistry as C, type ActionContext as D, type ExecuteNodeParams as E, type FlowRuntimeStateManager as F, type ActionResult as G, type ConditionRef as H, type ActorConstraint as I, type RuntimeRef as J, type CompiledBlock as K, type CompiledEdge as L, type MergeResult as M, type NodeActionResult as N, type OutputSchemaField as O, type CompiledFlowNode as P, isRuntimeRef as Q, type ReadFlowOptions as R, type SetupFlowOptions as S, type TTLConstraint as T, buildAuthzFromProps as a, buildFlowNodeFromBlock as b, createRuntimeStateManager as c, type ExecutionOutcome as d, executeNode as e, type ExecutionContext as f, readFlowFromEditor as g, readFlow as h, isAuthorized as i, setActiveEditor as j, getActiveEditor as k, compileBaseUcanFlow as l, readCompiledFlowFromYDoc as m, mergeCompiledFlows as n, decompileToBaseUcanFlow as o, type SetupFlowResult as p, type ReadFlowResult as q, readFlowAsBaseUcan as r, setupFlowFromBaseUcan as s, type ReadableEditor as t, type FlowCapability as u, type CompiledFlow as v, type FlowStrategy as w, type ActionDefinition as x, type ActionServices as y, clearRuntimeForTemplateClone as z };
@@ -1,5 +1,5 @@
1
1
  import * as _blocknote_core from '@blocknote/core';
2
- import { K as IxoBlockProps, J as IxoEditorType, l as IxoEditorOptions, p as IxoCollaborativeEditorOptions, k as DelegationGrant } from './index-MLwb3a2P.mjs';
2
+ import { J as IxoBlockProps, H as IxoEditorType, l as IxoEditorOptions, p as IxoCollaborativeEditorOptions, k as DelegationGrant } from './index-BEoftwDZ.mjs';
3
3
  import { Text, Doc, Map, Array as Array$1 } from 'yjs';
4
4
  import React__default from 'react';
5
5
  import { MatrixClient } from 'matrix-js-sdk';
@@ -2721,11 +2721,9 @@ interface CoverImageProps {
2721
2721
  }
2722
2722
  declare function CoverImage({ coverImageUrl, logoUrl }: CoverImageProps): React__default.ReactElement | null;
2723
2723
 
2724
- type AuthorizationTabState = {
2725
- activationUpstreamNodeId: string;
2726
- activationRequiredStatus: 'pending' | 'approved' | 'rejected' | '';
2727
- activationRequireAuthorisedActor: boolean;
2728
- };
2724
+ /** @deprecated The activation gating fields were removed; this type is kept
2725
+ * empty for any external imports during the transition. */
2726
+ type AuthorizationTabState = Record<string, never>;
2729
2727
  interface AuthorizationTabProps extends IxoBlockProps {
2730
2728
  /** Flow URI for capability scoping */
2731
2729
  flowUri?: string;