@ixo/editor 6.1.1 → 6.2.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.
@@ -39,7 +39,6 @@ var ACTION_TYPE_ALIASES = {
39
39
  MemberMultiSelect: "qi/pod.member-multi-select",
40
40
  governanceConfig: "qi/pod.governance-config",
41
41
  listDomainFlows: "qi/pod.list-domain-flows",
42
- payment: "qi/payment.execute",
43
42
  "matrix.dm": "qi/matrix.dm"
44
43
  };
45
44
  var aliases = new Map(Object.entries(ACTION_TYPE_ALIASES));
@@ -191,7 +190,6 @@ var CAN_TO_TYPE = {
191
190
  "domain/card-preview": "qi/domain.card-preview",
192
191
  "domain/sign": "qi/domain.sign",
193
192
  "credential/store": "qi/credential.store",
194
- "payment/execute": "qi/payment.execute",
195
193
  "http/request": "qi/http.request",
196
194
  "protocol/select": "qi/protocol.select",
197
195
  "human/checkbox": "qi/human.checkbox.set",
@@ -254,7 +252,8 @@ var SERVICE_GROUP_REQUIRED_HANDLERS = {
254
252
  "collection.updateIntents"
255
253
  ],
256
254
  collectionUsers: ["collectionUsers.grant", "collectionUsers.revoke", "collectionUsers.list", "collectionUsers.classifyAddress", "collectionUsers.enumerateMembers"],
257
- carbon: ["carbon.loadBatches", "carbon.harvest", "carbon.retire"]
255
+ carbon: ["carbon.loadBatches", "carbon.harvest", "carbon.retire"],
256
+ kyc: ["kycLoadForm", "kycInitiate", "kycGetVerificationUrl", "kycGetStatus", "kycSaveCredential"]
258
257
  };
259
258
  function getHandlerAtPath(handlers, path) {
260
259
  return path.split(".").reduce((acc, key) => acc == null ? void 0 : acc[key], handlers);
@@ -402,6 +401,17 @@ function buildServicesFromHandlers(handlers) {
402
401
  // we only forward the call here.
403
402
  entity: handlers?.entity?.transfer ? {
404
403
  transfer: async (params) => handlers.entity.transfer(params)
404
+ } : void 0,
405
+ // KYC verification service (qi/kyc.verify). The consumer exposes the five
406
+ // flat kyc* handlers (all-or-nothing group); wire each method straight
407
+ // through. The consumer handler owns the KYC-server calls, PII handling,
408
+ // and saveCredential idempotency — we only forward calls here.
409
+ kyc: handlers?.kycLoadForm && handlers?.kycInitiate && handlers?.kycGetVerificationUrl && handlers?.kycGetStatus && handlers?.kycSaveCredential ? {
410
+ loadForm: async (params) => handlers.kycLoadForm(params),
411
+ initiate: async (params) => handlers.kycInitiate(params),
412
+ getVerificationUrl: async (params) => handlers.kycGetVerificationUrl(params),
413
+ getStatus: async (params) => handlers.kycGetStatus(params),
414
+ saveCredential: async (params) => handlers.kycSaveCredential(params)
405
415
  } : void 0
406
416
  };
407
417
  }
@@ -1014,13 +1024,11 @@ registerAction({
1014
1024
  }
1015
1025
  const quorumPercent = clampPercent(inputs.quorumPercent, "quorumPercent", { allowZero: true });
1016
1026
  const thresholdPercent = clampPercent(inputs.thresholdPercent, "thresholdPercent");
1017
- const vetoThresholdPercent = clampPercent(inputs.vetoThresholdPercent, "vetoThresholdPercent", { allowZero: true });
1018
- if (thresholdPercent + vetoThresholdPercent > 100) {
1019
- throw new Error("thresholdPercent + vetoThresholdPercent cannot exceed 100");
1020
- }
1021
1027
  const allowRevoting = Boolean(inputs.allowRevoting);
1022
1028
  const data = {
1023
- onlyMembersExecute: false,
1029
+ // Group creation instantiates the proposal module with
1030
+ // only_members_execute: true — preserve that policy on updates.
1031
+ onlyMembersExecute: true,
1024
1032
  thresholdType: "%",
1025
1033
  thresholdPercentage: thresholdPercent,
1026
1034
  quorumEnabled: quorumPercent > 0,
@@ -1028,11 +1036,7 @@ registerAction({
1028
1036
  quorumPercentage: quorumPercent,
1029
1037
  proposalDuration: Math.trunc(votingPeriodHours),
1030
1038
  proposalDurationUnits: "hours",
1031
- allowRevoting,
1032
- // TODO(governance): the editor's UpdateProposalConfigData / the consumer's
1033
- // message builder don't yet carry a veto threshold for single-choice
1034
- // voting. Passed through so the consumer can apply it once supported.
1035
- vetoThresholdPercentage: vetoThresholdPercent
1039
+ allowRevoting
1036
1040
  };
1037
1041
  const updateVotingConfigAction = { type: "UpdateVotingConfig", data };
1038
1042
  const title = String(inputs.title || "").trim() || "Update governance settings";
@@ -1095,8 +1099,16 @@ registerAction({
1095
1099
  if (!denom) throw new Error("denom is required");
1096
1100
  const amount = Number(inputs.amount);
1097
1101
  if (!Number.isFinite(amount) || amount <= 0) throw new Error("amount must be greater than 0");
1098
- const spendAction = { type: "Spend", data: { to: recipient, denom, amount: String(amount) } };
1099
- const title = String(inputs.title || "").trim() || `Send ${amount} ${denom} to ${recipient}`;
1102
+ const KNOWN_DENOMS = {
1103
+ uixo: { symbol: "IXO", exponent: 6 }
1104
+ };
1105
+ const tokenInfo = KNOWN_DENOMS[denom];
1106
+ if (!tokenInfo) {
1107
+ throw new Error(`Sending ${denom} is not supported yet \u2014 only IXO transfers are currently available`);
1108
+ }
1109
+ const baseAmount = BigInt(Math.round(amount * 10 ** tokenInfo.exponent)).toString();
1110
+ const spendAction = { type: "Spend", data: { to: recipient, denom, amount: baseAmount } };
1111
+ const title = String(inputs.title || "").trim() || `Send ${amount} ${tokenInfo.symbol} to ${recipient}`;
1100
1112
  const description = String(inputs.description || "").trim() || "Sends funds from the group treasury once the proposal passes.";
1101
1113
  const { preProposalContractAddress } = await handlers.getPreProposalContractAddress({ coreAddress });
1102
1114
  const { groupContractAddress } = await handlers.getGroupContractAddress({ coreAddress });
@@ -2797,13 +2809,13 @@ registerAction({
2797
2809
  required: ["proposalId", "vote", "proposalContractAddress"],
2798
2810
  properties: {
2799
2811
  proposalId: { type: "number", description: "The proposal number to vote on." },
2800
- vote: { type: "string", description: "The vote to cast: yes, no, no_with_veto, or abstain." },
2812
+ vote: { type: "string", description: "The vote to cast: yes, no, or abstain." },
2801
2813
  proposalContractAddress: { type: "string", description: "The proposal module contract address." },
2802
2814
  rationale: { type: "string", description: "Optional rationale provided with the vote." }
2803
2815
  }
2804
2816
  },
2805
2817
  outputSchema: [
2806
- { path: "vote", displayName: "Vote", type: "string", description: "The vote cast (yes, no, no_with_veto, abstain)" },
2818
+ { path: "vote", displayName: "Vote", type: "string", description: "The vote cast (yes, no, abstain)" },
2807
2819
  { path: "rationale", displayName: "Rationale", type: "string", description: "Optional rationale provided with the vote" },
2808
2820
  { path: "proposalId", displayName: "Proposal ID", type: "string", description: "The proposal that was voted on" },
2809
2821
  { path: "votedAt", displayName: "Voted At", type: "string", description: "ISO timestamp of when the vote was cast" }
@@ -2823,7 +2835,7 @@ registerAction({
2823
2835
  if (!proposalId || isNaN(proposalId)) throw new Error("proposalId is required");
2824
2836
  if (!vote) throw new Error("vote is required");
2825
2837
  if (!proposalContractAddress) throw new Error("proposalContractAddress is required");
2826
- const validVotes = ["yes", "no", "no_with_veto", "abstain"];
2838
+ const validVotes = ["yes", "no", "abstain"];
2827
2839
  if (!validVotes.includes(vote)) {
2828
2840
  throw new Error(`vote must be one of: ${validVotes.join(", ")}`);
2829
2841
  }
@@ -4071,15 +4083,23 @@ function parseDuration(raw) {
4071
4083
  function buildGroupConfig(groupType, governance, memberConfig) {
4072
4084
  const duration = parseDuration(governance.votingPeriod || "604800s");
4073
4085
  const thresholdNum = parseFloat(governance.threshold || "0.51");
4086
+ const quorumNum = parseFloat(governance.quorum);
4087
+ const unstakingDuration = governance.unstakingDuration ? parseDuration(governance.unstakingDuration) : null;
4074
4088
  const baseConfig = {
4075
4089
  proposalDurationAmount: duration.amount,
4076
4090
  proposalDurationUnit: duration.unit,
4077
4091
  proposalSubmissionPolicy: "members",
4078
4092
  voteSwitching: false
4079
4093
  };
4094
+ const decisionPolicy = {
4095
+ passingThreshold: "percentage",
4096
+ passingThresholdPercentage: Math.round(thresholdNum * 100),
4097
+ ...Number.isFinite(quorumNum) && quorumNum > 0 ? { quorum: "percentage", quorumPercentage: Math.round(quorumNum * 100) } : {}
4098
+ };
4080
4099
  if (groupType === "multisig") {
4081
4100
  const members2 = memberConfig?.members || [];
4082
4101
  return {
4102
+ ...baseConfig,
4083
4103
  threshold: memberConfig?.multisigThreshold || 1,
4084
4104
  membershipCategory: [{ members: members2.map((m) => m.did) }]
4085
4105
  };
@@ -4087,21 +4107,23 @@ function buildGroupConfig(groupType, governance, memberConfig) {
4087
4107
  if (groupType === "nftStaking") {
4088
4108
  return {
4089
4109
  ...baseConfig,
4110
+ ...decisionPolicy,
4090
4111
  nftContractAddress: memberConfig?.nftContractAddress || "",
4091
- unstakingDuration: governance.unstakingDuration ? parseDuration(governance.unstakingDuration) : void 0
4112
+ ...unstakingDuration ? { unstakingDurationAmount: unstakingDuration.amount, unstakingDurationUnit: unstakingDuration.unit } : {}
4092
4113
  };
4093
4114
  }
4094
4115
  if (groupType === "tokenStaking") {
4095
4116
  const tokenConfig = memberConfig?.tokenConfig || {};
4096
4117
  return {
4097
4118
  ...baseConfig,
4098
- passingThreshold: thresholdNum === 0.5 ? "majority" : "percentage",
4099
- passingThresholdPercentage: Math.round(thresholdNum * 100),
4119
+ ...decisionPolicy,
4120
+ isExistingToken: Boolean(tokenConfig.isExistingToken),
4121
+ tokenAddress: tokenConfig.tokenAddress || "",
4100
4122
  tokenName: tokenConfig.tokenName || "",
4101
4123
  tokenSymbol: tokenConfig.tokenSymbol || "",
4102
4124
  tokenSupply: tokenConfig.tokenSupply || 0,
4103
4125
  distributionCategory: tokenConfig.distributionCategory || [],
4104
- unstakingDuration: governance.unstakingDuration ? parseDuration(governance.unstakingDuration) : void 0
4126
+ ...unstakingDuration ? { unstakingDurationAmount: unstakingDuration.amount, unstakingDurationUnit: unstakingDuration.unit } : {}
4105
4127
  };
4106
4128
  }
4107
4129
  const members = memberConfig?.members || [];
@@ -4117,9 +4139,9 @@ function buildGroupConfig(groupType, governance, memberConfig) {
4117
4139
  }
4118
4140
  return {
4119
4141
  ...baseConfig,
4120
- passingThreshold: thresholdNum === 0.5 ? "majority" : "percentage",
4121
- passingThresholdPercentage: Math.round(thresholdNum * 100),
4122
- membershipCategory: Array.from(byRole.values()).map(({ dids, weight }) => ({
4142
+ ...decisionPolicy,
4143
+ membershipCategory: Array.from(byRole.entries()).map(([role, { dids, weight }]) => ({
4144
+ categoryName: role,
4123
4145
  members: dids.map((did) => ({ memberAddress: did })),
4124
4146
  weightPerMember: weight
4125
4147
  }))
@@ -4710,91 +4732,6 @@ registerAction({
4710
4732
  }
4711
4733
  });
4712
4734
 
4713
- // src/core/lib/actionRegistry/actions/payment.ts
4714
- registerAction({
4715
- type: "qi/payment.execute",
4716
- can: "payment/execute",
4717
- sideEffect: true,
4718
- proof: { fields: ["paymentBlockId"] },
4719
- defaultRequiresConfirmation: true,
4720
- requiredCapability: "flow/block/execute",
4721
- inputSchema: {
4722
- type: "object",
4723
- required: ["rowIds", "verb", "paymentBlockId"],
4724
- properties: {
4725
- rowIds: { type: "array", description: "IDs of the rows in the payment block to operate on (at least one)." },
4726
- verb: { type: "string", description: 'Which worker route to hit: "propose", "execute", or "check".' },
4727
- paymentBlockId: { type: "string", description: "The payment block ID so the oracle can edit_block back into the right place." },
4728
- delegationCid: { type: "string", description: "Optional user's UCAN delegation CID to the oracle." },
4729
- skill: { type: "object", description: "Optional skill context with cid and name." }
4730
- }
4731
- },
4732
- outputSchema: [
4733
- { path: "verb", displayName: "Action verb", type: "string" },
4734
- { path: "rowCount", displayName: "Rows targeted", type: "number" },
4735
- { path: "paymentBlockId", displayName: "Payment block ID", type: "string" }
4736
- ],
4737
- events: [
4738
- {
4739
- name: "rows.completed",
4740
- displayName: "Payment rows completed",
4741
- description: "Fires after the oracle writes terminal status for one or more rows in this batch. Listeners can react to the just-completed payouts.",
4742
- payloadSchema: [
4743
- { path: "paymentBlockId", displayName: "Payment block ID", type: "string" },
4744
- { path: "completedRowIds", displayName: "Completed row IDs", type: "string" },
4745
- { path: "failedRowIds", displayName: "Failed row IDs", type: "string" }
4746
- ]
4747
- }
4748
- ],
4749
- run: async (inputs, ctx) => {
4750
- const rowIds = Array.isArray(inputs.rowIds) ? inputs.rowIds.filter((v) => typeof v === "string" && v.length > 0) : [];
4751
- if (rowIds.length === 0) {
4752
- throw new Error("rowIds is required \u2014 pick at least one row before sending");
4753
- }
4754
- const verb = String(inputs.verb || "").trim().toLowerCase();
4755
- if (verb !== "propose" && verb !== "execute" && verb !== "check") {
4756
- throw new Error('verb is required and must be one of: "propose", "execute", "check"');
4757
- }
4758
- const paymentBlockId = String(inputs.paymentBlockId || "").trim();
4759
- if (!paymentBlockId) {
4760
- throw new Error("paymentBlockId is required");
4761
- }
4762
- const delegationCid = typeof inputs.delegationCid === "string" ? inputs.delegationCid : "";
4763
- const skillCtx = inputs.skill && typeof inputs.skill === "object" ? inputs.skill : null;
4764
- if (!ctx.handlers?.askCompanion) {
4765
- throw new Error("askCompanion handler is not available");
4766
- }
4767
- const verbDescription = verb === "propose" ? "Make payout proposals for the rows listed below." : verb === "execute" ? "Execute the previously-proposed payouts for the rows listed below." : "Check status for the rows listed below.";
4768
- const lines = [verbDescription];
4769
- lines.push(
4770
- "Read the flow context and the payment block to find the worker base URL, sender info, defaults, and the rows. Follow the skill's SKILL.md for the workflow.",
4771
- `Payment block ID: ${paymentBlockId}`,
4772
- `Verb: ${verb}`,
4773
- `Row IDs (in this batch): ${rowIds.join(", ")}`
4774
- );
4775
- if (skillCtx?.name) lines.push(`Skill name: ${skillCtx.name}`);
4776
- if (skillCtx?.cid) lines.push(`Skill CID: ${skillCtx.cid}`);
4777
- if (delegationCid) lines.push(`UCAN delegation CID: ${delegationCid}`);
4778
- await ctx.handlers.askCompanion(lines.join("\n"));
4779
- return {
4780
- output: {
4781
- verb,
4782
- rowCount: rowIds.length,
4783
- paymentBlockId
4784
- },
4785
- completion: {
4786
- state: "awaiting_readback",
4787
- readBack: {
4788
- kind: "paymentRows",
4789
- paymentBlockId,
4790
- rowIds,
4791
- verb
4792
- }
4793
- }
4794
- };
4795
- }
4796
- });
4797
-
4798
4735
  // src/core/lib/actionRegistry/actions/matrixDm.ts
4799
4736
  registerAction({
4800
4737
  type: "qi/matrix.dm",
@@ -6534,6 +6471,89 @@ registerAction({
6534
6471
  }
6535
6472
  });
6536
6473
 
6474
+ // src/core/lib/actionRegistry/actions/kycVerify.ts
6475
+ registerAction({
6476
+ type: "qi/kyc.verify",
6477
+ can: "kyc/verify",
6478
+ sideEffect: true,
6479
+ proof: { fields: ["credentialCid"] },
6480
+ defaultRequiresConfirmation: false,
6481
+ cardinality: "once",
6482
+ // Human-driven (details form + hosted webview) — never event-triggered,
6483
+ // same as the human input actions.
6484
+ eligibleForEventTrigger: false,
6485
+ inputSchema: {
6486
+ type: "object",
6487
+ required: ["protocolDid"],
6488
+ properties: {
6489
+ protocolDid: { type: "string", description: "DID of the KYC protocol entity to verify against. The protocol determines the KYC level and check plan." },
6490
+ credentialType: {
6491
+ type: "string",
6492
+ description: "Vault index key of the credential the protocol issues (e.g. 'kycamllevel1', 'kycamllevel2'). Defaults to level 1 when omitted."
6493
+ },
6494
+ credentialCid: {
6495
+ type: "string",
6496
+ description: "Runtime-selected CID of an existing Vault credential to use (set by the FlowDetail when the user picks one of several)."
6497
+ }
6498
+ }
6499
+ },
6500
+ outputSchema: [
6501
+ { path: "credentialCid", displayName: "Credential CID", type: "string", description: "CID of the SD-JWT credential saved to the Vault (proof of completion)." },
6502
+ { path: "credentialType", displayName: "Credential Type", type: "string", description: "Type of the issued credential." },
6503
+ { path: "protocolId", displayName: "Protocol ID", type: "string", description: "The KYC protocol this verification ran against." },
6504
+ { path: "status", displayName: "Status", type: "string", description: "Terminal lifecycle status \u2014 'complete' once the credential is saved." }
6505
+ ],
6506
+ events: [
6507
+ {
6508
+ name: "kyc.completed",
6509
+ displayName: "KYC completed",
6510
+ description: "Fires when the issued credential has been saved to the Vault and the verification is complete.",
6511
+ payloadSchema: [
6512
+ { path: "credentialCid", displayName: "Credential CID", type: "string" },
6513
+ { path: "credentialType", displayName: "Credential Type", type: "string" },
6514
+ { path: "protocolId", displayName: "Protocol ID", type: "string" },
6515
+ { path: "status", displayName: "Status", type: "string" }
6516
+ ],
6517
+ pendingDisplayFields: ["credentialType", "status"]
6518
+ }
6519
+ ],
6520
+ run: async (inputs, ctx) => {
6521
+ if (!ctx.services.kyc) {
6522
+ throw new Error("kyc handlers not available");
6523
+ }
6524
+ if (!inputs.protocolDid) throw new Error("protocolDid is required");
6525
+ const credentialType = typeof inputs.credentialType === "string" && inputs.credentialType.trim() ? inputs.credentialType.trim() : void 0;
6526
+ const credentialCid = typeof inputs.credentialCid === "string" && inputs.credentialCid.trim() ? inputs.credentialCid.trim() : void 0;
6527
+ const { status } = await ctx.services.kyc.getStatus({ protocolId: inputs.protocolDid });
6528
+ let eligible = status === "issued" || status === "complete";
6529
+ if (!eligible) {
6530
+ try {
6531
+ const form = await ctx.services.kyc.loadForm({ protocolDid: inputs.protocolDid, credentialType });
6532
+ eligible = !!form.hasExistingCredential;
6533
+ } catch (err) {
6534
+ console.warn("[kyc.verify] vault fallback check failed", err);
6535
+ }
6536
+ }
6537
+ if (!eligible) {
6538
+ throw new Error(`KYC verification not complete \u2014 current status: ${status}`);
6539
+ }
6540
+ const saved = await ctx.services.kyc.saveCredential({ protocolId: inputs.protocolDid, credentialType, credentialCid });
6541
+ if (!saved?.credentialCid) {
6542
+ throw new Error("kyc.saveCredential returned no credentialCid. Check the [kyc:saveCredential] handler logs.");
6543
+ }
6544
+ const output = {
6545
+ credentialCid: saved.credentialCid,
6546
+ credentialType: saved.credentialType,
6547
+ protocolId: inputs.protocolDid,
6548
+ status: "complete"
6549
+ };
6550
+ return {
6551
+ output,
6552
+ events: [{ name: "kyc.completed", payload: output }]
6553
+ };
6554
+ }
6555
+ });
6556
+
6537
6557
  // src/core/lib/actionRegistry/actions/_shared/delegatedTool.ts
6538
6558
  function parseBoundConnection(raw) {
6539
6559
  if (!raw || typeof raw !== "object") return null;
@@ -10587,42 +10607,6 @@ import * as Y3 from "yjs";
10587
10607
 
10588
10608
  // src/core/lib/flowEngine/readBackReconciler.ts
10589
10609
  import * as Y2 from "yjs";
10590
- function isYDoc(value) {
10591
- return value instanceof Y2.Doc;
10592
- }
10593
- function getYDoc(editorOrYDoc) {
10594
- if (!editorOrYDoc) return void 0;
10595
- if (isYDoc(editorOrYDoc)) return editorOrYDoc;
10596
- return editorOrYDoc._yDoc;
10597
- }
10598
- function getEditor(editorOrYDoc) {
10599
- return editorOrYDoc && !isYDoc(editorOrYDoc) ? editorOrYDoc : void 0;
10600
- }
10601
- function getRuntime(editorOrYDoc, runtime) {
10602
- if (runtime) return runtime;
10603
- const yDoc = getYDoc(editorOrYDoc);
10604
- if (yDoc) return createYDocRuntimeManager(yDoc);
10605
- return createRuntimeStateManager(!isYDoc(editorOrYDoc) ? editorOrYDoc : void 0);
10606
- }
10607
- function getReconcileEditor(params, yDoc, editor) {
10608
- if (editor) return editor;
10609
- if (!yDoc || !params.document) return void 0;
10610
- return {
10611
- _yDoc: yDoc,
10612
- _yRuntime: yDoc.getMap("runtime"),
10613
- document: params.document
10614
- };
10615
- }
10616
- function makeRunId(now) {
10617
- return `readback-${now()}-${Math.random().toString(36).slice(2, 8)}`;
10618
- }
10619
- function asOutput(value) {
10620
- return value && typeof value === "object" && !Array.isArray(value) ? { ...value } : {};
10621
- }
10622
- function errorRecord(error) {
10623
- if (!error) return void 0;
10624
- return typeof error === "string" ? { message: error } : { message: error.message, code: error.code };
10625
- }
10626
10610
  function normalizeActionReadBackMetadata(params) {
10627
10611
  const base = params.readBack && typeof params.readBack === "object" && !Array.isArray(params.readBack) ? { ...params.readBack } : {};
10628
10612
  const kind = typeof base.kind === "string" && base.kind.trim() ? base.kind.trim() : params.actionType;
@@ -10647,221 +10631,14 @@ function normalizeActionReadBackMetadata(params) {
10647
10631
  }
10648
10632
  return normalized;
10649
10633
  }
10650
- function writeReconciliationRunRecord(params) {
10651
- if (!params.yDoc) return void 0;
10652
- const completedAt = params.now();
10653
- const runId = makeRunId(params.now);
10654
- const pendingInvocation = params.readBack.pendingInvocation;
10655
- const details = {
10656
- runId,
10657
- output: params.output,
10658
- events: params.events,
10659
- startedAt: params.readBack.requestedAt || new Date(completedAt).toISOString(),
10660
- completedAt: new Date(completedAt).toISOString(),
10661
- actorDid: params.actorDid,
10662
- invocationCid: params.readBack.invocationCid,
10663
- capabilityId: params.readBack.capabilityId,
10664
- error: params.error,
10665
- readBack: params.readBack,
10666
- reconciled: true
10667
- };
10668
- if (pendingInvocation) {
10669
- details.fromPendingInvocationId = pendingInvocation.id;
10670
- details.triggeredBy = {
10671
- sourceBlockId: pendingInvocation.triggeringBlockId,
10672
- eventName: pendingInvocation.eventName
10673
- };
10674
- details.sourceRunId = pendingInvocation.sourceRunId;
10675
- }
10676
- appendRunRecord(params.yDoc, params.blockId, details, params.actorDid);
10677
- if (params.editor && params.events.length > 0) {
10678
- reconcilePendingInvocations(params.editor);
10679
- }
10680
- return runId;
10681
- }
10682
- async function reconcileActionReadBack(params) {
10683
- const now = params.now || Date.now;
10684
- const yDoc = getYDoc(params.editorOrYDoc);
10685
- const editor = getEditor(params.editorOrYDoc);
10686
- const runtime = getRuntime(params.editorOrYDoc, params.runtime);
10687
- const current = runtime.get(params.blockId);
10688
- const output = asOutput(current.output);
10689
- const readBack = current.readBack;
10690
- if (current.state !== "awaiting_readback" || !readBack?.kind) {
10691
- return {
10692
- success: false,
10693
- blockId: params.blockId,
10694
- state: current.state === "failed" ? "failed" : "pending",
10695
- output,
10696
- events: [],
10697
- error: `Block "${params.blockId}" is not awaiting read-back`,
10698
- pendingInvocationRemoved: false,
10699
- readBack
10700
- };
10701
- }
10702
- const resolver = params.resolver || params.resolvers?.[readBack.kind];
10703
- if (!resolver) {
10704
- return {
10705
- success: false,
10706
- blockId: params.blockId,
10707
- state: "pending",
10708
- output,
10709
- events: [],
10710
- error: `No read-back resolver registered for "${readBack.kind}"`,
10711
- pendingInvocationRemoved: false,
10712
- readBack
10713
- };
10714
- }
10715
- const resolution = await resolver({
10716
- blockId: params.blockId,
10717
- runtime: current,
10718
- output,
10719
- readBack
10720
- });
10721
- const checkedAt = now();
10722
- const checkedIso = new Date(checkedAt).toISOString();
10723
- const nextReadBack = {
10724
- ...readBack,
10725
- ...resolution.readBack || {},
10726
- status: resolution.state,
10727
- lastCheckedAt: checkedIso
10728
- };
10729
- if (resolution.state === "pending") {
10730
- runtime.update(params.blockId, {
10731
- readBack: nextReadBack
10732
- });
10733
- return {
10734
- success: true,
10735
- blockId: params.blockId,
10736
- state: "pending",
10737
- output,
10738
- events: resolution.events || [],
10739
- pendingInvocationRemoved: false,
10740
- readBack: nextReadBack
10741
- };
10742
- }
10743
- const events = resolution.events || [];
10744
- const finalOutput = {
10745
- ...output,
10746
- ...resolution.output || {}
10747
- };
10748
- const actorDid = params.actorDid || readBack.actorDid || current.executedByDid || "system:readback";
10749
- if (resolution.state === "failed") {
10750
- const error = errorRecord(resolution.error) || { message: "External read-back failed" };
10751
- const failedReadBack = {
10752
- ...nextReadBack,
10753
- terminalAt: checkedIso
10754
- };
10755
- runtime.update(params.blockId, {
10756
- state: "failed",
10757
- output: finalOutput,
10758
- error: { ...error, at: checkedAt },
10759
- readBack: failedReadBack
10760
- });
10761
- const runId2 = writeReconciliationRunRecord({
10762
- yDoc,
10763
- editor: getReconcileEditor(params, yDoc, editor),
10764
- blockId: params.blockId,
10765
- actorDid,
10766
- output: finalOutput,
10767
- events,
10768
- readBack: failedReadBack,
10769
- error,
10770
- now
10771
- });
10772
- return {
10773
- success: false,
10774
- blockId: params.blockId,
10775
- state: "failed",
10776
- output: finalOutput,
10777
- events,
10778
- error: error.message,
10779
- runId: runId2,
10780
- pendingInvocationRemoved: false,
10781
- readBack: failedReadBack
10782
- };
10783
- }
10784
- const readBackActionType = readBack.actionType || readBack.kind;
10785
- const actionDef = readBackActionType ? getAction(readBackActionType) : void 0;
10786
- if (actionDef) {
10787
- const proofCheck = validateActionProof(actionDef, finalOutput || {});
10788
- if (!proofCheck.valid) {
10789
- const message = proofCheck.reason || "Read-back resolved completed without proof of execution.";
10790
- const proofFailedReadBack = {
10791
- ...nextReadBack,
10792
- terminalAt: checkedIso
10793
- };
10794
- runtime.update(params.blockId, {
10795
- state: actionDef.sideEffect ? "needs_verification" : "failed",
10796
- output: finalOutput,
10797
- error: { message, code: PROOF_MISSING_CODE, at: checkedAt },
10798
- readBack: proofFailedReadBack
10799
- });
10800
- const failedRunId = writeReconciliationRunRecord({
10801
- yDoc,
10802
- editor: getReconcileEditor(params, yDoc, editor),
10803
- blockId: params.blockId,
10804
- actorDid,
10805
- output: finalOutput,
10806
- events,
10807
- readBack: proofFailedReadBack,
10808
- error: { message, code: PROOF_MISSING_CODE },
10809
- now
10810
- });
10811
- return {
10812
- success: false,
10813
- blockId: params.blockId,
10814
- state: "failed",
10815
- output: finalOutput,
10816
- events,
10817
- error: message,
10818
- runId: failedRunId,
10819
- pendingInvocationRemoved: false,
10820
- readBack: proofFailedReadBack
10821
- };
10822
- }
10823
- }
10824
- const completedReadBack = {
10825
- ...nextReadBack,
10826
- terminalAt: checkedIso
10827
- };
10828
- runtime.update(params.blockId, {
10829
- state: "completed",
10830
- output: finalOutput,
10831
- executedAt: checkedAt,
10832
- error: void 0,
10833
- readBack: completedReadBack
10834
- });
10835
- const runId = writeReconciliationRunRecord({
10836
- yDoc,
10837
- editor: getReconcileEditor(params, yDoc, editor),
10838
- blockId: params.blockId,
10839
- actorDid,
10840
- output: finalOutput,
10841
- events,
10842
- readBack: completedReadBack,
10843
- now
10844
- });
10845
- const pendingInvocationRemoved = Boolean(yDoc && completedReadBack.pendingInvocation?.id) && removePendingInvocation(yDoc, params.blockId, completedReadBack.pendingInvocation.id);
10846
- return {
10847
- success: true,
10848
- blockId: params.blockId,
10849
- state: "completed",
10850
- output: finalOutput,
10851
- events,
10852
- runId,
10853
- pendingInvocationRemoved,
10854
- readBack: completedReadBack
10855
- };
10856
- }
10857
10634
 
10858
10635
  // src/core/lib/flowEngine/actionExecutor.ts
10859
- function isYDoc2(value) {
10636
+ function isYDoc(value) {
10860
10637
  return value instanceof Y3.Doc;
10861
10638
  }
10862
- function getYDoc2(editorOrYDoc) {
10639
+ function getYDoc(editorOrYDoc) {
10863
10640
  if (!editorOrYDoc) return void 0;
10864
- if (isYDoc2(editorOrYDoc)) return editorOrYDoc;
10641
+ if (isYDoc(editorOrYDoc)) return editorOrYDoc;
10865
10642
  return editorOrYDoc._yDoc;
10866
10643
  }
10867
10644
  function parseInputs2(value) {
@@ -10876,20 +10653,20 @@ function parseInputs2(value) {
10876
10653
  return {};
10877
10654
  }
10878
10655
  }
10879
- function getRuntime2(editorOrYDoc, runtime) {
10656
+ function getRuntime(editorOrYDoc, runtime) {
10880
10657
  if (runtime) return runtime;
10881
- const yDoc = getYDoc2(editorOrYDoc);
10658
+ const yDoc = getYDoc(editorOrYDoc);
10882
10659
  if (yDoc) return createYDocRuntimeManager(yDoc);
10883
- return createRuntimeStateManager(!isYDoc2(editorOrYDoc) ? editorOrYDoc : void 0);
10660
+ return createRuntimeStateManager(!isYDoc(editorOrYDoc) ? editorOrYDoc : void 0);
10884
10661
  }
10885
- function getEditor2(editorOrYDoc) {
10886
- return editorOrYDoc && !isYDoc2(editorOrYDoc) ? editorOrYDoc : void 0;
10662
+ function getEditor(editorOrYDoc) {
10663
+ return editorOrYDoc && !isYDoc(editorOrYDoc) ? editorOrYDoc : void 0;
10887
10664
  }
10888
10665
  function findBlock(params) {
10889
10666
  if (params.block) return params.block;
10890
10667
  const blockId = params.blockId;
10891
10668
  if (!blockId) return void 0;
10892
- const editor = getEditor2(params.editorOrYDoc);
10669
+ const editor = getEditor(params.editorOrYDoc);
10893
10670
  return (params.document || editor?.document || []).find((block) => block?.id === blockId);
10894
10671
  }
10895
10672
  function getFlowMetadata(editor) {
@@ -10923,8 +10700,8 @@ function getNodeOutput(runtime, nodeId) {
10923
10700
  }
10924
10701
  function buildActionRunInputs(params) {
10925
10702
  const blockId = params.blockId || params.block?.id;
10926
- const yDoc = getYDoc2(params.editorOrYDoc);
10927
- const runtime = getRuntime2(params.editorOrYDoc, params.runtime);
10703
+ const yDoc = getYDoc(params.editorOrYDoc);
10704
+ const runtime = getRuntime(params.editorOrYDoc, params.runtime);
10928
10705
  const savedInputs = parseInputs2(params.savedInputs ?? params.block?.props?.inputs);
10929
10706
  const pendingInvocation = getPendingInvocation(yDoc, blockId, params.pendingInvocationId);
10930
10707
  const triggerContext = pendingInvocation ? {
@@ -10963,10 +10740,10 @@ function updateRuntimeFailure(runtime, blockId, message, now) {
10963
10740
  error: { message, at: now() }
10964
10741
  });
10965
10742
  }
10966
- function makeRunId2(now) {
10743
+ function makeRunId(now) {
10967
10744
  return `run-${now()}-${Math.random().toString(36).slice(2, 8)}`;
10968
10745
  }
10969
- function getReconcileEditor2(params, yDoc, editor) {
10746
+ function getReconcileEditor(params, yDoc, editor) {
10970
10747
  if (editor) return editor;
10971
10748
  if (!yDoc || !params.document) return void 0;
10972
10749
  return {
@@ -10977,7 +10754,7 @@ function getReconcileEditor2(params, yDoc, editor) {
10977
10754
  }
10978
10755
  function persistEvents(params) {
10979
10756
  if (!params.yDoc || params.events.length === 0) return void 0;
10980
- const runId = makeRunId2(params.now);
10757
+ const runId = makeRunId(params.now);
10981
10758
  const details = {
10982
10759
  runId,
10983
10760
  output: params.output,
@@ -11009,9 +10786,9 @@ function cleanupCompletedPendingInvocation(yDoc, blockId, pendingInvocation) {
11009
10786
  async function executeActionBlock(params) {
11010
10787
  const block = findBlock(params);
11011
10788
  const blockId = params.blockId || block?.id;
11012
- const editor = getEditor2(params.editorOrYDoc);
11013
- const yDoc = getYDoc2(params.editorOrYDoc);
11014
- const runtime = getRuntime2(params.editorOrYDoc, params.runtime);
10789
+ const editor = getEditor(params.editorOrYDoc);
10790
+ const yDoc = getYDoc(params.editorOrYDoc);
10791
+ const runtime = getRuntime(params.editorOrYDoc, params.runtime);
11015
10792
  const now = params.now || Date.now;
11016
10793
  if (!block || !blockId) {
11017
10794
  return buildFailureResult({
@@ -11171,7 +10948,7 @@ async function executeActionBlock(params) {
11171
10948
  });
11172
10949
  const runId = persistEvents({
11173
10950
  yDoc,
11174
- editor: getReconcileEditor2(params, yDoc, editor),
10951
+ editor: getReconcileEditor(params, yDoc, editor),
11175
10952
  blockId,
11176
10953
  actorDid: params.actorDid,
11177
10954
  output,
@@ -11433,7 +11210,6 @@ var ICON_DEFAULTS = {
11433
11210
  "domain/card-preview": "id",
11434
11211
  "domain/sign": "feather",
11435
11212
  "credential/store": "shield",
11436
- "payment/execute": "credit-card",
11437
11213
  "http/request": "cloud",
11438
11214
  "protocol/select": "git-branch",
11439
11215
  "human/checkbox": "check-square",
@@ -12931,7 +12707,7 @@ var BLOCKER_DIAGNOSIS_VERSION = 2;
12931
12707
  function getBlocks(context) {
12932
12708
  return context.blocks || context.editor?.document || [];
12933
12709
  }
12934
- function getRuntime3(yDoc, nodeId) {
12710
+ function getRuntime2(yDoc, nodeId) {
12935
12711
  const runtime = yDoc.getMap("runtime");
12936
12712
  const value = runtime.get(nodeId);
12937
12713
  return value && typeof value === "object" ? value : {};
@@ -13141,7 +12917,7 @@ function planRalphLoopCommands(context, options = {}) {
13141
12917
  const nodeId = getBlockId(block);
13142
12918
  if (!nodeId) continue;
13143
12919
  const pendingInvocationCount = readPendingInvocations(context.yDoc, nodeId).length;
13144
- const runtime = getRuntime3(context.yDoc, nodeId);
12920
+ const runtime = getRuntime2(context.yDoc, nodeId);
13145
12921
  const actionType = getBlockActionType(block);
13146
12922
  const completionVerification = verifyCompletion({
13147
12923
  runtime,
@@ -13833,7 +13609,6 @@ export {
13833
13609
  executeNode,
13834
13610
  PROOF_MISSING_CODE,
13835
13611
  validateActionProof,
13836
- reconcileActionReadBack,
13837
13612
  buildActionRunInputs,
13838
13613
  executeActionBlock,
13839
13614
  verifyCompletion,
@@ -13894,4 +13669,4 @@ export {
13894
13669
  executeQueuedFlowAgentCoreCommands,
13895
13670
  FlowAgentService
13896
13671
  };
13897
- //# sourceMappingURL=chunk-KEGZJCNU.js.map
13672
+ //# sourceMappingURL=chunk-GUKGNTGT.js.map