@ixo/editor 5.39.0 → 5.40.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,5 +1,12 @@
1
1
  // src/core/lib/actionRegistry/registry.ts
2
2
  var actions = /* @__PURE__ */ new Map();
3
+ var STEP_COMPLETED_EVENT_NAME = "step.completed";
4
+ var STEP_COMPLETED_EVENT = {
5
+ name: STEP_COMPLETED_EVENT_NAME,
6
+ displayName: "Completed",
7
+ description: "Fires when this step is completed.",
8
+ payloadSchema: []
9
+ };
3
10
  var ACTION_TYPE_ALIASES = {
4
11
  bid: "qi/bid.submit",
5
12
  claim: "qi/claim.submit",
@@ -51,15 +58,21 @@ function getActionByCan(can) {
51
58
  }
52
59
  function getEventsForBlock(action, inputs) {
53
60
  if (!action) return [];
61
+ let events;
54
62
  if (action.getDynamicEvents) {
55
63
  const parsed = normalizeInputs(inputs);
56
64
  try {
57
- return action.getDynamicEvents(parsed) || [];
65
+ events = action.getDynamicEvents(parsed) || [];
58
66
  } catch {
59
- return [];
67
+ events = [];
60
68
  }
69
+ } else {
70
+ events = action.events || [];
61
71
  }
62
- return action.events || [];
72
+ if (events.some((event) => event.name === STEP_COMPLETED_EVENT_NAME)) {
73
+ return events;
74
+ }
75
+ return [...events, STEP_COMPLETED_EVENT];
63
76
  }
64
77
  function getOutputSchemaForBlock(action, inputs) {
65
78
  if (!action) return [];
@@ -9031,438 +9044,90 @@ var createUcanService = (config) => {
9031
9044
  };
9032
9045
  };
9033
9046
 
9034
- // src/core/lib/flowEngine/utils.ts
9035
- var buildAuthzFromProps = (props) => {
9036
- const linkedClaimCollectionId = typeof props.linkedClaimCollectionId === "string" ? props.linkedClaimCollectionId.trim() : "";
9037
- const authz = {};
9038
- if (linkedClaimCollectionId) {
9039
- authz.linkedClaim = { collectionId: linkedClaimCollectionId };
9040
- }
9041
- return authz;
9042
- };
9043
- var buildFlowNodeFromBlock = (block) => {
9044
- const base = {
9045
- id: block.id,
9046
- type: block.type,
9047
- props: block.props || {}
9048
- };
9049
- const authz = buildAuthzFromProps(block.props || {});
9050
- return {
9051
- ...base,
9052
- ...authz
9053
- };
9054
- };
9055
-
9056
- // src/core/lib/flowEngine/runtime.ts
9057
- var XERO_WORK_ITEMS_MAP_NAME = "xeroWorkItems";
9058
- var XERO_CONNECTION_MAP_NAME = "xeroConnection";
9059
- var ensureStateObject = (value) => {
9060
- if (!value || typeof value !== "object") {
9061
- return {};
9062
- }
9063
- return { ...value };
9064
- };
9065
- var createYMapManager = (map) => {
9066
- return {
9067
- get: (nodeId) => {
9068
- const stored = map.get(nodeId);
9069
- return ensureStateObject(stored);
9070
- },
9071
- update: (nodeId, updates) => {
9072
- const current = ensureStateObject(map.get(nodeId));
9073
- map.set(nodeId, { ...current, ...updates });
9074
- }
9075
- };
9076
- };
9077
- var createMemoryManager = () => {
9078
- const memory = /* @__PURE__ */ new Map();
9079
- return {
9080
- get: (nodeId) => ensureStateObject(memory.get(nodeId)),
9081
- update: (nodeId, updates) => {
9082
- const current = ensureStateObject(memory.get(nodeId));
9083
- memory.set(nodeId, { ...current, ...updates });
9084
- }
9085
- };
9086
- };
9087
- var createRuntimeStateManager = (editor) => {
9088
- if (editor?._yRuntime) {
9089
- return createYMapManager(editor._yRuntime);
9090
- }
9091
- return createMemoryManager();
9092
- };
9093
- var createYDocRuntimeManager = (yDoc) => {
9094
- return createYMapManager(yDoc.getMap("runtime"));
9095
- };
9096
- function clearRuntimeForTemplateClone(yDoc) {
9097
- const runtime = yDoc.getMap("runtime");
9098
- const invocations = yDoc.getMap("invocations");
9099
- const pendingInvocations = yDoc.getMap("pendingInvocations");
9100
- const agentOutbox = yDoc.getMap("agentOutbox");
9101
- const agentLeases = yDoc.getMap("agentLeases");
9102
- const auditTrail = yDoc.getMap("auditTrail");
9103
- const xeroWorkItems = yDoc.getMap(XERO_WORK_ITEMS_MAP_NAME);
9104
- const xeroConnection = yDoc.getMap(XERO_CONNECTION_MAP_NAME);
9105
- yDoc.transact(() => {
9106
- runtime.forEach((_, key) => runtime.delete(key));
9107
- invocations.forEach((_, key) => invocations.delete(key));
9108
- pendingInvocations.forEach((_, key) => pendingInvocations.delete(key));
9109
- agentOutbox.forEach((_, key) => agentOutbox.delete(key));
9110
- agentLeases.forEach((_, key) => agentLeases.delete(key));
9111
- auditTrail.forEach((_, key) => auditTrail.delete(key));
9112
- xeroWorkItems.forEach((_, key) => xeroWorkItems.delete(key));
9113
- xeroConnection.forEach((_, key) => xeroConnection.delete(key));
9114
- });
9115
- }
9116
-
9117
9047
  // src/core/types/baseUcan.ts
9118
9048
  function isRuntimeRef(value) {
9119
9049
  return typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string";
9120
9050
  }
9121
9051
 
9122
- // src/core/lib/flowCompiler/resolveRefs.ts
9123
- function resolveRuntimeRefs(nb, getNodeOutput2, triggerContext) {
9124
- return resolveValue(nb, getNodeOutput2, triggerContext);
9052
+ // src/core/lib/flowEngine/triggers.ts
9053
+ import * as Y from "yjs";
9054
+ var RUN_RECORD_AUDIT_TYPE = "block.run";
9055
+ function computePendingInvocationId(args) {
9056
+ const { sourceBlockId, sourceRunId, listenerBlockId, eventName, eventIndex } = args;
9057
+ const input = `${sourceBlockId}:${sourceRunId}:${listenerBlockId}:${eventName}:${eventIndex}`;
9058
+ return `pi-${fnv1a32(input)}`;
9125
9059
  }
9126
- function resolveValue(value, getNodeOutput2, triggerContext) {
9060
+ function snapshotInputRefs(inputs, getNodeOutput2) {
9061
+ const snapshots = {};
9062
+ walkRefs(inputs, (ref) => {
9063
+ if (ref.$ref.startsWith("trigger.")) return;
9064
+ const parsed = parseOutputRef(ref.$ref);
9065
+ if (!parsed) return;
9066
+ const output = getNodeOutput2(parsed.nodeId);
9067
+ if (!output) return;
9068
+ snapshots[ref.$ref] = getNestedValue2(output, parsed.fieldPath);
9069
+ });
9070
+ return snapshots;
9071
+ }
9072
+ function walkRefs(value, visit) {
9127
9073
  if (isRuntimeRef(value)) {
9128
- return resolveRef(value.$ref, getNodeOutput2, triggerContext);
9074
+ visit(value);
9075
+ return;
9129
9076
  }
9130
9077
  if (Array.isArray(value)) {
9131
- return value.map((item) => resolveValue(item, getNodeOutput2, triggerContext));
9078
+ for (const item of value) walkRefs(item, visit);
9079
+ return;
9132
9080
  }
9133
9081
  if (typeof value === "object" && value !== null) {
9134
- const result = {};
9135
- for (const [key, val] of Object.entries(value)) {
9136
- result[key] = resolveValue(val, getNodeOutput2, triggerContext);
9137
- }
9138
- return result;
9082
+ for (const v of Object.values(value)) walkRefs(v, visit);
9139
9083
  }
9140
- return value;
9141
9084
  }
9142
- function resolveRef(ref, getNodeOutput2, triggerContext) {
9143
- if (ref.startsWith("trigger.payload.")) {
9144
- if (!triggerContext) {
9145
- throw new Error(`Trigger ref "${ref}" used outside of a listener invocation context. trigger.payload.* refs are only valid on block.event-triggered blocks.`);
9146
- }
9147
- const fieldPath2 = ref.slice("trigger.payload.".length);
9148
- return getNestedValue2(triggerContext.payload, fieldPath2);
9149
- }
9150
- if (triggerContext && Object.prototype.hasOwnProperty.call(triggerContext.refSnapshots, ref)) {
9151
- return triggerContext.refSnapshots[ref];
9152
- }
9085
+ function parseOutputRef(ref) {
9153
9086
  const outputIndex = ref.indexOf(".output.");
9154
- if (outputIndex === -1) {
9155
- throw new Error(`Invalid runtime reference "${ref}". Expected format: "nodeId.output.fieldPath" or "trigger.payload.fieldPath"`);
9156
- }
9157
- const nodeId = ref.slice(0, outputIndex);
9158
- const fieldPath = ref.slice(outputIndex + ".output.".length);
9159
- const output = getNodeOutput2(nodeId);
9160
- if (!output) {
9161
- return void 0;
9162
- }
9163
- return getNestedValue2(output, fieldPath);
9087
+ if (outputIndex === -1) return null;
9088
+ return {
9089
+ nodeId: ref.slice(0, outputIndex),
9090
+ fieldPath: ref.slice(outputIndex + ".output.".length)
9091
+ };
9164
9092
  }
9165
9093
  function getNestedValue2(obj, path) {
9166
9094
  const parts = path.split(".");
9167
9095
  let current = obj;
9168
9096
  for (const part of parts) {
9169
- if (current == null || typeof current !== "object") {
9170
- return void 0;
9171
- }
9097
+ if (current == null || typeof current !== "object") return void 0;
9172
9098
  current = current[part];
9173
9099
  }
9174
9100
  return current;
9175
9101
  }
9176
-
9177
- // src/core/lib/flowEngine/versionManifest.ts
9178
- var VERSION_MANIFEST = {
9179
- "0.3": {
9180
- version: "0.3",
9181
- label: "Legacy",
9182
- ucanRequired: false,
9183
- delegationRootRequired: false,
9184
- whitelistOnlyAllowed: true,
9185
- unrestrictedAllowed: true,
9186
- executionPath: "legacy",
9187
- authorizationFn: "v1",
9188
- allowedAuthModes: ["anyone", "actors", "capability"],
9189
- ui: {
9190
- showDelegationPanel: false,
9191
- showWhitelistConfig: true,
9192
- showAnyoneConfig: true,
9193
- showMigrationBanner: true,
9194
- requirePinForExecution: false
9195
- },
9196
- description: "Legacy version. UCAN optional, whitelist-only authorization accepted."
9197
- },
9198
- "1.0.0": {
9199
- version: "1.0.0",
9200
- label: "UCAN Required",
9201
- /** TEMP Disablement - needs to be true TODO */
9202
- ucanRequired: false,
9203
- delegationRootRequired: true,
9204
- whitelistOnlyAllowed: false,
9205
- unrestrictedAllowed: false,
9206
- executionPath: "invocation",
9207
- authorizationFn: "v2",
9208
- allowedAuthModes: ["capability"],
9209
- ui: {
9210
- showDelegationPanel: true,
9211
- showWhitelistConfig: false,
9212
- showAnyoneConfig: false,
9213
- showMigrationBanner: false,
9214
- requirePinForExecution: true
9215
- },
9216
- description: "UCAN-enforced. Every block execution requires a valid delegation chain."
9217
- }
9218
- };
9219
- var LATEST_VERSION = "1.0.0";
9220
- function getVersionPolicy(version) {
9221
- const policy = VERSION_MANIFEST[version];
9222
- if (!policy) {
9223
- return VERSION_MANIFEST[LATEST_VERSION];
9102
+ function fnv1a32(input) {
9103
+ let hash = 2166136261;
9104
+ for (let i = 0; i < input.length; i++) {
9105
+ hash ^= input.charCodeAt(i);
9106
+ hash = Math.imul(hash, 16777619);
9224
9107
  }
9225
- return policy;
9108
+ return (hash >>> 0).toString(16).padStart(8, "0");
9226
9109
  }
9227
-
9228
- // src/core/lib/flowEngine/authorization.ts
9229
- var isAuthorized = async (blockId, actorDid, ucanService, flowUri, schemaVersion) => {
9230
- const policy = schemaVersion ? getVersionPolicy(schemaVersion) : null;
9231
- if (policy && !policy.ucanRequired) {
9232
- return { authorized: true };
9110
+ var PENDING_INVOCATIONS_MAP_KEY = "pendingInvocations";
9111
+ function getPendingInvocationsMap(yDoc) {
9112
+ return yDoc.getMap(PENDING_INVOCATIONS_MAP_KEY);
9113
+ }
9114
+ function getOrCreateBlockPendingMap(yDoc, blockId) {
9115
+ const outer = getPendingInvocationsMap(yDoc);
9116
+ let inner = outer.get(blockId);
9117
+ if (!inner) {
9118
+ inner = new Y.Map();
9119
+ outer.set(blockId, inner);
9233
9120
  }
9234
- if (!ucanService) {
9235
- if (!policy) {
9236
- return { authorized: true };
9237
- }
9238
- return {
9239
- authorized: false,
9240
- reason: "UCAN service is not configured. This flow version requires UCAN authorization."
9241
- };
9242
- }
9243
- const capability = {
9244
- can: "flow/block/execute",
9245
- with: `${flowUri}:${blockId}`
9246
- };
9247
- const result = await ucanService.validateDelegationChain(actorDid, capability);
9248
- if (!result.valid) {
9249
- return {
9250
- authorized: false,
9251
- reason: result.error || "No valid capability chain found"
9252
- };
9253
- }
9254
- const proofCids = result.proofChain?.map((d) => d.cid) || [];
9255
- return {
9256
- authorized: true,
9257
- capabilityId: proofCids[0],
9258
- proofCids
9259
- };
9260
- };
9261
-
9262
- // src/core/lib/flowEngine/executor.ts
9263
- var updateRuntimeAfterSuccess = (node, actorDid, runtime, actionResult, invocationCid, now) => {
9264
- const updates = {
9265
- submittedByDid: actionResult.submittedByDid || actorDid,
9266
- evaluationStatus: actionResult.evaluationStatus || "pending",
9267
- executionTimestamp: now ? now() : Date.now(),
9268
- lastInvocationCid: invocationCid
9269
- };
9270
- if (actionResult.claimId) {
9271
- updates.claimId = actionResult.claimId;
9272
- }
9273
- runtime.update(node.id, updates);
9274
- };
9275
- var executeNode = async ({ node, actorDid, actorType, entityRoomId, context, action, pin }) => {
9276
- const { runtime, ucanService, invocationStore, flowUri, flowId, schemaVersion, now } = context;
9277
- const auth = await isAuthorized(node.id, actorDid, ucanService, flowUri, schemaVersion);
9278
- if (!auth.authorized) {
9279
- return { success: false, stage: "authorization", error: auth.reason };
9280
- }
9281
- if (node.linkedClaim && !node.linkedClaim.collectionId) {
9282
- return { success: false, stage: "claim", error: "Linked claim collection is required but missing." };
9283
- }
9284
- let invocationCid;
9285
- let invocationData;
9286
- if (ucanService && auth.proofCids && auth.proofCids.length > 0) {
9287
- const capability = {
9288
- can: "flow/block/execute",
9289
- with: `${flowUri}:${node.id}`
9290
- };
9291
- try {
9292
- const invocationResult = await ucanService.createAndValidateInvocation(
9293
- {
9294
- invokerDid: actorDid,
9295
- invokerType: actorType,
9296
- entityRoomId,
9297
- capability,
9298
- proofs: auth.proofCids,
9299
- pin
9300
- },
9301
- flowId,
9302
- node.id
9303
- );
9304
- if (!invocationResult.valid) {
9305
- return {
9306
- success: false,
9307
- stage: "authorization",
9308
- error: `Invocation validation failed: ${invocationResult.error}`
9309
- };
9310
- }
9311
- invocationCid = invocationResult.cid;
9312
- invocationData = invocationResult.invocation;
9313
- } catch (error) {
9314
- const message = error instanceof Error ? error.message : "Failed to create invocation";
9315
- return { success: false, stage: "authorization", error: message };
9316
- }
9317
- }
9318
- try {
9319
- const result = await action();
9320
- if (node.linkedClaim && !result.claimId) {
9321
- if (invocationStore && invocationCid && invocationData) {
9322
- const storedInvocation = {
9323
- cid: invocationCid,
9324
- invocation: invocationData,
9325
- invokerDid: actorDid,
9326
- capability: { can: "flow/block/execute", with: `${flowUri}:${node.id}` },
9327
- executedAt: now ? now() : Date.now(),
9328
- flowId,
9329
- blockId: node.id,
9330
- result: "failure",
9331
- error: "Execution did not return a claimId for linked claim requirement.",
9332
- proofCids: auth.proofCids || []
9333
- };
9334
- invocationStore.add(storedInvocation);
9335
- }
9336
- return {
9337
- success: false,
9338
- stage: "claim",
9339
- error: "Execution did not return a claimId for linked claim requirement.",
9340
- invocationCid
9341
- };
9342
- }
9343
- if (invocationStore && invocationCid && invocationData) {
9344
- const storedInvocation = {
9345
- cid: invocationCid,
9346
- invocation: invocationData,
9347
- invokerDid: actorDid,
9348
- capability: { can: "flow/block/execute", with: `${flowUri}:${node.id}` },
9349
- executedAt: now ? now() : Date.now(),
9350
- flowId,
9351
- blockId: node.id,
9352
- result: "success",
9353
- proofCids: auth.proofCids || [],
9354
- claimId: result.claimId
9355
- };
9356
- invocationStore.add(storedInvocation);
9357
- }
9358
- updateRuntimeAfterSuccess(node, actorDid, runtime, result, invocationCid || auth.capabilityId, now);
9359
- return {
9360
- success: true,
9361
- stage: "complete",
9362
- result,
9363
- capabilityId: auth.capabilityId,
9364
- invocationCid
9365
- };
9366
- } catch (error) {
9367
- const message = error instanceof Error ? error.message : "Execution failed";
9368
- if (invocationStore && invocationCid && invocationData) {
9369
- const storedInvocation = {
9370
- cid: invocationCid,
9371
- invocation: invocationData,
9372
- invokerDid: actorDid,
9373
- capability: { can: "flow/block/execute", with: `${flowUri}:${node.id}` },
9374
- executedAt: now ? now() : Date.now(),
9375
- flowId,
9376
- blockId: node.id,
9377
- result: "failure",
9378
- error: message,
9379
- proofCids: auth.proofCids || []
9380
- };
9381
- invocationStore.add(storedInvocation);
9382
- }
9383
- return { success: false, stage: "action", error: message, invocationCid };
9384
- }
9385
- };
9386
-
9387
- // src/core/lib/flowEngine/triggers.ts
9388
- import * as Y from "yjs";
9389
- var RUN_RECORD_AUDIT_TYPE = "block.run";
9390
- function computePendingInvocationId(args) {
9391
- const { sourceBlockId, sourceRunId, listenerBlockId, eventName, eventIndex } = args;
9392
- const input = `${sourceBlockId}:${sourceRunId}:${listenerBlockId}:${eventName}:${eventIndex}`;
9393
- return `pi-${fnv1a32(input)}`;
9394
- }
9395
- function snapshotInputRefs(inputs, getNodeOutput2) {
9396
- const snapshots = {};
9397
- walkRefs(inputs, (ref) => {
9398
- if (ref.$ref.startsWith("trigger.")) return;
9399
- const parsed = parseOutputRef(ref.$ref);
9400
- if (!parsed) return;
9401
- const output = getNodeOutput2(parsed.nodeId);
9402
- if (!output) return;
9403
- snapshots[ref.$ref] = getNestedValue3(output, parsed.fieldPath);
9404
- });
9405
- return snapshots;
9406
- }
9407
- function walkRefs(value, visit) {
9408
- if (isRuntimeRef(value)) {
9409
- visit(value);
9410
- return;
9411
- }
9412
- if (Array.isArray(value)) {
9413
- for (const item of value) walkRefs(item, visit);
9414
- return;
9415
- }
9416
- if (typeof value === "object" && value !== null) {
9417
- for (const v of Object.values(value)) walkRefs(v, visit);
9418
- }
9419
- }
9420
- function parseOutputRef(ref) {
9421
- const outputIndex = ref.indexOf(".output.");
9422
- if (outputIndex === -1) return null;
9423
- return {
9424
- nodeId: ref.slice(0, outputIndex),
9425
- fieldPath: ref.slice(outputIndex + ".output.".length)
9426
- };
9427
- }
9428
- function getNestedValue3(obj, path) {
9429
- const parts = path.split(".");
9430
- let current = obj;
9431
- for (const part of parts) {
9432
- if (current == null || typeof current !== "object") return void 0;
9433
- current = current[part];
9434
- }
9435
- return current;
9436
- }
9437
- function fnv1a32(input) {
9438
- let hash = 2166136261;
9439
- for (let i = 0; i < input.length; i++) {
9440
- hash ^= input.charCodeAt(i);
9441
- hash = Math.imul(hash, 16777619);
9442
- }
9443
- return (hash >>> 0).toString(16).padStart(8, "0");
9444
- }
9445
- var PENDING_INVOCATIONS_MAP_KEY = "pendingInvocations";
9446
- function getPendingInvocationsMap(yDoc) {
9447
- return yDoc.getMap(PENDING_INVOCATIONS_MAP_KEY);
9448
- }
9449
- function getOrCreateBlockPendingMap(yDoc, blockId) {
9450
- const outer = getPendingInvocationsMap(yDoc);
9451
- let inner = outer.get(blockId);
9452
- if (!inner) {
9453
- inner = new Y.Map();
9454
- outer.set(blockId, inner);
9455
- }
9456
- return inner;
9457
- }
9458
- function readPendingInvocations(yDoc, blockId) {
9459
- const outer = getPendingInvocationsMap(yDoc);
9460
- const inner = outer.get(blockId);
9461
- if (!inner) return [];
9462
- const items = [];
9463
- inner.forEach((value) => {
9464
- if (value && typeof value === "object") {
9465
- items.push(value);
9121
+ return inner;
9122
+ }
9123
+ function readPendingInvocations(yDoc, blockId) {
9124
+ const outer = getPendingInvocationsMap(yDoc);
9125
+ const inner = outer.get(blockId);
9126
+ if (!inner) return [];
9127
+ const items = [];
9128
+ inner.forEach((value) => {
9129
+ if (value && typeof value === "object") {
9130
+ items.push(value);
9466
9131
  }
9467
9132
  });
9468
9133
  items.sort((a, b) => a.emittedAt.localeCompare(b.emittedAt));
@@ -9791,69 +9456,437 @@ function processBarrierRunRecord(yDoc, sourceBlockId, record, barrierListenersBy
9791
9456
  }
9792
9457
  }
9793
9458
  }
9794
- function parseTrigger(block) {
9795
- const raw = block?.props?.trigger;
9796
- if (!raw || typeof raw !== "string") return null;
9797
- try {
9798
- const parsed = JSON.parse(raw);
9799
- if (parsed && typeof parsed === "object" && typeof parsed.type === "string") {
9800
- return parsed;
9459
+ function parseTrigger(block) {
9460
+ const raw = block?.props?.trigger;
9461
+ if (!raw || typeof raw !== "string") return null;
9462
+ try {
9463
+ const parsed = JSON.parse(raw);
9464
+ if (parsed && typeof parsed === "object" && typeof parsed.type === "string") {
9465
+ return parsed;
9466
+ }
9467
+ } catch {
9468
+ }
9469
+ return null;
9470
+ }
9471
+ function parseInputs(block) {
9472
+ const raw = block?.props?.inputs;
9473
+ if (!raw || typeof raw !== "string") return {};
9474
+ try {
9475
+ const parsed = JSON.parse(raw);
9476
+ if (parsed && typeof parsed === "object") return parsed;
9477
+ } catch {
9478
+ }
9479
+ return {};
9480
+ }
9481
+ function resolveAssignee(block) {
9482
+ const raw = block?.props?.assignment;
9483
+ if (!raw) return void 0;
9484
+ try {
9485
+ const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
9486
+ const did = parsed?.assignedActor?.did;
9487
+ return typeof did === "string" && did.length > 0 ? did : void 0;
9488
+ } catch {
9489
+ return void 0;
9490
+ }
9491
+ }
9492
+ function computeExpiry(block, emittedAt) {
9493
+ const ttlAbsolute = block?.props?.ttlAbsoluteDueDate;
9494
+ if (typeof ttlAbsolute === "string" && ttlAbsolute) {
9495
+ return ttlAbsolute;
9496
+ }
9497
+ const ttlFromEnablement = block?.props?.ttlFromEnablement;
9498
+ if (typeof ttlFromEnablement === "string" && ttlFromEnablement) {
9499
+ const ms = parseIsoDurationToMs(ttlFromEnablement);
9500
+ if (ms != null) {
9501
+ return new Date(new Date(emittedAt).getTime() + ms).toISOString();
9502
+ }
9503
+ }
9504
+ return new Date(new Date(emittedAt).getTime() + 7 * 24 * 60 * 60 * 1e3).toISOString();
9505
+ }
9506
+ function parseIsoDurationToMs(duration) {
9507
+ const match = /^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/.exec(duration);
9508
+ if (!match) return null;
9509
+ const [, d, h, m, s] = match;
9510
+ let ms = 0;
9511
+ if (d) ms += parseInt(d, 10) * 24 * 60 * 60 * 1e3;
9512
+ if (h) ms += parseInt(h, 10) * 60 * 60 * 1e3;
9513
+ if (m) ms += parseInt(m, 10) * 60 * 1e3;
9514
+ if (s) ms += parseInt(s, 10) * 1e3;
9515
+ return ms;
9516
+ }
9517
+ function getActionForBlock(block) {
9518
+ const actionType = block?.props?.actionType;
9519
+ if (typeof actionType !== "string") return void 0;
9520
+ return getAction(actionType);
9521
+ }
9522
+
9523
+ // src/core/lib/flowEngine/emitEvents.ts
9524
+ function writeRunRecordAndReconcile(editor, blockId, output, events, actorDid, detailsPatch = {}) {
9525
+ const yDoc = editor._yDoc;
9526
+ if (!yDoc) return;
9527
+ if (events.length === 0) return;
9528
+ const runId = `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
9529
+ const now = (/* @__PURE__ */ new Date()).toISOString();
9530
+ const details = {
9531
+ runId,
9532
+ output,
9533
+ events,
9534
+ startedAt: now,
9535
+ completedAt: now,
9536
+ actorDid,
9537
+ ...detailsPatch
9538
+ };
9539
+ appendRunRecord(yDoc, blockId, details, actorDid);
9540
+ reconcilePendingInvocations(editor);
9541
+ }
9542
+
9543
+ // src/core/lib/flowEngine/utils.ts
9544
+ var buildAuthzFromProps = (props) => {
9545
+ const linkedClaimCollectionId = typeof props.linkedClaimCollectionId === "string" ? props.linkedClaimCollectionId.trim() : "";
9546
+ const authz = {};
9547
+ if (linkedClaimCollectionId) {
9548
+ authz.linkedClaim = { collectionId: linkedClaimCollectionId };
9549
+ }
9550
+ return authz;
9551
+ };
9552
+ var buildFlowNodeFromBlock = (block) => {
9553
+ const base = {
9554
+ id: block.id,
9555
+ type: block.type,
9556
+ props: block.props || {}
9557
+ };
9558
+ const authz = buildAuthzFromProps(block.props || {});
9559
+ return {
9560
+ ...base,
9561
+ ...authz
9562
+ };
9563
+ };
9564
+
9565
+ // src/core/lib/flowEngine/runtime.ts
9566
+ var XERO_WORK_ITEMS_MAP_NAME = "xeroWorkItems";
9567
+ var XERO_CONNECTION_MAP_NAME = "xeroConnection";
9568
+ var ensureStateObject = (value) => {
9569
+ if (!value || typeof value !== "object") {
9570
+ return {};
9571
+ }
9572
+ return { ...value };
9573
+ };
9574
+ var createYMapManager = (map) => {
9575
+ return {
9576
+ get: (nodeId) => {
9577
+ const stored = map.get(nodeId);
9578
+ return ensureStateObject(stored);
9579
+ },
9580
+ update: (nodeId, updates) => {
9581
+ const current = ensureStateObject(map.get(nodeId));
9582
+ map.set(nodeId, { ...current, ...updates });
9583
+ }
9584
+ };
9585
+ };
9586
+ var createMemoryManager = () => {
9587
+ const memory = /* @__PURE__ */ new Map();
9588
+ return {
9589
+ get: (nodeId) => ensureStateObject(memory.get(nodeId)),
9590
+ update: (nodeId, updates) => {
9591
+ const current = ensureStateObject(memory.get(nodeId));
9592
+ memory.set(nodeId, { ...current, ...updates });
9593
+ }
9594
+ };
9595
+ };
9596
+ var createRuntimeStateManager = (editor) => {
9597
+ if (editor?._yRuntime) {
9598
+ return createYMapManager(editor._yRuntime);
9599
+ }
9600
+ return createMemoryManager();
9601
+ };
9602
+ var createYDocRuntimeManager = (yDoc) => {
9603
+ return createYMapManager(yDoc.getMap("runtime"));
9604
+ };
9605
+ function clearRuntimeForTemplateClone(yDoc) {
9606
+ const runtime = yDoc.getMap("runtime");
9607
+ const invocations = yDoc.getMap("invocations");
9608
+ const pendingInvocations = yDoc.getMap("pendingInvocations");
9609
+ const agentOutbox = yDoc.getMap("agentOutbox");
9610
+ const agentLeases = yDoc.getMap("agentLeases");
9611
+ const auditTrail = yDoc.getMap("auditTrail");
9612
+ const xeroWorkItems = yDoc.getMap(XERO_WORK_ITEMS_MAP_NAME);
9613
+ const xeroConnection = yDoc.getMap(XERO_CONNECTION_MAP_NAME);
9614
+ yDoc.transact(() => {
9615
+ runtime.forEach((_, key) => runtime.delete(key));
9616
+ invocations.forEach((_, key) => invocations.delete(key));
9617
+ pendingInvocations.forEach((_, key) => pendingInvocations.delete(key));
9618
+ agentOutbox.forEach((_, key) => agentOutbox.delete(key));
9619
+ agentLeases.forEach((_, key) => agentLeases.delete(key));
9620
+ auditTrail.forEach((_, key) => auditTrail.delete(key));
9621
+ xeroWorkItems.forEach((_, key) => xeroWorkItems.delete(key));
9622
+ xeroConnection.forEach((_, key) => xeroConnection.delete(key));
9623
+ });
9624
+ }
9625
+
9626
+ // src/core/lib/flowCompiler/resolveRefs.ts
9627
+ function resolveRuntimeRefs(nb, getNodeOutput2, triggerContext) {
9628
+ return resolveValue(nb, getNodeOutput2, triggerContext);
9629
+ }
9630
+ function resolveValue(value, getNodeOutput2, triggerContext) {
9631
+ if (isRuntimeRef(value)) {
9632
+ return resolveRef(value.$ref, getNodeOutput2, triggerContext);
9633
+ }
9634
+ if (Array.isArray(value)) {
9635
+ return value.map((item) => resolveValue(item, getNodeOutput2, triggerContext));
9636
+ }
9637
+ if (typeof value === "object" && value !== null) {
9638
+ const result = {};
9639
+ for (const [key, val] of Object.entries(value)) {
9640
+ result[key] = resolveValue(val, getNodeOutput2, triggerContext);
9641
+ }
9642
+ return result;
9643
+ }
9644
+ return value;
9645
+ }
9646
+ function resolveRef(ref, getNodeOutput2, triggerContext) {
9647
+ if (ref.startsWith("trigger.payload.")) {
9648
+ if (!triggerContext) {
9649
+ throw new Error(`Trigger ref "${ref}" used outside of a listener invocation context. trigger.payload.* refs are only valid on block.event-triggered blocks.`);
9650
+ }
9651
+ const fieldPath2 = ref.slice("trigger.payload.".length);
9652
+ return getNestedValue3(triggerContext.payload, fieldPath2);
9653
+ }
9654
+ if (triggerContext && Object.prototype.hasOwnProperty.call(triggerContext.refSnapshots, ref)) {
9655
+ return triggerContext.refSnapshots[ref];
9656
+ }
9657
+ const outputIndex = ref.indexOf(".output.");
9658
+ if (outputIndex === -1) {
9659
+ throw new Error(`Invalid runtime reference "${ref}". Expected format: "nodeId.output.fieldPath" or "trigger.payload.fieldPath"`);
9660
+ }
9661
+ const nodeId = ref.slice(0, outputIndex);
9662
+ const fieldPath = ref.slice(outputIndex + ".output.".length);
9663
+ const output = getNodeOutput2(nodeId);
9664
+ if (!output) {
9665
+ return void 0;
9666
+ }
9667
+ return getNestedValue3(output, fieldPath);
9668
+ }
9669
+ function getNestedValue3(obj, path) {
9670
+ const parts = path.split(".");
9671
+ let current = obj;
9672
+ for (const part of parts) {
9673
+ if (current == null || typeof current !== "object") {
9674
+ return void 0;
9675
+ }
9676
+ current = current[part];
9677
+ }
9678
+ return current;
9679
+ }
9680
+
9681
+ // src/core/lib/flowEngine/versionManifest.ts
9682
+ var VERSION_MANIFEST = {
9683
+ "0.3": {
9684
+ version: "0.3",
9685
+ label: "Legacy",
9686
+ ucanRequired: false,
9687
+ delegationRootRequired: false,
9688
+ whitelistOnlyAllowed: true,
9689
+ unrestrictedAllowed: true,
9690
+ executionPath: "legacy",
9691
+ authorizationFn: "v1",
9692
+ allowedAuthModes: ["anyone", "actors", "capability"],
9693
+ ui: {
9694
+ showDelegationPanel: false,
9695
+ showWhitelistConfig: true,
9696
+ showAnyoneConfig: true,
9697
+ showMigrationBanner: true,
9698
+ requirePinForExecution: false
9699
+ },
9700
+ description: "Legacy version. UCAN optional, whitelist-only authorization accepted."
9701
+ },
9702
+ "1.0.0": {
9703
+ version: "1.0.0",
9704
+ label: "UCAN Required",
9705
+ /** TEMP Disablement - needs to be true TODO */
9706
+ ucanRequired: false,
9707
+ delegationRootRequired: true,
9708
+ whitelistOnlyAllowed: false,
9709
+ unrestrictedAllowed: false,
9710
+ executionPath: "invocation",
9711
+ authorizationFn: "v2",
9712
+ allowedAuthModes: ["capability"],
9713
+ ui: {
9714
+ showDelegationPanel: true,
9715
+ showWhitelistConfig: false,
9716
+ showAnyoneConfig: false,
9717
+ showMigrationBanner: false,
9718
+ requirePinForExecution: true
9719
+ },
9720
+ description: "UCAN-enforced. Every block execution requires a valid delegation chain."
9721
+ }
9722
+ };
9723
+ var LATEST_VERSION = "1.0.0";
9724
+ function getVersionPolicy(version) {
9725
+ const policy = VERSION_MANIFEST[version];
9726
+ if (!policy) {
9727
+ return VERSION_MANIFEST[LATEST_VERSION];
9728
+ }
9729
+ return policy;
9730
+ }
9731
+
9732
+ // src/core/lib/flowEngine/authorization.ts
9733
+ var isAuthorized = async (blockId, actorDid, ucanService, flowUri, schemaVersion) => {
9734
+ const policy = schemaVersion ? getVersionPolicy(schemaVersion) : null;
9735
+ if (policy && !policy.ucanRequired) {
9736
+ return { authorized: true };
9737
+ }
9738
+ if (!ucanService) {
9739
+ if (!policy) {
9740
+ return { authorized: true };
9801
9741
  }
9802
- } catch {
9742
+ return {
9743
+ authorized: false,
9744
+ reason: "UCAN service is not configured. This flow version requires UCAN authorization."
9745
+ };
9803
9746
  }
9804
- return null;
9805
- }
9806
- function parseInputs(block) {
9807
- const raw = block?.props?.inputs;
9808
- if (!raw || typeof raw !== "string") return {};
9809
- try {
9810
- const parsed = JSON.parse(raw);
9811
- if (parsed && typeof parsed === "object") return parsed;
9812
- } catch {
9747
+ const capability = {
9748
+ can: "flow/block/execute",
9749
+ with: `${flowUri}:${blockId}`
9750
+ };
9751
+ const result = await ucanService.validateDelegationChain(actorDid, capability);
9752
+ if (!result.valid) {
9753
+ return {
9754
+ authorized: false,
9755
+ reason: result.error || "No valid capability chain found"
9756
+ };
9813
9757
  }
9814
- return {};
9815
- }
9816
- function resolveAssignee(block) {
9817
- const raw = block?.props?.assignment;
9818
- if (!raw) return void 0;
9819
- try {
9820
- const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
9821
- const did = parsed?.assignedActor?.did;
9822
- return typeof did === "string" && did.length > 0 ? did : void 0;
9823
- } catch {
9824
- return void 0;
9758
+ const proofCids = result.proofChain?.map((d) => d.cid) || [];
9759
+ return {
9760
+ authorized: true,
9761
+ capabilityId: proofCids[0],
9762
+ proofCids
9763
+ };
9764
+ };
9765
+
9766
+ // src/core/lib/flowEngine/executor.ts
9767
+ var updateRuntimeAfterSuccess = (node, actorDid, runtime, actionResult, invocationCid, now) => {
9768
+ const updates = {
9769
+ submittedByDid: actionResult.submittedByDid || actorDid,
9770
+ evaluationStatus: actionResult.evaluationStatus || "pending",
9771
+ executionTimestamp: now ? now() : Date.now(),
9772
+ lastInvocationCid: invocationCid
9773
+ };
9774
+ if (actionResult.claimId) {
9775
+ updates.claimId = actionResult.claimId;
9825
9776
  }
9826
- }
9827
- function computeExpiry(block, emittedAt) {
9828
- const ttlAbsolute = block?.props?.ttlAbsoluteDueDate;
9829
- if (typeof ttlAbsolute === "string" && ttlAbsolute) {
9830
- return ttlAbsolute;
9777
+ runtime.update(node.id, updates);
9778
+ };
9779
+ var executeNode = async ({ node, actorDid, actorType, entityRoomId, context, action, pin }) => {
9780
+ const { runtime, ucanService, invocationStore, flowUri, flowId, schemaVersion, now } = context;
9781
+ const auth = await isAuthorized(node.id, actorDid, ucanService, flowUri, schemaVersion);
9782
+ if (!auth.authorized) {
9783
+ return { success: false, stage: "authorization", error: auth.reason };
9831
9784
  }
9832
- const ttlFromEnablement = block?.props?.ttlFromEnablement;
9833
- if (typeof ttlFromEnablement === "string" && ttlFromEnablement) {
9834
- const ms = parseIsoDurationToMs(ttlFromEnablement);
9835
- if (ms != null) {
9836
- return new Date(new Date(emittedAt).getTime() + ms).toISOString();
9785
+ if (node.linkedClaim && !node.linkedClaim.collectionId) {
9786
+ return { success: false, stage: "claim", error: "Linked claim collection is required but missing." };
9787
+ }
9788
+ let invocationCid;
9789
+ let invocationData;
9790
+ if (ucanService && auth.proofCids && auth.proofCids.length > 0) {
9791
+ const capability = {
9792
+ can: "flow/block/execute",
9793
+ with: `${flowUri}:${node.id}`
9794
+ };
9795
+ try {
9796
+ const invocationResult = await ucanService.createAndValidateInvocation(
9797
+ {
9798
+ invokerDid: actorDid,
9799
+ invokerType: actorType,
9800
+ entityRoomId,
9801
+ capability,
9802
+ proofs: auth.proofCids,
9803
+ pin
9804
+ },
9805
+ flowId,
9806
+ node.id
9807
+ );
9808
+ if (!invocationResult.valid) {
9809
+ return {
9810
+ success: false,
9811
+ stage: "authorization",
9812
+ error: `Invocation validation failed: ${invocationResult.error}`
9813
+ };
9814
+ }
9815
+ invocationCid = invocationResult.cid;
9816
+ invocationData = invocationResult.invocation;
9817
+ } catch (error) {
9818
+ const message = error instanceof Error ? error.message : "Failed to create invocation";
9819
+ return { success: false, stage: "authorization", error: message };
9837
9820
  }
9838
9821
  }
9839
- return new Date(new Date(emittedAt).getTime() + 7 * 24 * 60 * 60 * 1e3).toISOString();
9840
- }
9841
- function parseIsoDurationToMs(duration) {
9842
- const match = /^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?)?$/.exec(duration);
9843
- if (!match) return null;
9844
- const [, d, h, m, s] = match;
9845
- let ms = 0;
9846
- if (d) ms += parseInt(d, 10) * 24 * 60 * 60 * 1e3;
9847
- if (h) ms += parseInt(h, 10) * 60 * 60 * 1e3;
9848
- if (m) ms += parseInt(m, 10) * 60 * 1e3;
9849
- if (s) ms += parseInt(s, 10) * 1e3;
9850
- return ms;
9851
- }
9852
- function getActionForBlock(block) {
9853
- const actionType = block?.props?.actionType;
9854
- if (typeof actionType !== "string") return void 0;
9855
- return getAction(actionType);
9856
- }
9822
+ try {
9823
+ const result = await action();
9824
+ if (node.linkedClaim && !result.claimId) {
9825
+ if (invocationStore && invocationCid && invocationData) {
9826
+ const storedInvocation = {
9827
+ cid: invocationCid,
9828
+ invocation: invocationData,
9829
+ invokerDid: actorDid,
9830
+ capability: { can: "flow/block/execute", with: `${flowUri}:${node.id}` },
9831
+ executedAt: now ? now() : Date.now(),
9832
+ flowId,
9833
+ blockId: node.id,
9834
+ result: "failure",
9835
+ error: "Execution did not return a claimId for linked claim requirement.",
9836
+ proofCids: auth.proofCids || []
9837
+ };
9838
+ invocationStore.add(storedInvocation);
9839
+ }
9840
+ return {
9841
+ success: false,
9842
+ stage: "claim",
9843
+ error: "Execution did not return a claimId for linked claim requirement.",
9844
+ invocationCid
9845
+ };
9846
+ }
9847
+ if (invocationStore && invocationCid && invocationData) {
9848
+ const storedInvocation = {
9849
+ cid: invocationCid,
9850
+ invocation: invocationData,
9851
+ invokerDid: actorDid,
9852
+ capability: { can: "flow/block/execute", with: `${flowUri}:${node.id}` },
9853
+ executedAt: now ? now() : Date.now(),
9854
+ flowId,
9855
+ blockId: node.id,
9856
+ result: "success",
9857
+ proofCids: auth.proofCids || [],
9858
+ claimId: result.claimId
9859
+ };
9860
+ invocationStore.add(storedInvocation);
9861
+ }
9862
+ updateRuntimeAfterSuccess(node, actorDid, runtime, result, invocationCid || auth.capabilityId, now);
9863
+ return {
9864
+ success: true,
9865
+ stage: "complete",
9866
+ result,
9867
+ capabilityId: auth.capabilityId,
9868
+ invocationCid
9869
+ };
9870
+ } catch (error) {
9871
+ const message = error instanceof Error ? error.message : "Execution failed";
9872
+ if (invocationStore && invocationCid && invocationData) {
9873
+ const storedInvocation = {
9874
+ cid: invocationCid,
9875
+ invocation: invocationData,
9876
+ invokerDid: actorDid,
9877
+ capability: { can: "flow/block/execute", with: `${flowUri}:${node.id}` },
9878
+ executedAt: now ? now() : Date.now(),
9879
+ flowId,
9880
+ blockId: node.id,
9881
+ result: "failure",
9882
+ error: message,
9883
+ proofCids: auth.proofCids || []
9884
+ };
9885
+ invocationStore.add(storedInvocation);
9886
+ }
9887
+ return { success: false, stage: "action", error: message, invocationCid };
9888
+ }
9889
+ };
9857
9890
 
9858
9891
  // src/core/lib/ucanDelegationStore.ts
9859
9892
  var ROOT_DELEGATION_KEY = "__root__";
@@ -10187,26 +10220,6 @@ var createMemoryInvocationStore = () => {
10187
10220
  };
10188
10221
  };
10189
10222
 
10190
- // src/core/lib/flowEngine/emitEvents.ts
10191
- function writeRunRecordAndReconcile(editor, blockId, output, events, actorDid, detailsPatch = {}) {
10192
- const yDoc = editor._yDoc;
10193
- if (!yDoc) return;
10194
- if (events.length === 0) return;
10195
- const runId = `run-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
10196
- const now = (/* @__PURE__ */ new Date()).toISOString();
10197
- const details = {
10198
- runId,
10199
- output,
10200
- events,
10201
- startedAt: now,
10202
- completedAt: now,
10203
- actorDid,
10204
- ...detailsPatch
10205
- };
10206
- appendRunRecord(yDoc, blockId, details, actorDid);
10207
- reconcilePendingInvocations(editor);
10208
- }
10209
-
10210
10223
  // src/core/lib/flowEngine/actionExecutor.ts
10211
10224
  import * as Y3 from "yjs";
10212
10225
 
@@ -13225,6 +13238,8 @@ var FlowAgentService = class {
13225
13238
  };
13226
13239
 
13227
13240
  export {
13241
+ STEP_COMPLETED_EVENT_NAME,
13242
+ STEP_COMPLETED_EVENT,
13228
13243
  resolveActionType,
13229
13244
  registerAction,
13230
13245
  getAction,
@@ -13292,15 +13307,7 @@ export {
13292
13307
  formatCoin2 as formatCoin,
13293
13308
  formatCoinAmount,
13294
13309
  createUcanService,
13295
- buildAuthzFromProps,
13296
- buildFlowNodeFromBlock,
13297
- createRuntimeStateManager,
13298
- clearRuntimeForTemplateClone,
13299
13310
  isRuntimeRef,
13300
- resolveRuntimeRefs,
13301
- LATEST_VERSION,
13302
- isAuthorized,
13303
- executeNode,
13304
13311
  RUN_RECORD_AUDIT_TYPE,
13305
13312
  computePendingInvocationId,
13306
13313
  snapshotInputRefs,
@@ -13315,6 +13322,15 @@ export {
13315
13322
  replayFailedListenerRun,
13316
13323
  reconcilePendingInvocations,
13317
13324
  getActionForBlock,
13325
+ writeRunRecordAndReconcile,
13326
+ buildAuthzFromProps,
13327
+ buildFlowNodeFromBlock,
13328
+ createRuntimeStateManager,
13329
+ clearRuntimeForTemplateClone,
13330
+ resolveRuntimeRefs,
13331
+ LATEST_VERSION,
13332
+ isAuthorized,
13333
+ executeNode,
13318
13334
  reconcileActionReadBack,
13319
13335
  buildActionRunInputs,
13320
13336
  executeActionBlock,
@@ -13322,7 +13338,6 @@ export {
13322
13338
  createMemoryUcanDelegationStore,
13323
13339
  createInvocationStore,
13324
13340
  createMemoryInvocationStore,
13325
- writeRunRecordAndReconcile,
13326
13341
  compileBlockProps,
13327
13342
  COMPILED_BLOCK_TYPE,
13328
13343
  toEvaluatorOperator,
@@ -13374,4 +13389,4 @@ export {
13374
13389
  executeQueuedFlowAgentCoreCommands,
13375
13390
  FlowAgentService
13376
13391
  };
13377
- //# sourceMappingURL=chunk-YWZJYSOP.js.map
13392
+ //# sourceMappingURL=chunk-KNMPGX5G.js.map