@ixo/editor 3.0.0-beta.26 → 3.0.0-beta.28

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.
@@ -14,10 +14,12 @@ import {
14
14
  getAction,
15
15
  getAllActions,
16
16
  isActorAuthorized,
17
+ isNodeActive,
17
18
  parseLinkedEntities,
19
+ resolveActionType,
18
20
  sendDirectMessage,
19
21
  transformSurveyToCredentialSubject
20
- } from "./chunk-SUFKRSSM.mjs";
22
+ } from "./chunk-NOMJJJDB.mjs";
21
23
 
22
24
  // src/mantine/hooks/useCreateIxoEditor.ts
23
25
  import { useCreateBlockNote } from "@blocknote/react";
@@ -1540,14 +1542,14 @@ var BlocknoteProvider = ({
1540
1542
  }, [sharedProposals]);
1541
1543
  const fetchSharedProposal = useCallback4(
1542
1544
  async (proposalId, contractAddress, force = false) => {
1543
- const cacheKey = `${contractAddress}:${proposalId}`;
1544
- const cached = sharedProposalsRef.current[cacheKey];
1545
+ const cacheKey2 = `${contractAddress}:${proposalId}`;
1546
+ const cached = sharedProposalsRef.current[cacheKey2];
1545
1547
  if (!force && cached && Date.now() - cached.lastFetched < 3e4 && !cached.error) {
1546
1548
  return cached.proposal;
1547
1549
  }
1548
1550
  setSharedProposals((prev) => ({
1549
1551
  ...prev,
1550
- [cacheKey]: { ...prev[cacheKey], loading: true }
1552
+ [cacheKey2]: { ...prev[cacheKey2], loading: true }
1551
1553
  }));
1552
1554
  try {
1553
1555
  if (!handlers) {
@@ -1556,7 +1558,7 @@ var BlocknoteProvider = ({
1556
1558
  const proposal = await handlers.getProposal(contractAddress, proposalId);
1557
1559
  setSharedProposals((prev) => ({
1558
1560
  ...prev,
1559
- [cacheKey]: {
1561
+ [cacheKey2]: {
1560
1562
  proposal,
1561
1563
  lastFetched: Date.now(),
1562
1564
  loading: false
@@ -1566,8 +1568,8 @@ var BlocknoteProvider = ({
1566
1568
  } catch (error) {
1567
1569
  setSharedProposals((prev) => ({
1568
1570
  ...prev,
1569
- [cacheKey]: {
1570
- ...prev[cacheKey],
1571
+ [cacheKey2]: {
1572
+ ...prev[cacheKey2],
1571
1573
  loading: false,
1572
1574
  error
1573
1575
  }
@@ -1593,8 +1595,8 @@ var BlocknoteProvider = ({
1593
1595
  });
1594
1596
  }, []);
1595
1597
  const subscribeToProposal = useCallback4(
1596
- (cacheKey) => {
1597
- return sharedProposals[cacheKey]?.proposal;
1598
+ (cacheKey2) => {
1599
+ return sharedProposals[cacheKey2]?.proposal;
1598
1600
  },
1599
1601
  [sharedProposals]
1600
1602
  );
@@ -2192,24 +2194,24 @@ import { useState as useState6, useEffect as useEffect8, useCallback as useCallb
2192
2194
  var useSharedProposal = ({ proposalId, contractAddress, autoFetch = true }) => {
2193
2195
  const { sharedProposals, fetchSharedProposal, invalidateProposal, subscribeToProposal } = useBlocknoteContext();
2194
2196
  const [localProposal, setLocalProposal] = useState6(null);
2195
- const cacheKey = `${contractAddress}:${proposalId}`;
2197
+ const cacheKey2 = `${contractAddress}:${proposalId}`;
2196
2198
  useEffect8(() => {
2197
2199
  if (!proposalId || !contractAddress || !autoFetch) return;
2198
2200
  fetchSharedProposal(proposalId, contractAddress).then(setLocalProposal).catch(() => {
2199
2201
  });
2200
2202
  }, [proposalId, contractAddress, fetchSharedProposal, autoFetch]);
2201
2203
  useEffect8(() => {
2202
- const proposal = subscribeToProposal(cacheKey);
2204
+ const proposal = subscribeToProposal(cacheKey2);
2203
2205
  if (proposal) {
2204
2206
  setLocalProposal(proposal);
2205
2207
  }
2206
- }, [subscribeToProposal, cacheKey]);
2208
+ }, [subscribeToProposal, cacheKey2]);
2207
2209
  const refetch = useCallback10(() => fetchSharedProposal(proposalId, contractAddress, true), [fetchSharedProposal, proposalId, contractAddress]);
2208
2210
  const invalidate = useCallback10(() => invalidateProposal(proposalId), [invalidateProposal, proposalId]);
2209
2211
  return {
2210
2212
  proposal: localProposal,
2211
- loading: sharedProposals[cacheKey]?.loading ?? false,
2212
- error: sharedProposals[cacheKey]?.error,
2213
+ loading: sharedProposals[cacheKey2]?.loading ?? false,
2214
+ error: sharedProposals[cacheKey2]?.error,
2213
2215
  refetch,
2214
2216
  invalidate
2215
2217
  };
@@ -2265,6 +2267,10 @@ function computeExpiresAt(committedAt, ttlDuration) {
2265
2267
  const expiresAt = new Date(committedAt.getTime() + days * 864e5 + hours * 36e5 + minutes * 6e4);
2266
2268
  return expiresAt.toISOString();
2267
2269
  }
2270
+ function durationToMs(iso) {
2271
+ const { days, hours, minutes } = parseDuration(iso);
2272
+ return days * 864e5 + hours * 36e5 + minutes * 6e4;
2273
+ }
2268
2274
  var formatDate = (dateString) => {
2269
2275
  if (!dateString) return "N/A";
2270
2276
  try {
@@ -22862,7 +22868,7 @@ import React234, { useMemo as useMemo85 } from "react";
22862
22868
  // src/mantine/blocks/action/template/TemplateConfig.tsx
22863
22869
  import React233, { useCallback as useCallback69, useMemo as useMemo84 } from "react";
22864
22870
  import { Stack as Stack154 } from "@mantine/core";
22865
- import { IconCheck as IconCheck15, IconContract as IconContract4, IconSettings as IconSettings18, IconShieldCheck as IconShieldCheck13, IconUserCheck as IconUserCheck4 } from "@tabler/icons-react";
22871
+ import { IconCheck as IconCheck15, IconClock as IconClock11, IconContract as IconContract4, IconSettings as IconSettings18, IconShieldCheck as IconShieldCheck13, IconUserCheck as IconUserCheck4 } from "@tabler/icons-react";
22866
22872
 
22867
22873
  // src/mantine/blocks/action/template/GeneralTab.tsx
22868
22874
  import React232, { useEffect as useEffect72, useMemo as useMemo83, useState as useState87 } from "react";
@@ -22958,105 +22964,105 @@ function registerActionTypeUI(actionType, ui) {
22958
22964
  registry.set(actionType, ui);
22959
22965
  }
22960
22966
  function getActionTypeUI(actionType) {
22961
- return registry.get(actionType);
22967
+ return registry.get(resolveActionType(actionType));
22962
22968
  }
22963
22969
 
22964
22970
  // src/mantine/blocks/action/template/GeneralTab.tsx
22965
22971
  var COMBO_ICON_SIZE = 20;
22966
22972
  var ACTION_TYPE_META = {
22967
- "email.send": {
22973
+ "qi/email.send": {
22968
22974
  label: "Email",
22969
22975
  description: "Send an email to a user",
22970
22976
  icon: icon(IconMail6, COMBO_ICON_SIZE)
22971
22977
  },
22972
- "http.request": {
22978
+ "qi/http.request": {
22973
22979
  label: "HTTP Request",
22974
22980
  description: "Make an HTTP API request",
22975
22981
  icon: icon(IconWorld2, COMBO_ICON_SIZE)
22976
22982
  },
22977
- "notification.push": {
22983
+ "qi/notification.push": {
22978
22984
  label: "Push Notification",
22979
22985
  description: "Send a push notification",
22980
22986
  icon: icon(IconBell2, COMBO_ICON_SIZE)
22981
22987
  },
22982
- "human.checkbox.set": {
22988
+ "qi/human.checkbox.set": {
22983
22989
  label: "Checkbox Set",
22984
22990
  description: "Record a checkbox response",
22985
22991
  icon: icon(IconCheckbox3, COMBO_ICON_SIZE)
22986
22992
  },
22987
- "form.submit": {
22993
+ "qi/form.submit": {
22988
22994
  label: "Form Submit",
22989
22995
  description: "Submit a form response",
22990
22996
  icon: icon(IconClipboard, COMBO_ICON_SIZE)
22991
22997
  },
22992
- "human.form.submit": {
22998
+ "qi/human.form.submit": {
22993
22999
  label: "Human Form Submit",
22994
23000
  description: "Submit a human-completed form",
22995
23001
  icon: icon(IconClipboardCheck, COMBO_ICON_SIZE)
22996
23002
  },
22997
- bid: {
23003
+ "qi/bid.submit": {
22998
23004
  label: "Bid",
22999
23005
  description: "Submit a bid application",
23000
23006
  icon: icon(IconBriefcase2, COMBO_ICON_SIZE)
23001
23007
  },
23002
- evaluateBid: {
23008
+ "qi/bid.evaluate": {
23003
23009
  label: "Evaluate Bid",
23004
23010
  description: "Approve or reject a bid",
23005
23011
  icon: icon(IconScale, COMBO_ICON_SIZE)
23006
23012
  },
23007
- claim: {
23013
+ "qi/claim.submit": {
23008
23014
  label: "Claim",
23009
23015
  description: "Submit a claim",
23010
23016
  icon: icon(IconFileText5, COMBO_ICON_SIZE)
23011
23017
  },
23012
- evaluateClaim: {
23018
+ "qi/claim.evaluate": {
23013
23019
  label: "Evaluate Claim",
23014
23020
  description: "Approve or reject a claim",
23015
23021
  icon: icon(IconChecks4, COMBO_ICON_SIZE)
23016
23022
  },
23017
- "proposal.create": {
23023
+ "qi/proposal.create": {
23018
23024
  label: "Create Proposal",
23019
23025
  description: "Create an on-chain governance proposal",
23020
23026
  icon: icon(IconFileText5, COMBO_ICON_SIZE)
23021
23027
  },
23022
- "proposal.vote": {
23028
+ "qi/proposal.vote": {
23023
23029
  label: "Vote on Proposal",
23024
23030
  description: "Cast a vote on a governance proposal",
23025
23031
  icon: icon(IconThumbUp2, COMBO_ICON_SIZE)
23026
23032
  },
23027
- "protocol.select": {
23033
+ "qi/protocol.select": {
23028
23034
  label: "Select Protocol",
23029
23035
  description: "Select a protocol from a configured list",
23030
23036
  icon: icon(IconBolt7, COMBO_ICON_SIZE)
23031
23037
  },
23032
- "domain.sign": {
23038
+ "qi/domain.sign": {
23033
23039
  label: "Sign Domain",
23034
23040
  description: "Sign a domain card credential",
23035
23041
  icon: icon(IconSignature3, COMBO_ICON_SIZE)
23036
23042
  },
23037
- "domain.create": {
23043
+ "qi/domain.create": {
23038
23044
  label: "Create Domain",
23039
23045
  description: "Create a new domain entity on-chain",
23040
23046
  icon: icon(IconBuildingEstate, COMBO_ICON_SIZE)
23041
23047
  },
23042
- "credential.store": {
23048
+ "qi/credential.store": {
23043
23049
  label: "Store Credential",
23044
23050
  description: "Store a verifiable credential in Matrix room state",
23045
23051
  icon: icon(IconShieldCheck12, COMBO_ICON_SIZE)
23046
23052
  },
23047
- payment: {
23053
+ "qi/payment.execute": {
23048
23054
  label: "Payment",
23049
23055
  description: "Calculate, propose, and execute a payment",
23050
23056
  icon: icon(IconCash, COMBO_ICON_SIZE)
23051
23057
  },
23052
- "matrix.dm": {
23058
+ "qi/matrix.dm": {
23053
23059
  label: "Matrix DM",
23054
23060
  description: "Send a direct message via Matrix",
23055
23061
  icon: icon(IconMessageCircle, COMBO_ICON_SIZE)
23056
23062
  }
23057
23063
  };
23058
23064
  function getActionMeta(actionType) {
23059
- return ACTION_TYPE_META[actionType] || {
23065
+ return ACTION_TYPE_META[resolveActionType(actionType)] || {
23060
23066
  label: actionType || "Select action",
23061
23067
  description: actionType ? `Run ${actionType}` : "Choose an action type",
23062
23068
  icon: icon(IconBolt7, COMBO_ICON_SIZE)
@@ -23177,27 +23183,27 @@ var TemplateConfig16 = ({ editor, block }) => {
23177
23183
  const { closePanel } = usePanelStore();
23178
23184
  const isValid = useMemo84(() => {
23179
23185
  const title = (block.props.title || "").trim();
23180
- const actionType = block.props.actionType || "";
23186
+ const actionType = resolveActionType(block.props.actionType || "");
23181
23187
  if (!title || !actionType) return false;
23182
23188
  try {
23183
23189
  const inputs = JSON.parse(block.props.inputs || "{}");
23184
23190
  switch (actionType) {
23185
- case "email.send":
23191
+ case "qi/email.send":
23186
23192
  if (!inputs.to?.trim()) return false;
23187
23193
  break;
23188
- case "http.request":
23194
+ case "qi/http.request":
23189
23195
  if (!inputs.endpoint?.trim()) return false;
23190
23196
  break;
23191
- case "bid":
23192
- case "claim":
23193
- case "evaluateBid":
23194
- case "evaluateClaim":
23197
+ case "qi/bid.submit":
23198
+ case "qi/claim.submit":
23199
+ case "qi/bid.evaluate":
23200
+ case "qi/claim.evaluate":
23195
23201
  if (!inputs.deedDid?.trim() || !inputs.collectionId?.trim()) return false;
23196
23202
  break;
23197
- case "form.submit":
23203
+ case "qi/form.submit":
23198
23204
  if (!inputs.surveySchema?.trim()) return false;
23199
23205
  break;
23200
- case "payment":
23206
+ case "qi/payment.execute":
23201
23207
  break;
23202
23208
  }
23203
23209
  } catch {
@@ -23260,6 +23266,12 @@ var TemplateConfig16 = ({ editor, block }) => {
23260
23266
  value: "commitment",
23261
23267
  icon: icon(IconContract4),
23262
23268
  content: /* @__PURE__ */ React233.createElement(CommitmentTab, { editor, block })
23269
+ },
23270
+ {
23271
+ label: "TTL",
23272
+ value: "ttl",
23273
+ icon: icon(IconClock11),
23274
+ content: /* @__PURE__ */ React233.createElement(TtlTab, { editor, block })
23263
23275
  }
23264
23276
  ];
23265
23277
  return /* @__PURE__ */ React233.createElement(BaseRightPanelLayout, { title: "Configuration", onClose: closePanel, tabs, context: { editor, block } });
@@ -23320,7 +23332,7 @@ var ActionTemplateView = ({ editor, block }) => {
23320
23332
  // src/mantine/blocks/action/flow/FlowView.tsx
23321
23333
  import React235, { useMemo as useMemo86, useState as useState88 } from "react";
23322
23334
  import { Group as Group87, Stack as Stack156, Text as Text132, Button as Button40, Code as Code7, Loader as Loader32, Alert as Alert32, Box as Box45, Divider as Divider21 } from "@mantine/core";
23323
- import { IconPlayerPlay as IconPlayerPlay2, IconAlertTriangle as IconAlertTriangle3, IconUser as IconUser13, IconBolt as IconBolt8 } from "@tabler/icons-react";
23335
+ import { IconPlayerPlay as IconPlayerPlay2, IconAlertTriangle as IconAlertTriangle3, IconUser as IconUser13, IconBolt as IconBolt8, IconShieldCheck as IconShieldCheck14 } from "@tabler/icons-react";
23324
23336
 
23325
23337
  // src/mantine/hooks/useAutoCommitOnExecute.ts
23326
23338
  import { useEffect as useEffect73, useRef as useRef21 } from "react";
@@ -23441,6 +23453,12 @@ var ActionFlowView = ({ editor, block, isDisabled }) => {
23441
23453
  }
23442
23454
  )
23443
23455
  },
23456
+ {
23457
+ label: "Authorization",
23458
+ value: "authorization",
23459
+ icon: /* @__PURE__ */ React235.createElement(IconShieldCheck14, { size: 18, color: ICON_COLOR }),
23460
+ content: /* @__PURE__ */ React235.createElement(AuthorizationTab, { editor, block })
23461
+ },
23444
23462
  {
23445
23463
  label: "Assignment",
23446
23464
  value: "assignment",
@@ -23944,7 +23962,7 @@ var HttpRequestFlowDetail = ({ inputs, editor, runtime, updateRuntime, isDisable
23944
23962
  };
23945
23963
 
23946
23964
  // src/mantine/blocks/action/actionTypes/httpRequest/index.ts
23947
- registerActionTypeUI("http.request", {
23965
+ registerActionTypeUI("qi/http.request", {
23948
23966
  configComponent: HttpRequestConfig,
23949
23967
  flowDetailComponent: HttpRequestFlowDetail
23950
23968
  });
@@ -24127,7 +24145,7 @@ var EmailSendConfig = ({ inputs, onInputsChange, editor, blockId }) => {
24127
24145
  };
24128
24146
 
24129
24147
  // src/mantine/blocks/action/actionTypes/emailSend/index.ts
24130
- registerActionTypeUI("email.send", {
24148
+ registerActionTypeUI("qi/email.send", {
24131
24149
  configComponent: EmailSendConfig
24132
24150
  });
24133
24151
 
@@ -24374,7 +24392,7 @@ var BidFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isDisabled
24374
24392
  if (!canSubmit) {
24375
24393
  return;
24376
24394
  }
24377
- const actionDef = getAction("bid");
24395
+ const actionDef = getAction("qi/bid.submit");
24378
24396
  if (!actionDef) {
24379
24397
  setError("Bid action is not registered");
24380
24398
  return;
@@ -24492,7 +24510,7 @@ var BidFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isDisabled
24492
24510
  };
24493
24511
 
24494
24512
  // src/mantine/blocks/action/actionTypes/bid/index.ts
24495
- registerActionTypeUI("bid", {
24513
+ registerActionTypeUI("qi/bid.submit", {
24496
24514
  configComponent: BidConfig,
24497
24515
  flowDetailComponent: BidFlowDetail
24498
24516
  });
@@ -24814,7 +24832,7 @@ var EvaluateBidFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, is
24814
24832
  setError("Rejection reason is required");
24815
24833
  return;
24816
24834
  }
24817
- const actionDef = getAction("evaluateBid");
24835
+ const actionDef = getAction("qi/bid.evaluate");
24818
24836
  if (!actionDef) {
24819
24837
  setError("evaluateBid action is not registered");
24820
24838
  return;
@@ -25067,7 +25085,7 @@ var EvaluateBidFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, is
25067
25085
  };
25068
25086
 
25069
25087
  // src/mantine/blocks/action/actionTypes/evaluateBid/index.ts
25070
- registerActionTypeUI("evaluateBid", {
25088
+ registerActionTypeUI("qi/bid.evaluate", {
25071
25089
  configComponent: EvaluateBidConfig,
25072
25090
  flowDetailComponent: EvaluateBidFlowDetail
25073
25091
  });
@@ -25388,7 +25406,7 @@ var ClaimFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isDisabl
25388
25406
  setError("Admin address could not be resolved for this collection");
25389
25407
  return;
25390
25408
  }
25391
- const actionDef = getAction("claim");
25409
+ const actionDef = getAction("qi/claim.submit");
25392
25410
  if (!actionDef) {
25393
25411
  setError("claim action is not registered");
25394
25412
  return;
@@ -25526,7 +25544,7 @@ var ClaimFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isDisabl
25526
25544
  };
25527
25545
 
25528
25546
  // src/mantine/blocks/action/actionTypes/claim/index.ts
25529
- registerActionTypeUI("claim", {
25547
+ registerActionTypeUI("qi/claim.submit", {
25530
25548
  configComponent: ClaimConfig,
25531
25549
  flowDetailComponent: ClaimFlowDetail
25532
25550
  });
@@ -25989,7 +26007,7 @@ var EvaluateClaimFlowDetail = ({ inputs, editor, block, runtime, updateRuntime,
25989
26007
  setError("Admin address could not be resolved for this collection");
25990
26008
  return;
25991
26009
  }
25992
- const actionDef = getAction("evaluateClaim");
26010
+ const actionDef = getAction("qi/claim.evaluate");
25993
26011
  if (!actionDef) {
25994
26012
  setError("evaluateClaim action is not registered");
25995
26013
  return;
@@ -26270,7 +26288,7 @@ var EvaluateClaimFlowDetail = ({ inputs, editor, block, runtime, updateRuntime,
26270
26288
  };
26271
26289
 
26272
26290
  // src/mantine/blocks/action/actionTypes/evaluateClaim/index.ts
26273
- registerActionTypeUI("evaluateClaim", {
26291
+ registerActionTypeUI("qi/claim.evaluate", {
26274
26292
  configComponent: EvaluateClaimConfig,
26275
26293
  flowDetailComponent: EvaluateClaimFlowDetail
26276
26294
  });
@@ -26542,7 +26560,7 @@ var ProposalCreateFlowDetail = ({ inputs, editor, block, runtime, updateRuntime,
26542
26560
  setError("Proposal description is required");
26543
26561
  return;
26544
26562
  }
26545
- const actionDef = getAction("proposal.create");
26563
+ const actionDef = getAction("qi/proposal.create");
26546
26564
  if (!actionDef) {
26547
26565
  setError("proposal.create action is not registered");
26548
26566
  return;
@@ -26691,7 +26709,7 @@ var ProposalCreateFlowDetail = ({ inputs, editor, block, runtime, updateRuntime,
26691
26709
  };
26692
26710
 
26693
26711
  // src/mantine/blocks/action/actionTypes/proposalCreate/index.ts
26694
- registerActionTypeUI("proposal.create", {
26712
+ registerActionTypeUI("qi/proposal.create", {
26695
26713
  configComponent: ProposalCreateConfig,
26696
26714
  flowDetailComponent: ProposalCreateFlowDetail
26697
26715
  });
@@ -26934,7 +26952,7 @@ var ProposalVoteFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, i
26934
26952
  }, [handlers, proposalContractAddress, proposalId]);
26935
26953
  const handleVote = useCallback83(async () => {
26936
26954
  if (!selectedVote || !proposalId || !proposalContractAddress || isDisabled || submitting) return;
26937
- const actionDef = getAction("proposal.vote");
26955
+ const actionDef = getAction("qi/proposal.vote");
26938
26956
  if (!actionDef) {
26939
26957
  setError("proposal.vote action is not registered");
26940
26958
  return;
@@ -27168,7 +27186,7 @@ var ProposalVoteFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, i
27168
27186
  };
27169
27187
 
27170
27188
  // src/mantine/blocks/action/actionTypes/proposalVote/index.ts
27171
- registerActionTypeUI("proposal.vote", {
27189
+ registerActionTypeUI("qi/proposal.vote", {
27172
27190
  configComponent: ProposalVoteConfig,
27173
27191
  flowDetailComponent: ProposalVoteFlowDetail
27174
27192
  });
@@ -27325,7 +27343,7 @@ var ProtocolSelectFlowDetail = ({ inputs, block, runtime, updateRuntime, isDisab
27325
27343
  };
27326
27344
 
27327
27345
  // src/mantine/blocks/action/actionTypes/protocolSelect/index.ts
27328
- registerActionTypeUI("protocol.select", {
27346
+ registerActionTypeUI("qi/protocol.select", {
27329
27347
  configComponent: ProtocolSelectConfig,
27330
27348
  flowDetailComponent: ProtocolSelectFlowDetail
27331
27349
  });
@@ -27468,7 +27486,7 @@ var DomainSignFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isD
27468
27486
  setError("No domain card data available. Ensure the domain card viewer block has pushed data to this action.");
27469
27487
  return;
27470
27488
  }
27471
- const actionDef = getAction("domain.sign");
27489
+ const actionDef = getAction("qi/domain.sign");
27472
27490
  if (!actionDef) {
27473
27491
  setError("domain.sign action is not registered");
27474
27492
  return;
@@ -27591,7 +27609,7 @@ var DomainSignFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isD
27591
27609
  };
27592
27610
 
27593
27611
  // src/mantine/blocks/action/actionTypes/domainSign/index.ts
27594
- registerActionTypeUI("domain.sign", {
27612
+ registerActionTypeUI("qi/domain.sign", {
27595
27613
  configComponent: DomainSignConfig,
27596
27614
  flowDetailComponent: DomainSignFlowDetail
27597
27615
  });
@@ -27706,7 +27724,7 @@ var DomainCreateFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, i
27706
27724
  }, [surveySchema]);
27707
27725
  const handleSurveyComplete = useCallback88(
27708
27726
  async (sender) => {
27709
- const actionDef = getAction("domain.create");
27727
+ const actionDef = getAction("qi/domain.create");
27710
27728
  if (!actionDef) {
27711
27729
  setError("domain.create action is not registered");
27712
27730
  return;
@@ -27802,7 +27820,7 @@ var DomainCreateFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, i
27802
27820
  };
27803
27821
 
27804
27822
  // src/mantine/blocks/action/actionTypes/domainCreate/index.ts
27805
- registerActionTypeUI("domain.create", {
27823
+ registerActionTypeUI("qi/domain.create", {
27806
27824
  configComponent: DomainCreateConfig,
27807
27825
  flowDetailComponent: DomainCreateFlowDetail
27808
27826
  });
@@ -28225,8 +28243,8 @@ var FormSubmitFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isD
28225
28243
  const handleSurveyComplete = useCallback94(
28226
28244
  async (sender) => {
28227
28245
  if (isDisabled || submitting) return;
28228
- const actionType = String(block?.props?.actionType || "form.submit");
28229
- const actionDef = getAction(actionType) || getAction("form.submit");
28246
+ const actionType = String(block?.props?.actionType || "qi/form.submit");
28247
+ const actionDef = getAction(actionType) || getAction("qi/form.submit");
28230
28248
  if (!actionDef) {
28231
28249
  setError(`${actionType} action is not registered`);
28232
28250
  return;
@@ -28333,11 +28351,11 @@ var FormSubmitFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isD
28333
28351
  };
28334
28352
 
28335
28353
  // src/mantine/blocks/action/actionTypes/formSubmit/index.ts
28336
- registerActionTypeUI("form.submit", {
28354
+ registerActionTypeUI("qi/form.submit", {
28337
28355
  configComponent: FormSubmitConfig,
28338
28356
  flowDetailComponent: FormSubmitFlowDetail
28339
28357
  });
28340
- registerActionTypeUI("human.form.submit", {
28358
+ registerActionTypeUI("qi/human.form.submit", {
28341
28359
  configComponent: FormSubmitConfig,
28342
28360
  flowDetailComponent: FormSubmitFlowDetail
28343
28361
  });
@@ -28421,7 +28439,7 @@ var CredentialStoreConfig = ({ inputs, onInputsChange, editor, blockId }) => {
28421
28439
  // src/mantine/blocks/action/actionTypes/credentialStore/CredentialStoreFlowDetail.tsx
28422
28440
  import React265, { useCallback as useCallback96, useMemo as useMemo106, useState as useState117 } from "react";
28423
28441
  import { Alert as Alert51, Button as Button49, Code as Code10, Loader as Loader51, Stack as Stack185, Text as Text155 } from "@mantine/core";
28424
- import { IconShieldCheck as IconShieldCheck14 } from "@tabler/icons-react";
28442
+ import { IconShieldCheck as IconShieldCheck15 } from "@tabler/icons-react";
28425
28443
  function safeParse(value) {
28426
28444
  let result = value;
28427
28445
  for (let i = 0; i < 2; i++) {
@@ -28488,7 +28506,7 @@ var CredentialStoreFlowDetail = ({ inputs, editor, block, runtime, updateRuntime
28488
28506
  const isCompleted = runtime.state === "completed";
28489
28507
  const handleExecute = useCallback96(async () => {
28490
28508
  if (isDisabled || submitting) return;
28491
- const actionDef = getAction("credential.store");
28509
+ const actionDef = getAction("qi/credential.store");
28492
28510
  if (!actionDef) {
28493
28511
  setError("credential.store action is not registered");
28494
28512
  return;
@@ -28574,11 +28592,11 @@ var CredentialStoreFlowDetail = ({ inputs, editor, block, runtime, updateRuntime
28574
28592
  updateRuntime,
28575
28593
  verifySignature
28576
28594
  ]);
28577
- return /* @__PURE__ */ React265.createElement(Stack185, { gap: "md" }, !hasKey && /* @__PURE__ */ React265.createElement(Alert51, { color: "yellow", styles: actionAlertStyles }, "No credential key configured. Set one in template mode."), hasKey && !hasCredential && !isCompleted && /* @__PURE__ */ React265.createElement(Alert51, { color: "yellow", styles: actionAlertStyles }, "Waiting for credential data. It will be provided by a block reference or at execution time."), hasKey && hasCredential && !isCompleted && /* @__PURE__ */ React265.createElement(Stack185, { gap: "xs" }, /* @__PURE__ */ React265.createElement(Text155, { size: "xs", c: "dimmed" }, "Credential key: ", resolvedCredentialKey), /* @__PURE__ */ React265.createElement(CredentialPreview, { value: resolvedCredential }), /* @__PURE__ */ React265.createElement(Button49, { leftSection: submitting ? /* @__PURE__ */ React265.createElement(Loader51, { size: 14 }) : /* @__PURE__ */ React265.createElement(IconShieldCheck14, { size: 14 }), onClick: handleExecute, disabled: isDisabled || submitting, size: "sm" }, submitting ? "Storing..." : "Store Credential")), isCompleted && /* @__PURE__ */ React265.createElement(Alert51, { color: runtime.output?.duplicate ? "yellow" : "green", styles: actionAlertStyles }, runtime.output?.duplicate ? `Credential already stored under key "${runtime.output?.credentialKey || resolvedCredentialKey}" (duplicate).` : `Credential stored successfully under key "${runtime.output?.credentialKey || resolvedCredentialKey}".`), error && /* @__PURE__ */ React265.createElement(Alert51, { color: "red", styles: actionAlertStyles }, error), runtime.error?.message && !error && /* @__PURE__ */ React265.createElement(Alert51, { color: "red", styles: actionAlertStyles }, runtime.error.message));
28595
+ return /* @__PURE__ */ React265.createElement(Stack185, { gap: "md" }, !hasKey && /* @__PURE__ */ React265.createElement(Alert51, { color: "yellow", styles: actionAlertStyles }, "No credential key configured. Set one in template mode."), hasKey && !hasCredential && !isCompleted && /* @__PURE__ */ React265.createElement(Alert51, { color: "yellow", styles: actionAlertStyles }, "Waiting for credential data. It will be provided by a block reference or at execution time."), hasKey && hasCredential && !isCompleted && /* @__PURE__ */ React265.createElement(Stack185, { gap: "xs" }, /* @__PURE__ */ React265.createElement(Text155, { size: "xs", c: "dimmed" }, "Credential key: ", resolvedCredentialKey), /* @__PURE__ */ React265.createElement(CredentialPreview, { value: resolvedCredential }), /* @__PURE__ */ React265.createElement(Button49, { leftSection: submitting ? /* @__PURE__ */ React265.createElement(Loader51, { size: 14 }) : /* @__PURE__ */ React265.createElement(IconShieldCheck15, { size: 14 }), onClick: handleExecute, disabled: isDisabled || submitting, size: "sm" }, submitting ? "Storing..." : "Store Credential")), isCompleted && /* @__PURE__ */ React265.createElement(Alert51, { color: runtime.output?.duplicate ? "yellow" : "green", styles: actionAlertStyles }, runtime.output?.duplicate ? `Credential already stored under key "${runtime.output?.credentialKey || resolvedCredentialKey}" (duplicate).` : `Credential stored successfully under key "${runtime.output?.credentialKey || resolvedCredentialKey}".`), error && /* @__PURE__ */ React265.createElement(Alert51, { color: "red", styles: actionAlertStyles }, error), runtime.error?.message && !error && /* @__PURE__ */ React265.createElement(Alert51, { color: "red", styles: actionAlertStyles }, runtime.error.message));
28578
28596
  };
28579
28597
 
28580
28598
  // src/mantine/blocks/action/actionTypes/credentialStore/index.ts
28581
- registerActionTypeUI("credential.store", {
28599
+ registerActionTypeUI("qi/credential.store", {
28582
28600
  configComponent: CredentialStoreConfig,
28583
28601
  flowDetailComponent: CredentialStoreFlowDetail
28584
28602
  });
@@ -28827,7 +28845,7 @@ var PaymentFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isDisa
28827
28845
  setError("No skill configured on this block.");
28828
28846
  return;
28829
28847
  }
28830
- const actionDef = getAction("payment");
28848
+ const actionDef = getAction("qi/payment.execute");
28831
28849
  if (!actionDef) {
28832
28850
  setError("Payment action is not registered");
28833
28851
  return;
@@ -28973,7 +28991,7 @@ var PaymentFlowDetail = ({ inputs, editor, block, runtime, updateRuntime, isDisa
28973
28991
  };
28974
28992
 
28975
28993
  // src/mantine/blocks/action/actionTypes/payment/index.ts
28976
- registerActionTypeUI("payment", {
28994
+ registerActionTypeUI("qi/payment.execute", {
28977
28995
  configComponent: PaymentConfig,
28978
28996
  flowDetailComponent: PaymentFlowDetail
28979
28997
  });
@@ -29081,7 +29099,7 @@ var MatrixDmConfig = ({ inputs, onInputsChange, editor }) => {
29081
29099
  };
29082
29100
 
29083
29101
  // src/mantine/blocks/action/actionTypes/matrixDm/index.ts
29084
- registerActionTypeUI("matrix.dm", {
29102
+ registerActionTypeUI("qi/matrix.dm", {
29085
29103
  configComponent: MatrixDmConfig
29086
29104
  });
29087
29105
 
@@ -30739,7 +30757,7 @@ function useCollaborativeYDoc(_options) {
30739
30757
  }
30740
30758
 
30741
30759
  // src/mantine/hooks/useCollaborativeIxoEditor.ts
30742
- import { useMemo as useMemo117, useEffect as useEffect105, useState as useState128, useRef as useRef26 } from "react";
30760
+ import { useMemo as useMemo117, useEffect as useEffect106, useState as useState128, useRef as useRef27 } from "react";
30743
30761
 
30744
30762
  // src/core/lib/matrixMetadata.ts
30745
30763
  var COVER_IMAGE_EVENT_TYPE = "ixo.page.cover_image";
@@ -30896,6 +30914,200 @@ var MatrixMetadataManager = class {
30896
30914
  }
30897
30915
  };
30898
30916
 
30917
+ // src/core/lib/matrixThreadLog.ts
30918
+ var THREAD_STATE_EVENT_TYPE = "ixo.flow.thread";
30919
+ function getThreadRootFromState(matrixClient, roomId, threadType) {
30920
+ try {
30921
+ const room = matrixClient.getRoom(roomId);
30922
+ if (!room) return null;
30923
+ const stateEvent = room.currentState.getStateEvents(THREAD_STATE_EVENT_TYPE, threadType);
30924
+ if (!stateEvent) return null;
30925
+ const content = stateEvent.getContent();
30926
+ return content?.thread_root_event_id || null;
30927
+ } catch {
30928
+ return null;
30929
+ }
30930
+ }
30931
+ async function createThreadRoot(matrixClient, roomId, threadType) {
30932
+ const response = await matrixClient.sendEvent(roomId, "m.room.message", {
30933
+ msgtype: "m.text",
30934
+ body: `[${threadType} log]`
30935
+ });
30936
+ const eventId = response.event_id;
30937
+ try {
30938
+ await matrixClient.sendStateEvent(roomId, THREAD_STATE_EVENT_TYPE, { thread_root_event_id: eventId }, threadType);
30939
+ } catch {
30940
+ }
30941
+ return eventId;
30942
+ }
30943
+ var threadRootCache = /* @__PURE__ */ new Map();
30944
+ var pendingCreation = /* @__PURE__ */ new Map();
30945
+ function cacheKey(roomId, threadType) {
30946
+ return `${roomId}:${threadType}`;
30947
+ }
30948
+ async function ensureThreadRoot(matrixClient, roomId, threadType) {
30949
+ const key = cacheKey(roomId, threadType);
30950
+ const cached = threadRootCache.get(key);
30951
+ if (cached) return cached;
30952
+ const pending = pendingCreation.get(key);
30953
+ if (pending) return pending;
30954
+ const existing = getThreadRootFromState(matrixClient, roomId, threadType);
30955
+ if (existing) {
30956
+ threadRootCache.set(key, existing);
30957
+ return existing;
30958
+ }
30959
+ const promise = createThreadRoot(matrixClient, roomId, threadType).then((eventId) => {
30960
+ threadRootCache.set(key, eventId);
30961
+ pendingCreation.delete(key);
30962
+ return eventId;
30963
+ }).catch((error) => {
30964
+ pendingCreation.delete(key);
30965
+ throw error;
30966
+ });
30967
+ pendingCreation.set(key, promise);
30968
+ return promise;
30969
+ }
30970
+ async function appendToThread(matrixClient, roomId, threadType, payload) {
30971
+ const threadRootId = await ensureThreadRoot(matrixClient, roomId, threadType);
30972
+ await matrixClient.sendEvent(roomId, "m.room.message", {
30973
+ msgtype: "m.text",
30974
+ body: JSON.stringify(payload),
30975
+ "m.relates_to": {
30976
+ rel_type: "m.thread",
30977
+ event_id: threadRootId
30978
+ }
30979
+ });
30980
+ }
30981
+ function logDelegation(matrixClient, roomId, delegation) {
30982
+ appendToThread(matrixClient, roomId, "delegations", {
30983
+ type: "delegation",
30984
+ cid: delegation.cid,
30985
+ issuerDid: delegation.issuerDid,
30986
+ audienceDid: delegation.audienceDid,
30987
+ capabilities: delegation.capabilities,
30988
+ expiration: delegation.expiration,
30989
+ createdAt: delegation.createdAt,
30990
+ format: delegation.format,
30991
+ proofCids: delegation.proofCids
30992
+ }).catch((error) => {
30993
+ console.warn("[MatrixThreadLog] Failed to log delegation:", delegation.cid, error);
30994
+ });
30995
+ }
30996
+ function logInvocation(matrixClient, roomId, invocation) {
30997
+ appendToThread(matrixClient, roomId, "invocations", {
30998
+ type: "invocation",
30999
+ cid: invocation.cid,
31000
+ invokerDid: invocation.invokerDid,
31001
+ capability: invocation.capability,
31002
+ executedAt: invocation.executedAt,
31003
+ flowId: invocation.flowId,
31004
+ blockId: invocation.blockId,
31005
+ result: invocation.result,
31006
+ error: invocation.error,
31007
+ proofCids: invocation.proofCids,
31008
+ claimId: invocation.claimId
31009
+ }).catch((error) => {
31010
+ console.warn("[MatrixThreadLog] Failed to log invocation:", invocation.cid, error);
31011
+ });
31012
+ }
31013
+
31014
+ // src/mantine/hooks/useFlowLifecycle.ts
31015
+ import { useEffect as useEffect105, useCallback as useCallback106, useRef as useRef26 } from "react";
31016
+
31017
+ // src/mantine/hooks/useFlowTTLCleanup.ts
31018
+ function performTTLCleanup(editor) {
31019
+ const runtimeMap = editor._yRuntime;
31020
+ if (!runtimeMap) return;
31021
+ const blocks = editor.document || [];
31022
+ const now = Date.now();
31023
+ const runtimeManager = createRuntimeStateManager(editor);
31024
+ for (const block of blocks) {
31025
+ const props = block.props;
31026
+ const blockId = block.id;
31027
+ if (!props) continue;
31028
+ const runtimeState = runtimeManager.get(blockId);
31029
+ if (!runtimeState.enabledAt) {
31030
+ try {
31031
+ const flowNode = buildFlowNodeFromBlock(block);
31032
+ if (!flowNode.activationCondition || isNodeActive(flowNode, runtimeManager).active) {
31033
+ runtimeManager.update(blockId, { enabledAt: now });
31034
+ }
31035
+ } catch {
31036
+ }
31037
+ }
31038
+ if (runtimeState.state === "completed") continue;
31039
+ let clearAssignment = false;
31040
+ let clearCommitment = false;
31041
+ if (props.ttlAbsoluteDueDate) {
31042
+ const dueMs = new Date(props.ttlAbsoluteDueDate).getTime();
31043
+ if (!isNaN(dueMs) && dueMs <= now) {
31044
+ clearAssignment = true;
31045
+ clearCommitment = true;
31046
+ }
31047
+ }
31048
+ if (!clearCommitment && props.commitment) {
31049
+ let commitment;
31050
+ try {
31051
+ commitment = typeof props.commitment === "string" ? JSON.parse(props.commitment) : props.commitment;
31052
+ } catch {
31053
+ }
31054
+ if (commitment?.commitmentExpiresAt) {
31055
+ const expiresMs = new Date(commitment.commitmentExpiresAt).getTime();
31056
+ if (!isNaN(expiresMs) && expiresMs <= now) {
31057
+ clearCommitment = true;
31058
+ }
31059
+ }
31060
+ }
31061
+ if ((!clearAssignment || !clearCommitment) && props.ttlFromEnablement) {
31062
+ const refreshedState = runtimeManager.get(blockId);
31063
+ if (refreshedState.enabledAt) {
31064
+ const ttlMs = durationToMs(props.ttlFromEnablement);
31065
+ if (ttlMs > 0 && refreshedState.enabledAt + ttlMs <= now) {
31066
+ clearAssignment = true;
31067
+ clearCommitment = true;
31068
+ }
31069
+ }
31070
+ }
31071
+ const propUpdates = {};
31072
+ if (clearAssignment && props.assignment) {
31073
+ let assignment;
31074
+ try {
31075
+ assignment = typeof props.assignment === "string" ? JSON.parse(props.assignment) : props.assignment;
31076
+ } catch {
31077
+ }
31078
+ if (assignment?.assignedActor?.did) {
31079
+ propUpdates.assignment = JSON.stringify({
31080
+ assignedActor: { did: "", avatar: "", displayName: "" },
31081
+ assignedBy: { did: "", avatar: "", displayName: "" },
31082
+ assignedTimestamp: ""
31083
+ });
31084
+ console.log(`[FlowTTL] Cleared expired assignment on block ${blockId}`);
31085
+ }
31086
+ }
31087
+ if (clearCommitment && props.commitment) {
31088
+ let commitment;
31089
+ try {
31090
+ commitment = typeof props.commitment === "string" ? JSON.parse(props.commitment) : props.commitment;
31091
+ } catch {
31092
+ }
31093
+ if (commitment?.committedActor?.did) {
31094
+ propUpdates.commitment = JSON.stringify({
31095
+ committedActor: { did: "", avatar: "", displayName: "" },
31096
+ committedTimestamp: "",
31097
+ commitmentExpiresAt: ""
31098
+ });
31099
+ console.log(`[FlowTTL] Cleared expired commitment on block ${blockId}`);
31100
+ }
31101
+ }
31102
+ if (Object.keys(propUpdates).length > 0) {
31103
+ const currentBlock = (editor.document || []).find((b) => b.id === blockId) || block;
31104
+ editor.updateBlock(currentBlock, {
31105
+ props: { ...currentBlock.props, ...propUpdates }
31106
+ });
31107
+ }
31108
+ }
31109
+ }
31110
+
30899
31111
  // src/core/lib/flowEngine/dmNotificationState.ts
30900
31112
  var DM_NOTIFICATIONS_KEY = "__dm_notifications";
30901
31113
  function getDMNotificationState(runtimeMap) {
@@ -30916,6 +31128,128 @@ function shouldNotify(state, blockId, currentAssignedDid) {
30916
31128
  return existing.assignedDid !== currentAssignedDid;
30917
31129
  }
30918
31130
 
31131
+ // src/mantine/hooks/useFlowLoadDMNotifications.ts
31132
+ async function performDMNotificationScan(editor) {
31133
+ const matrixClient = editor.getMatrixClient?.();
31134
+ const runtimeMap = editor._yRuntime;
31135
+ if (!matrixClient || !runtimeMap) return;
31136
+ const currentUserId = matrixClient.getUserId();
31137
+ if (!currentUserId) return;
31138
+ const blocks = editor.document || [];
31139
+ const dedupState = getDMNotificationState(runtimeMap);
31140
+ const flowMetadata = editor.getFlowMetadata?.();
31141
+ const flowTitle = flowMetadata?.title || "Untitled Flow";
31142
+ const roomId = editor.getRoomId?.() || "";
31143
+ const selfDid = currentUserId.split(":")[0].replace("@", "").replace(/-/g, ":");
31144
+ const notifications = [];
31145
+ for (const block of blocks) {
31146
+ const props = block.props;
31147
+ if (!props?.assignment) continue;
31148
+ let assignment;
31149
+ try {
31150
+ assignment = typeof props.assignment === "string" ? JSON.parse(props.assignment) : props.assignment;
31151
+ } catch {
31152
+ continue;
31153
+ }
31154
+ const assignedDid = assignment?.assignedActor?.did;
31155
+ if (!assignedDid) continue;
31156
+ if (assignedDid === selfDid) continue;
31157
+ if (!shouldNotify(dedupState, block.id, assignedDid)) continue;
31158
+ if (!isBlockEnabledInFlow(block, blocks)) continue;
31159
+ if (!isBlockActivated(block, editor)) continue;
31160
+ const blockType = block.type || "block";
31161
+ const blockId = block.id;
31162
+ const message = `Action needed: You have been assigned to a "${blockType}" block in flow "${flowTitle}".${roomId ? ` Room: ${roomId}` : ""}`;
31163
+ notifications.push(
31164
+ sendDirectMessage(matrixClient, assignedDid, message).then(() => {
31165
+ setDMNotificationRecord(runtimeMap, blockId, {
31166
+ assignedDid,
31167
+ notifiedAt: Date.now(),
31168
+ notifiedBy: currentUserId
31169
+ });
31170
+ console.log(`[FlowDM] Notified ${assignedDid} for block ${blockId}`);
31171
+ }).catch((error) => {
31172
+ console.error(`[FlowDM] Failed to notify ${assignedDid} for block ${blockId}:`, error);
31173
+ })
31174
+ );
31175
+ }
31176
+ if (notifications.length > 0) {
31177
+ await Promise.allSettled(notifications);
31178
+ console.log(`[FlowDM] Processed ${notifications.length} DM notification(s)`);
31179
+ }
31180
+ }
31181
+ function isBlockEnabledInFlow(block, editorDocument) {
31182
+ const conditionConfig = parseConditionConfig(block.props?.conditions);
31183
+ if (!conditionConfig.enabled || conditionConfig.conditions.length === 0) {
31184
+ return true;
31185
+ }
31186
+ const { actions } = evaluateBlockConditions(conditionConfig, editorDocument);
31187
+ if (hasVisibilityConditions(conditionConfig)) {
31188
+ const showActionExists = actions.some((a) => a.action === "show");
31189
+ if (!showActionExists) return false;
31190
+ }
31191
+ if (hasEnableConditions(conditionConfig)) {
31192
+ const enableActionExists = actions.some((a) => a.action === "enable");
31193
+ if (!enableActionExists) return false;
31194
+ }
31195
+ return true;
31196
+ }
31197
+ function isBlockActivated(block, editor) {
31198
+ try {
31199
+ const flowNode = buildFlowNodeFromBlock(block);
31200
+ if (!flowNode.activationCondition) return true;
31201
+ const runtimeManager = createRuntimeStateManager(editor);
31202
+ const result = isNodeActive(flowNode, runtimeManager);
31203
+ return result.active;
31204
+ } catch {
31205
+ return true;
31206
+ }
31207
+ }
31208
+
31209
+ // src/mantine/hooks/useFlowLifecycle.ts
31210
+ var DEFAULT_INTERVAL_MS = 3e4;
31211
+ function useFlowLifecycle({ editor, connectionStatus, enabled = true }) {
31212
+ const hasRunInitialRef = useRef26(false);
31213
+ const runningRef = useRef26(false);
31214
+ const runPipeline = useCallback106(async () => {
31215
+ if (!editor || runningRef.current) return;
31216
+ runningRef.current = true;
31217
+ try {
31218
+ performTTLCleanup(editor);
31219
+ await performDMNotificationScan(editor);
31220
+ } catch (error) {
31221
+ console.error("[FlowLifecycle] Pipeline error:", error);
31222
+ } finally {
31223
+ runningRef.current = false;
31224
+ }
31225
+ }, [editor]);
31226
+ useEffect105(() => {
31227
+ if (!enabled || !editor || connectionStatus !== "connected" || hasRunInitialRef.current) return;
31228
+ if (editor.docType !== "flow") return;
31229
+ hasRunInitialRef.current = true;
31230
+ runPipeline();
31231
+ }, [editor, connectionStatus, enabled, runPipeline]);
31232
+ useEffect105(() => {
31233
+ if (!enabled || !editor || connectionStatus !== "connected") return;
31234
+ if (editor.docType !== "flow") return;
31235
+ const id = setInterval(runPipeline, DEFAULT_INTERVAL_MS);
31236
+ return () => clearInterval(id);
31237
+ }, [editor, connectionStatus, enabled, runPipeline]);
31238
+ useEffect105(() => {
31239
+ if (!enabled || !editor || connectionStatus !== "connected") return;
31240
+ if (editor.docType !== "flow") return;
31241
+ const runtimeMap = editor._yRuntime;
31242
+ if (!runtimeMap) return;
31243
+ const observer = () => {
31244
+ runPipeline();
31245
+ };
31246
+ runtimeMap.observe(observer);
31247
+ return () => {
31248
+ runtimeMap.unobserve(observer);
31249
+ };
31250
+ }, [editor, connectionStatus, enabled, runPipeline]);
31251
+ }
31252
+
30919
31253
  // src/mantine/hooks/useCollaborativeIxoEditor.ts
30920
31254
  var ROOT_CAPABILITY_KEY = "__root__";
30921
31255
  function useCreateCollaborativeIxoEditor(options) {
@@ -30953,7 +31287,7 @@ function useCreateCollaborativeIxoEditor(options) {
30953
31287
  roomId: options.roomId
30954
31288
  });
30955
31289
  const metadataManager = useMemo117(() => new MatrixMetadataManager(matrixClient, options.roomId), [matrixClient, options.roomId]);
30956
- useEffect105(() => {
31290
+ useEffect106(() => {
30957
31291
  return () => {
30958
31292
  metadataManager.dispose();
30959
31293
  };
@@ -30993,8 +31327,24 @@ function useCreateCollaborativeIxoEditor(options) {
30993
31327
  const runtimeMap = useMemo117(() => yDoc.getMap("runtime"), [yDoc]);
30994
31328
  const delegationsMap = useMemo117(() => yDoc.getMap("delegations"), [yDoc]);
30995
31329
  const invocationsMap = useMemo117(() => yDoc.getMap("invocations"), [yDoc]);
30996
- const ucanDelegationStore = useMemo117(() => createUcanDelegationStore(delegationsMap), [delegationsMap]);
30997
- const invocationStore = useMemo117(() => createInvocationStore(invocationsMap), [invocationsMap]);
31330
+ const ucanDelegationStore = useMemo117(() => {
31331
+ const store = createUcanDelegationStore(delegationsMap);
31332
+ const originalSet = store.set;
31333
+ store.set = (delegation) => {
31334
+ originalSet(delegation);
31335
+ logDelegation(matrixClient, options.roomId, delegation);
31336
+ };
31337
+ return store;
31338
+ }, [delegationsMap, matrixClient, options.roomId]);
31339
+ const invocationStore = useMemo117(() => {
31340
+ const store = createInvocationStore(invocationsMap);
31341
+ const originalAdd = store.add;
31342
+ store.add = (invocation) => {
31343
+ originalAdd(invocation);
31344
+ logInvocation(matrixClient, options.roomId, invocation);
31345
+ };
31346
+ return store;
31347
+ }, [invocationsMap, matrixClient, options.roomId]);
30998
31348
  const userFragment = useMemo117(() => yDoc.getMap(memoizedUser.id), [yDoc, memoizedUser.id]);
30999
31349
  const collaborationConfig = useMemo117(
31000
31350
  () => ({
@@ -31108,6 +31458,17 @@ function useCreateCollaborativeIxoEditor(options) {
31108
31458
  return;
31109
31459
  }
31110
31460
  delegationsMap.set(capability.id, JSON.stringify(capability));
31461
+ logDelegation(matrixClient, options.roomId, {
31462
+ cid: capability.id,
31463
+ delegation: "",
31464
+ issuerDid: capability.issuer,
31465
+ audienceDid: capability.audience,
31466
+ capabilities: capability.capabilities,
31467
+ expiration: capability.expiration,
31468
+ createdAt: new Date(capability.issuedAt).getTime() || Date.now(),
31469
+ format: "legacy",
31470
+ proofCids: capability.proofs || []
31471
+ });
31111
31472
  };
31112
31473
  ixoEditor.getRootCapability = () => {
31113
31474
  const rootId = delegationsMap.get(ROOT_CAPABILITY_KEY);
@@ -31220,12 +31581,12 @@ function useCreateCollaborativeIxoEditor(options) {
31220
31581
  return void 0;
31221
31582
  };
31222
31583
  }
31223
- useEffect105(() => {
31584
+ useEffect106(() => {
31224
31585
  if (ixoEditor) {
31225
31586
  ixoEditor.isEditable = editable;
31226
31587
  }
31227
31588
  }, [ixoEditor, editable]);
31228
- useEffect105(() => {
31589
+ useEffect106(() => {
31229
31590
  if (connectionStatus !== "connected") {
31230
31591
  return;
31231
31592
  }
@@ -31248,9 +31609,9 @@ function useCreateCollaborativeIxoEditor(options) {
31248
31609
  }
31249
31610
  }, [connectionStatus, root, titleText, permissions.write, options.docId, options.title, memoizedUser.id]);
31250
31611
  const [connectedUsers, setConnectedUsers] = useState128([]);
31251
- const activeBlockIdRef = useRef26(null);
31612
+ const activeBlockIdRef = useRef27(null);
31252
31613
  const awarenessInstance = matrixProvider?.awarenessInstance ?? null;
31253
- useEffect105(() => {
31614
+ useEffect106(() => {
31254
31615
  if (!awarenessInstance || connectionStatus !== "connected") {
31255
31616
  return;
31256
31617
  }
@@ -31268,7 +31629,7 @@ function useCreateCollaborativeIxoEditor(options) {
31268
31629
  awarenessInstance.off("change", updateUsers);
31269
31630
  };
31270
31631
  }, [awarenessInstance, connectionStatus]);
31271
- useEffect105(() => {
31632
+ useEffect106(() => {
31272
31633
  if (!awarenessInstance || connectionStatus !== "connected") {
31273
31634
  return;
31274
31635
  }
@@ -31296,59 +31657,7 @@ function useCreateCollaborativeIxoEditor(options) {
31296
31657
  awarenessInstance.setLocalState(null);
31297
31658
  };
31298
31659
  }, [awarenessInstance, connectionStatus, memoizedUser.id, memoizedUser.name, memoizedUser.color, memoizedUser.avatar]);
31299
- const dmSentRef = useRef26(false);
31300
- useEffect105(() => {
31301
- if (!ixoEditor || connectionStatus !== "connected" || dmSentRef.current) return;
31302
- if (ixoEditor.docType !== "flow") return;
31303
- const mx = ixoEditor.getMatrixClient?.();
31304
- const runtime = ixoEditor._yRuntime;
31305
- const currentUserId = mx?.getUserId();
31306
- if (!mx || !runtime || !currentUserId) return;
31307
- dmSentRef.current = true;
31308
- const sendNotifications = async () => {
31309
- const blocks = ixoEditor?.document || [];
31310
- const dedupState = getDMNotificationState(runtime);
31311
- const flowTitle = ixoEditor?.getFlowMetadata?.()?.title || "Untitled Flow";
31312
- const roomId = ixoEditor?.getRoomId?.() || "";
31313
- const selfDid = currentUserId.split(":")[0].replace("@", "").replace(/-/g, ":");
31314
- const notifications = [];
31315
- for (const block of blocks) {
31316
- const props = block.props;
31317
- if (!props?.assignment) continue;
31318
- let assignment;
31319
- try {
31320
- assignment = typeof props.assignment === "string" ? JSON.parse(props.assignment) : props.assignment;
31321
- } catch {
31322
- continue;
31323
- }
31324
- const assignedDid = assignment?.assignedActor?.did;
31325
- if (!assignedDid || assignedDid === selfDid) continue;
31326
- if (!shouldNotify(dedupState, block.id, assignedDid)) continue;
31327
- const blockType = block.type || "block";
31328
- const blockId = block.id;
31329
- const message = `Action needed: You have been assigned to a "${blockType}" block in flow "${flowTitle}".${roomId ? ` Room: ${roomId}` : ""}`;
31330
- notifications.push(
31331
- sendDirectMessage(mx, assignedDid, message).then(() => {
31332
- setDMNotificationRecord(runtime, blockId, {
31333
- assignedDid,
31334
- notifiedAt: Date.now(),
31335
- notifiedBy: currentUserId
31336
- });
31337
- console.log(`[FlowDM] Notified ${assignedDid} for block ${blockId}`);
31338
- }).catch((error) => {
31339
- console.error(`[FlowDM] Failed to notify ${assignedDid} for block ${blockId}:`, error);
31340
- })
31341
- );
31342
- }
31343
- if (notifications.length > 0) {
31344
- await Promise.allSettled(notifications);
31345
- console.log(`[FlowDM] Processed ${notifications.length} DM notification(s)`);
31346
- }
31347
- };
31348
- sendNotifications().catch((error) => {
31349
- console.error("[FlowDM] Unexpected error in sendNotifications:", error);
31350
- });
31351
- }, [ixoEditor, connectionStatus]);
31660
+ useFlowLifecycle({ editor: ixoEditor, connectionStatus, enabled: permissions.write });
31352
31661
  return {
31353
31662
  editor: ixoEditor,
31354
31663
  connectionStatus,
@@ -31362,7 +31671,7 @@ function useCreateCollaborativeIxoEditor(options) {
31362
31671
  }
31363
31672
 
31364
31673
  // src/mantine/IxoEditor.tsx
31365
- import React295, { useState as useState134, useEffect as useEffect111, useCallback as useCallback108 } from "react";
31674
+ import React295, { useState as useState134, useEffect as useEffect112, useCallback as useCallback109 } from "react";
31366
31675
  import { SuggestionMenuController } from "@blocknote/react";
31367
31676
  import { BlockNoteView } from "@blocknote/mantine";
31368
31677
  import { filterSuggestionItems } from "@blocknote/core";
@@ -31419,7 +31728,7 @@ function PanelContent({ theme }) {
31419
31728
  }
31420
31729
 
31421
31730
  // src/mantine/components/CoverImage.tsx
31422
- import React292, { useState as useState131, useRef as useRef27, useEffect as useEffect108, useMemo as useMemo120 } from "react";
31731
+ import React292, { useState as useState131, useRef as useRef28, useEffect as useEffect109, useMemo as useMemo120 } from "react";
31423
31732
  import { Box as Box60, Group as Group107 } from "@mantine/core";
31424
31733
 
31425
31734
  // src/core/lib/imageTransform.ts
@@ -31578,7 +31887,7 @@ var CoverImageButton = forwardRef(({ isActive = false, onClick, children, style,
31578
31887
  CoverImageButton.displayName = "CoverImageButton";
31579
31888
 
31580
31889
  // src/mantine/components/Base/BaseIconPicker.tsx
31581
- import React289, { useState as useState129, useMemo as useMemo118, useEffect as useEffect106 } from "react";
31890
+ import React289, { useState as useState129, useMemo as useMemo118, useEffect as useEffect107 } from "react";
31582
31891
  import { TextInput as TextInput8, Tabs as Tabs4, Box as Box57, Stack as Stack195, UnstyledButton as UnstyledButton5, Text as Text166, Center as Center13, ScrollArea as ScrollArea9, Group as Group105, Popover as Popover6 } from "@mantine/core";
31583
31892
  import * as TablerIcons from "@tabler/icons-react";
31584
31893
  import { IconSearch as IconSearch7, IconX as IconX14, IconChevronLeft, IconChevronRight as IconChevronRight14 } from "@tabler/icons-react";
@@ -31623,7 +31932,7 @@ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children
31623
31932
  const query = searchQuery.toLowerCase();
31624
31933
  return allIcons.filter(([name]) => name.toLowerCase().includes(query));
31625
31934
  }, [allIcons, searchQuery]);
31626
- useEffect106(() => {
31935
+ useEffect107(() => {
31627
31936
  setCurrentPage(1);
31628
31937
  }, [searchQuery]);
31629
31938
  const paginatedIcons = useMemo118(() => {
@@ -31786,14 +32095,14 @@ function PageIcon({ src, iconSize = 64, useCenter = false, style }) {
31786
32095
  import { useDisclosure as useDisclosure7 } from "@mantine/hooks";
31787
32096
 
31788
32097
  // src/mantine/components/FlowSettingsPanel.tsx
31789
- import React291, { useState as useState130, useEffect as useEffect107, useCallback as useCallback106 } from "react";
32098
+ import React291, { useState as useState130, useEffect as useEffect108, useCallback as useCallback107 } from "react";
31790
32099
  import { Stack as Stack196, Group as Group106, Button as Button52, ActionIcon as ActionIcon37, Text as Text167, Box as Box59 } from "@mantine/core";
31791
32100
  import { IconPlus as IconPlus11, IconTrash as IconTrash10 } from "@tabler/icons-react";
31792
32101
  var SYSTEM_KEYS = /* @__PURE__ */ new Set(["@context", "_type", "schema_version", "doc_id", "title", "createdAt", "createdBy", "flowOwnerDid"]);
31793
32102
  var FlowSettingsPanel = ({ editor }) => {
31794
32103
  const { closePanel } = usePanelStore();
31795
32104
  const [rows, setRows] = useState130([]);
31796
- const loadSettings = useCallback106(() => {
32105
+ const loadSettings = useCallback107(() => {
31797
32106
  const metadata = editor.getFlowMetadata?.();
31798
32107
  if (!metadata) return;
31799
32108
  const customRows = [];
@@ -31804,10 +32113,10 @@ var FlowSettingsPanel = ({ editor }) => {
31804
32113
  }
31805
32114
  setRows(customRows);
31806
32115
  }, [editor]);
31807
- useEffect107(() => {
32116
+ useEffect108(() => {
31808
32117
  loadSettings();
31809
32118
  }, [loadSettings]);
31810
- const handleKeyChange = useCallback106(
32119
+ const handleKeyChange = useCallback107(
31811
32120
  (index, newKey) => {
31812
32121
  setRows((prev) => {
31813
32122
  const updated = [...prev];
@@ -31824,7 +32133,7 @@ var FlowSettingsPanel = ({ editor }) => {
31824
32133
  },
31825
32134
  [editor]
31826
32135
  );
31827
- const handleValueChange = useCallback106(
32136
+ const handleValueChange = useCallback107(
31828
32137
  (index, newValue) => {
31829
32138
  setRows((prev) => {
31830
32139
  const updated = [...prev];
@@ -31838,10 +32147,10 @@ var FlowSettingsPanel = ({ editor }) => {
31838
32147
  },
31839
32148
  [editor]
31840
32149
  );
31841
- const handleAdd = useCallback106(() => {
32150
+ const handleAdd = useCallback107(() => {
31842
32151
  setRows((prev) => [...prev, { key: "", value: "" }]);
31843
32152
  }, []);
31844
- const handleDelete = useCallback106(
32153
+ const handleDelete = useCallback107(
31845
32154
  (index) => {
31846
32155
  setRows((prev) => {
31847
32156
  const row = prev[index];
@@ -31863,13 +32172,13 @@ function CoverImage({ coverImageUrl, logoUrl }) {
31863
32172
  const [isHovering, setIsHovering] = useState131(false);
31864
32173
  const [isRepositioning, setIsRepositioning] = useState131(false);
31865
32174
  const [coverPosition, setCoverPosition] = useState131(() => editor?.getPageMetadata?.()?.coverPosition ?? 50);
31866
- const coverFileInputRef = useRef27(null);
31867
- const logoFileInputRef = useRef27(null);
32175
+ const coverFileInputRef = useRef28(null);
32176
+ const logoFileInputRef = useRef28(null);
31868
32177
  const [opened, { open, close }] = useDisclosure7(false);
31869
32178
  const [metadata, setMetadata] = useState131(() => editor?.getPageMetadata?.() || null);
31870
32179
  const settingsPanelContent = useMemo120(() => editor ? /* @__PURE__ */ React292.createElement(FlowSettingsPanel, { editor }) : null, [editor]);
31871
32180
  const { open: openSettings } = usePanel("flow-settings-panel", settingsPanelContent);
31872
- useEffect108(() => {
32181
+ useEffect109(() => {
31873
32182
  if (!editor?._metadataManager) {
31874
32183
  return;
31875
32184
  }
@@ -32183,7 +32492,7 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32183
32492
  }
32184
32493
 
32185
32494
  // src/mantine/components/PageHeader.tsx
32186
- import React293, { useState as useState132, useRef as useRef28, useEffect as useEffect109 } from "react";
32495
+ import React293, { useState as useState132, useRef as useRef29, useEffect as useEffect110 } from "react";
32187
32496
  function PageHeader({
32188
32497
  title = "New page",
32189
32498
  icon: icon2,
@@ -32197,9 +32506,9 @@ function PageHeader({
32197
32506
  }) {
32198
32507
  const [isMenuOpen, setIsMenuOpen] = useState132(false);
32199
32508
  const [isPrivacyOpen, setIsPrivacyOpen] = useState132(false);
32200
- const menuRef = useRef28(null);
32201
- const privacyRef = useRef28(null);
32202
- useEffect109(() => {
32509
+ const menuRef = useRef29(null);
32510
+ const privacyRef = useRef29(null);
32511
+ useEffect110(() => {
32203
32512
  function handleClickOutside(event) {
32204
32513
  if (menuRef.current && !menuRef.current.contains(event.target)) {
32205
32514
  setIsMenuOpen(false);
@@ -32397,7 +32706,7 @@ var styles = {
32397
32706
  };
32398
32707
 
32399
32708
  // src/mantine/components/ExternalDropZone.tsx
32400
- import React294, { useCallback as useCallback107, useEffect as useEffect110, useRef as useRef29, useState as useState133 } from "react";
32709
+ import React294, { useCallback as useCallback108, useEffect as useEffect111, useRef as useRef30, useState as useState133 } from "react";
32401
32710
  import { Box as Box61 } from "@mantine/core";
32402
32711
  var SCROLL_ZONE_SIZE = 80;
32403
32712
  var SCROLL_SPEED = 12;
@@ -32410,20 +32719,20 @@ var ExternalDropZone = ({
32410
32719
  onPlacementCancel,
32411
32720
  children
32412
32721
  }) => {
32413
- const containerRef = useRef29(null);
32722
+ const containerRef = useRef30(null);
32414
32723
  const [isValidDrag, setIsValidDrag] = useState133(false);
32415
32724
  const [isHoveringInPlacementMode, setIsHoveringInPlacementMode] = useState133(false);
32416
32725
  const [indicatorStyle, setIndicatorStyle] = useState133({});
32417
- const dropPositionRef = useRef29(null);
32418
- const scrollAnimationRef = useRef29(null);
32419
- const scrollDirectionRef = useRef29(null);
32420
- const scrollContainerRef = useRef29(null);
32421
- const getBlockElements = useCallback107(() => {
32726
+ const dropPositionRef = useRef30(null);
32727
+ const scrollAnimationRef = useRef30(null);
32728
+ const scrollDirectionRef = useRef30(null);
32729
+ const scrollContainerRef = useRef30(null);
32730
+ const getBlockElements = useCallback108(() => {
32422
32731
  if (!containerRef.current) return [];
32423
32732
  const blocks = containerRef.current.querySelectorAll('[data-node-type="blockContainer"]');
32424
32733
  return Array.from(blocks);
32425
32734
  }, []);
32426
- const getScrollContainer = useCallback107(() => {
32735
+ const getScrollContainer = useCallback108(() => {
32427
32736
  if (scrollContainerRef.current) return scrollContainerRef.current;
32428
32737
  let element = containerRef.current;
32429
32738
  while (element) {
@@ -32438,7 +32747,7 @@ var ExternalDropZone = ({
32438
32747
  scrollContainerRef.current = window;
32439
32748
  return window;
32440
32749
  }, []);
32441
- const performScroll = useCallback107(() => {
32750
+ const performScroll = useCallback108(() => {
32442
32751
  const container = getScrollContainer();
32443
32752
  const direction = scrollDirectionRef.current;
32444
32753
  if (!direction) {
@@ -32453,7 +32762,7 @@ var ExternalDropZone = ({
32453
32762
  }
32454
32763
  scrollAnimationRef.current = requestAnimationFrame(performScroll);
32455
32764
  }, [getScrollContainer]);
32456
- const startAutoScroll = useCallback107(
32765
+ const startAutoScroll = useCallback108(
32457
32766
  (direction) => {
32458
32767
  if (scrollDirectionRef.current === direction) return;
32459
32768
  scrollDirectionRef.current = direction;
@@ -32463,14 +32772,14 @@ var ExternalDropZone = ({
32463
32772
  },
32464
32773
  [performScroll]
32465
32774
  );
32466
- const stopAutoScroll = useCallback107(() => {
32775
+ const stopAutoScroll = useCallback108(() => {
32467
32776
  scrollDirectionRef.current = null;
32468
32777
  if (scrollAnimationRef.current) {
32469
32778
  cancelAnimationFrame(scrollAnimationRef.current);
32470
32779
  scrollAnimationRef.current = null;
32471
32780
  }
32472
32781
  }, []);
32473
- const checkAutoScroll = useCallback107(
32782
+ const checkAutoScroll = useCallback108(
32474
32783
  (clientY) => {
32475
32784
  const container = getScrollContainer();
32476
32785
  let containerTop;
@@ -32493,7 +32802,7 @@ var ExternalDropZone = ({
32493
32802
  },
32494
32803
  [getScrollContainer, startAutoScroll, stopAutoScroll]
32495
32804
  );
32496
- const findDropPosition = useCallback107(
32805
+ const findDropPosition = useCallback108(
32497
32806
  (clientY) => {
32498
32807
  const blocks = getBlockElements();
32499
32808
  if (blocks.length === 0 || !editor?.document) return null;
@@ -32526,7 +32835,7 @@ var ExternalDropZone = ({
32526
32835
  },
32527
32836
  [getBlockElements, editor]
32528
32837
  );
32529
- const handleDragOver = useCallback107(
32838
+ const handleDragOver = useCallback108(
32530
32839
  (e) => {
32531
32840
  if (!e.dataTransfer.types.includes(acceptedType)) return;
32532
32841
  e.preventDefault();
@@ -32549,7 +32858,7 @@ var ExternalDropZone = ({
32549
32858
  },
32550
32859
  [acceptedType, findDropPosition, checkAutoScroll]
32551
32860
  );
32552
- const handleDragLeave = useCallback107(
32861
+ const handleDragLeave = useCallback108(
32553
32862
  (e) => {
32554
32863
  if (containerRef.current && !containerRef.current.contains(e.relatedTarget)) {
32555
32864
  setIsValidDrag(false);
@@ -32559,7 +32868,7 @@ var ExternalDropZone = ({
32559
32868
  },
32560
32869
  [stopAutoScroll]
32561
32870
  );
32562
- const handleDrop = useCallback107(
32871
+ const handleDrop = useCallback108(
32563
32872
  (e) => {
32564
32873
  e.preventDefault();
32565
32874
  e.stopPropagation();
@@ -32573,7 +32882,7 @@ var ExternalDropZone = ({
32573
32882
  },
32574
32883
  [onDrop, stopAutoScroll]
32575
32884
  );
32576
- useEffect110(() => {
32885
+ useEffect111(() => {
32577
32886
  const handleGlobalDragEnd = () => {
32578
32887
  setIsValidDrag(false);
32579
32888
  dropPositionRef.current = null;
@@ -32582,7 +32891,7 @@ var ExternalDropZone = ({
32582
32891
  window.addEventListener("dragend", handleGlobalDragEnd);
32583
32892
  return () => window.removeEventListener("dragend", handleGlobalDragEnd);
32584
32893
  }, [stopAutoScroll]);
32585
- const handleOverlayMouseMove = useCallback107(
32894
+ const handleOverlayMouseMove = useCallback108(
32586
32895
  (e) => {
32587
32896
  setIsHoveringInPlacementMode(true);
32588
32897
  checkAutoScroll(e.clientY);
@@ -32601,12 +32910,12 @@ var ExternalDropZone = ({
32601
32910
  },
32602
32911
  [findDropPosition, checkAutoScroll]
32603
32912
  );
32604
- const handleOverlayMouseLeave = useCallback107(() => {
32913
+ const handleOverlayMouseLeave = useCallback108(() => {
32605
32914
  setIsHoveringInPlacementMode(false);
32606
32915
  dropPositionRef.current = null;
32607
32916
  stopAutoScroll();
32608
32917
  }, [stopAutoScroll]);
32609
- const handleOverlayClick = useCallback107(
32918
+ const handleOverlayClick = useCallback108(
32610
32919
  (e) => {
32611
32920
  e.preventDefault();
32612
32921
  e.stopPropagation();
@@ -32620,7 +32929,7 @@ var ExternalDropZone = ({
32620
32929
  },
32621
32930
  [onDrop, stopAutoScroll]
32622
32931
  );
32623
- const handleOverlayWheel = useCallback107(
32932
+ const handleOverlayWheel = useCallback108(
32624
32933
  (e) => {
32625
32934
  const container = getScrollContainer();
32626
32935
  if (container === window) {
@@ -32631,7 +32940,7 @@ var ExternalDropZone = ({
32631
32940
  },
32632
32941
  [getScrollContainer]
32633
32942
  );
32634
- useEffect110(() => {
32943
+ useEffect111(() => {
32635
32944
  if (!isPlacementMode) return;
32636
32945
  const handleKeyDown = (e) => {
32637
32946
  if (e.key === "Escape") {
@@ -32654,13 +32963,13 @@ var ExternalDropZone = ({
32654
32963
  document.removeEventListener("click", handleGlobalClick, true);
32655
32964
  };
32656
32965
  }, [isPlacementMode, onPlacementCancel]);
32657
- useEffect110(() => {
32966
+ useEffect111(() => {
32658
32967
  if (!isPlacementMode) {
32659
32968
  setIsHoveringInPlacementMode(false);
32660
32969
  dropPositionRef.current = null;
32661
32970
  }
32662
32971
  }, [isPlacementMode]);
32663
- useEffect110(() => {
32972
+ useEffect111(() => {
32664
32973
  const isActive = isValidDrag || isPlacementMode && isHoveringInPlacementMode;
32665
32974
  if (isActive) {
32666
32975
  document.body.classList.add("external-artifact-drag-active");
@@ -32671,7 +32980,7 @@ var ExternalDropZone = ({
32671
32980
  document.body.classList.remove("external-artifact-drag-active");
32672
32981
  };
32673
32982
  }, [isValidDrag, isPlacementMode, isHoveringInPlacementMode]);
32674
- useEffect110(() => {
32983
+ useEffect111(() => {
32675
32984
  return () => {
32676
32985
  if (scrollAnimationRef.current) {
32677
32986
  cancelAnimationFrame(scrollAnimationRef.current);
@@ -32745,7 +33054,7 @@ function IxoEditorContent({
32745
33054
  const { activePanel } = usePanelStore();
32746
33055
  const isPanelOpen = activePanel !== null;
32747
33056
  const [isRoomPrivate, setIsRoomPrivate] = useState134(pageHeaderProps?.isPrivate ?? true);
32748
- useEffect111(() => {
33057
+ useEffect112(() => {
32749
33058
  const matrixClient = editor.getMatrixClient?.();
32750
33059
  const roomId = editor.getRoomId?.();
32751
33060
  if (!matrixClient || !roomId) return;
@@ -32761,7 +33070,7 @@ function IxoEditorContent({
32761
33070
  } catch {
32762
33071
  }
32763
33072
  }, [editor]);
32764
- const handlePrivacyChange = useCallback108(
33073
+ const handlePrivacyChange = useCallback109(
32765
33074
  async (makePrivate) => {
32766
33075
  const matrixClient = editor.getMatrixClient?.();
32767
33076
  const roomId = editor.getRoomId?.();
@@ -33052,15 +33361,15 @@ var EntitySigningSetup = ({ opened, onClose, entityDid, entityName, onSetup }) =
33052
33361
  };
33053
33362
 
33054
33363
  // src/mantine/components/FlowPermissionsPanel.tsx
33055
- import React298, { useState as useState136, useEffect as useEffect112, useMemo as useMemo121 } from "react";
33364
+ import React298, { useState as useState136, useEffect as useEffect113, useMemo as useMemo121 } from "react";
33056
33365
  import { Stack as Stack198, Text as Text169, Paper as Paper18, Group as Group109, Badge as Badge43, Button as Button54, ActionIcon as ActionIcon38, Loader as Loader54, Alert as Alert54, Divider as Divider29 } from "@mantine/core";
33057
- import { IconPlus as IconPlus12, IconTrash as IconTrash11, IconShieldCheck as IconShieldCheck15, IconUser as IconUser14, IconRobot as IconRobot4, IconBuilding as IconBuilding2 } from "@tabler/icons-react";
33366
+ import { IconPlus as IconPlus12, IconTrash as IconTrash11, IconShieldCheck as IconShieldCheck16, IconUser as IconUser14, IconRobot as IconRobot4, IconBuilding as IconBuilding2 } from "@tabler/icons-react";
33058
33367
  var FlowPermissionsPanel = ({ editor, entityDid, entityName, onGrantPermission, onRevokePermission, getUserDisplayName }) => {
33059
33368
  const [delegations, setDelegations] = useState136([]);
33060
33369
  const [loading, setLoading] = useState136(true);
33061
33370
  const [revoking, setRevoking] = useState136(null);
33062
33371
  const rootCapability = useMemo121(() => editor.getRootCapability?.(), [editor]);
33063
- useEffect112(() => {
33372
+ useEffect113(() => {
33064
33373
  const loadDelegations = async () => {
33065
33374
  setLoading(true);
33066
33375
  const allDelegations = editor.getAllDelegations?.() || [];
@@ -33122,11 +33431,11 @@ var FlowPermissionsPanel = ({ editor, entityDid, entityName, onGrantPermission,
33122
33431
  if (date < /* @__PURE__ */ new Date()) return "Expired";
33123
33432
  return date.toLocaleDateString();
33124
33433
  };
33125
- return /* @__PURE__ */ React298.createElement(Stack198, { gap: "md" }, /* @__PURE__ */ React298.createElement(Stack198, { gap: "xs" }, /* @__PURE__ */ React298.createElement(Text169, { fw: 600, size: "sm" }, "Root Authority"), /* @__PURE__ */ React298.createElement(Paper18, { p: "sm", withBorder: true }, /* @__PURE__ */ React298.createElement(Group109, { gap: "xs" }, /* @__PURE__ */ React298.createElement(IconShieldCheck15, { size: 20, color: "var(--mantine-color-green-6)" }), /* @__PURE__ */ React298.createElement(Stack198, { gap: 2, style: { flex: 1 } }, /* @__PURE__ */ React298.createElement(Text169, { size: "sm", fw: 500 }, entityName || entityDid), /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, rootCapability ? `Granted: ${new Date(rootCapability.issuedAt).toLocaleDateString()}` : "Root capability not set up")), /* @__PURE__ */ React298.createElement(Badge43, { color: "green", variant: "light" }, "Entity")))), /* @__PURE__ */ React298.createElement(Divider29, { label: "Delegated Permissions", labelPosition: "center" }), loading ? /* @__PURE__ */ React298.createElement(Group109, { justify: "center", py: "xl" }, /* @__PURE__ */ React298.createElement(Loader54, { size: "sm" })) : delegations.length === 0 ? /* @__PURE__ */ React298.createElement(Alert54, { color: "gray", variant: "light" }, /* @__PURE__ */ React298.createElement(Text169, { size: "sm" }, "No permissions have been granted yet.")) : /* @__PURE__ */ React298.createElement(Stack198, { gap: "xs" }, delegations.map(({ capability, displayName, type }) => /* @__PURE__ */ React298.createElement(Paper18, { key: capability.id, p: "sm", withBorder: true }, /* @__PURE__ */ React298.createElement(Group109, { justify: "space-between" }, /* @__PURE__ */ React298.createElement(Group109, { gap: "xs" }, getIcon2(type), /* @__PURE__ */ React298.createElement(Stack198, { gap: 2 }, /* @__PURE__ */ React298.createElement(Text169, { size: "sm", fw: 500 }, displayName), /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, formatCapabilities(capability.capabilities)), /* @__PURE__ */ React298.createElement(Group109, { gap: "xs" }, /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, "Expires: ", formatExpiration(capability.expiration)), /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, "\u2022"), /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, "Granted by: ", capability.issuer === entityDid ? "Entity" : capability.issuer.slice(-8))))), /* @__PURE__ */ React298.createElement(ActionIcon38, { color: "red", variant: "subtle", onClick: () => handleRevoke(capability.id), loading: revoking === capability.id, disabled: !!revoking }, /* @__PURE__ */ React298.createElement(IconTrash11, { size: 16 })))))), /* @__PURE__ */ React298.createElement(Button54, { leftSection: /* @__PURE__ */ React298.createElement(IconPlus12, { size: 16 }), variant: "light", onClick: onGrantPermission }, "Grant Permission"));
33434
+ return /* @__PURE__ */ React298.createElement(Stack198, { gap: "md" }, /* @__PURE__ */ React298.createElement(Stack198, { gap: "xs" }, /* @__PURE__ */ React298.createElement(Text169, { fw: 600, size: "sm" }, "Root Authority"), /* @__PURE__ */ React298.createElement(Paper18, { p: "sm", withBorder: true }, /* @__PURE__ */ React298.createElement(Group109, { gap: "xs" }, /* @__PURE__ */ React298.createElement(IconShieldCheck16, { size: 20, color: "var(--mantine-color-green-6)" }), /* @__PURE__ */ React298.createElement(Stack198, { gap: 2, style: { flex: 1 } }, /* @__PURE__ */ React298.createElement(Text169, { size: "sm", fw: 500 }, entityName || entityDid), /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, rootCapability ? `Granted: ${new Date(rootCapability.issuedAt).toLocaleDateString()}` : "Root capability not set up")), /* @__PURE__ */ React298.createElement(Badge43, { color: "green", variant: "light" }, "Entity")))), /* @__PURE__ */ React298.createElement(Divider29, { label: "Delegated Permissions", labelPosition: "center" }), loading ? /* @__PURE__ */ React298.createElement(Group109, { justify: "center", py: "xl" }, /* @__PURE__ */ React298.createElement(Loader54, { size: "sm" })) : delegations.length === 0 ? /* @__PURE__ */ React298.createElement(Alert54, { color: "gray", variant: "light" }, /* @__PURE__ */ React298.createElement(Text169, { size: "sm" }, "No permissions have been granted yet.")) : /* @__PURE__ */ React298.createElement(Stack198, { gap: "xs" }, delegations.map(({ capability, displayName, type }) => /* @__PURE__ */ React298.createElement(Paper18, { key: capability.id, p: "sm", withBorder: true }, /* @__PURE__ */ React298.createElement(Group109, { justify: "space-between" }, /* @__PURE__ */ React298.createElement(Group109, { gap: "xs" }, getIcon2(type), /* @__PURE__ */ React298.createElement(Stack198, { gap: 2 }, /* @__PURE__ */ React298.createElement(Text169, { size: "sm", fw: 500 }, displayName), /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, formatCapabilities(capability.capabilities)), /* @__PURE__ */ React298.createElement(Group109, { gap: "xs" }, /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, "Expires: ", formatExpiration(capability.expiration)), /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, "\u2022"), /* @__PURE__ */ React298.createElement(Text169, { size: "xs", c: "dimmed" }, "Granted by: ", capability.issuer === entityDid ? "Entity" : capability.issuer.slice(-8))))), /* @__PURE__ */ React298.createElement(ActionIcon38, { color: "red", variant: "subtle", onClick: () => handleRevoke(capability.id), loading: revoking === capability.id, disabled: !!revoking }, /* @__PURE__ */ React298.createElement(IconTrash11, { size: 16 })))))), /* @__PURE__ */ React298.createElement(Button54, { leftSection: /* @__PURE__ */ React298.createElement(IconPlus12, { size: 16 }), variant: "light", onClick: onGrantPermission }, "Grant Permission"));
33126
33435
  };
33127
33436
 
33128
33437
  // src/mantine/components/GrantPermissionModal.tsx
33129
- import React299, { useState as useState137, useCallback as useCallback109 } from "react";
33438
+ import React299, { useState as useState137, useCallback as useCallback110 } from "react";
33130
33439
  import { Modal as Modal4, Stack as Stack199, Text as Text170, TextInput as TextInput10, Button as Button55, Group as Group110, Radio as Radio6, Checkbox as Checkbox13, Alert as Alert55, Paper as Paper19, Loader as Loader55, Badge as Badge44, ActionIcon as ActionIcon39, Divider as Divider30, NumberInput as NumberInput3 } from "@mantine/core";
33131
33440
  import { IconSearch as IconSearch8, IconUser as IconUser15, IconRobot as IconRobot5, IconX as IconX15, IconShieldPlus as IconShieldPlus4 } from "@tabler/icons-react";
33132
33441
  var GrantPermissionModal = ({ opened, onClose, flowUri, blocks, targetBlockId, searchUsers, getOracles, onGrant }) => {
@@ -33147,7 +33456,7 @@ var GrantPermissionModal = ({ opened, onClose, flowUri, blocks, targetBlockId, s
33147
33456
  const [pin, setPin] = useState137("");
33148
33457
  const [loading, setLoading] = useState137(false);
33149
33458
  const [error, setError] = useState137(null);
33150
- const handleSearch = useCallback109(async () => {
33459
+ const handleSearch = useCallback110(async () => {
33151
33460
  if (searchQuery.length < 2) return;
33152
33461
  setSearching(true);
33153
33462
  try {
@@ -33404,4 +33713,4 @@ export {
33404
33713
  getExtraSlashMenuItems,
33405
33714
  useCreateIxoEditor
33406
33715
  };
33407
- //# sourceMappingURL=chunk-K75BAQDR.mjs.map
33716
+ //# sourceMappingURL=chunk-LQP2DPYM.mjs.map