@ixo/editor 6.17.0 → 6.19.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.
@@ -718,6 +718,8 @@ var CAN_TO_TYPE = {
718
718
  "bid/evaluate": "qi/bid.evaluate",
719
719
  "claim/submit": "qi/claim.submit",
720
720
  "claim/evaluate": "qi/claim.evaluate",
721
+ "collection/lifecycle": "qi/collection.lifecycle",
722
+ "collection/users": "qi/collection.users",
721
723
  "email/send": "qi/email.send",
722
724
  "notification/push": "qi/notification.push",
723
725
  "matrix/dm": "qi/matrix.dm",
@@ -740,6 +742,18 @@ var CAN_TO_TYPE = {
740
742
  "pod/governance-config": "qi/pod.governance-config",
741
743
  "pod/member-multi-select": "qi/pod.member-multi-select",
742
744
  "pod/list-domain-flows": "qi/pod.list-domain-flows",
745
+ "blueprint/workspace-start": "qi/blueprint.workspace-start",
746
+ "blueprint/journey-resume": "qi/blueprint.journey-resume",
747
+ "blueprint/guided-authoring": "qi/blueprint.guided-authoring",
748
+ "blueprint/artifact-preview": "qi/blueprint.artifact-preview",
749
+ "blueprint/artifact-save": "qi/blueprint.artifact-save",
750
+ "blueprint/checklist-update": "qi/blueprint.checklist-update",
751
+ "blueprint/phase-confirm": "qi/blueprint.phase-confirm",
752
+ "blueprint/reviewer-assign": "qi/blueprint.reviewer-assign",
753
+ "blueprint/review-submit": "qi/blueprint.review-submit",
754
+ "blueprint/review-respond": "qi/blueprint.review-respond",
755
+ "blueprint/release-compile": "qi/blueprint.release-compile",
756
+ "blueprint/publish": "qi/blueprint.publish",
743
757
  // Delegated integrations (author connects once, runners execute on their behalf)
744
758
  "gmail.email/send": "qi/gmail.email.send",
745
759
  "outlook.email/send": "qi/outlook.email.send",
@@ -838,6 +852,9 @@ function warnPartialServiceGroups(handlers) {
838
852
  function buildServicesFromHandlers(handlers) {
839
853
  warnPartialServiceGroups(handlers);
840
854
  return {
855
+ blueprint: handlers?.blueprint?.execute ? {
856
+ execute: async (params) => handlers.blueprint.execute(params)
857
+ } : void 0,
841
858
  http: {
842
859
  request: async (params) => {
843
860
  const fetchOptions = {
@@ -1651,6 +1668,240 @@ registerAction({
1651
1668
  }
1652
1669
  });
1653
1670
 
1671
+ // src/core/lib/actionRegistry/actions/blueprint.ts
1672
+ var OUTPUT_SCHEMA = [
1673
+ {
1674
+ path: "receiptRef",
1675
+ displayName: "Runtime receipt",
1676
+ type: "string",
1677
+ description: "Immutable Blueprint Runtime reference proving the governed operation completed."
1678
+ },
1679
+ {
1680
+ path: "result",
1681
+ displayName: "Result",
1682
+ type: "object",
1683
+ description: "The governed Blueprint Runtime result."
1684
+ }
1685
+ ];
1686
+ var WORKSPACE_ID = {
1687
+ type: "string",
1688
+ description: "Opaque Blueprint workspace reference supplied by Portal."
1689
+ };
1690
+ var ACTIONS = [
1691
+ {
1692
+ type: "qi/blueprint.workspace-start",
1693
+ can: "blueprint/workspace-start",
1694
+ sideEffect: true,
1695
+ confirmation: true,
1696
+ required: ["name"],
1697
+ properties: {
1698
+ name: {
1699
+ type: "string",
1700
+ description: "Plain-language name for the professional Service POD."
1701
+ }
1702
+ }
1703
+ },
1704
+ {
1705
+ type: "qi/blueprint.journey-resume",
1706
+ can: "blueprint/journey-resume",
1707
+ sideEffect: false,
1708
+ confirmation: false,
1709
+ required: ["workspaceId"],
1710
+ properties: { workspaceId: WORKSPACE_ID }
1711
+ },
1712
+ {
1713
+ type: "qi/blueprint.guided-authoring",
1714
+ can: "blueprint/guided-authoring",
1715
+ sideEffect: false,
1716
+ confirmation: false,
1717
+ required: ["workspaceId", "phase"],
1718
+ properties: {
1719
+ workspaceId: WORKSPACE_ID,
1720
+ phase: {
1721
+ type: "string",
1722
+ description: "The current product phase: discovery, design, validation, testing, or deployment."
1723
+ }
1724
+ }
1725
+ },
1726
+ {
1727
+ type: "qi/blueprint.artifact-preview",
1728
+ can: "blueprint/artifact-preview",
1729
+ sideEffect: false,
1730
+ confirmation: false,
1731
+ required: ["workspaceId", "stage", "content"],
1732
+ properties: {
1733
+ workspaceId: WORKSPACE_ID,
1734
+ stage: {
1735
+ type: "string",
1736
+ description: "Internal Blueprint control receiving the draft."
1737
+ },
1738
+ content: {
1739
+ type: "object",
1740
+ description: "Draft artifact content to validate without saving."
1741
+ }
1742
+ }
1743
+ },
1744
+ {
1745
+ type: "qi/blueprint.artifact-save",
1746
+ can: "blueprint/artifact-save",
1747
+ sideEffect: true,
1748
+ confirmation: true,
1749
+ required: ["workspaceId", "stage", "content"],
1750
+ properties: {
1751
+ workspaceId: WORKSPACE_ID,
1752
+ stage: {
1753
+ type: "string",
1754
+ description: "Internal Blueprint control receiving the approved draft."
1755
+ },
1756
+ content: {
1757
+ type: "object",
1758
+ description: "User-confirmed artifact content to save."
1759
+ }
1760
+ }
1761
+ },
1762
+ {
1763
+ type: "qi/blueprint.checklist-update",
1764
+ can: "blueprint/checklist-update",
1765
+ sideEffect: true,
1766
+ confirmation: true,
1767
+ required: ["workspaceId", "operation"],
1768
+ properties: {
1769
+ workspaceId: WORKSPACE_ID,
1770
+ operation: {
1771
+ type: "string",
1772
+ description: "Add, accept for later, or resolve a checklist item."
1773
+ },
1774
+ item: {
1775
+ type: "object",
1776
+ description: "Checklist proposal or disposition selected by the user."
1777
+ }
1778
+ }
1779
+ },
1780
+ {
1781
+ type: "qi/blueprint.phase-confirm",
1782
+ can: "blueprint/phase-confirm",
1783
+ sideEffect: true,
1784
+ confirmation: true,
1785
+ required: ["workspaceId", "phase"],
1786
+ properties: {
1787
+ workspaceId: WORKSPACE_ID,
1788
+ phase: {
1789
+ type: "string",
1790
+ description: "Discovery, design, validation, testing, or deployment."
1791
+ }
1792
+ }
1793
+ },
1794
+ {
1795
+ type: "qi/blueprint.reviewer-assign",
1796
+ can: "blueprint/reviewer-assign",
1797
+ sideEffect: true,
1798
+ confirmation: true,
1799
+ required: ["workspaceId"],
1800
+ properties: {
1801
+ workspaceId: WORKSPACE_ID,
1802
+ reviewer: {
1803
+ type: "object",
1804
+ description: "Portal-selected independent reviewer or IXO-supported review request."
1805
+ }
1806
+ }
1807
+ },
1808
+ {
1809
+ type: "qi/blueprint.review-submit",
1810
+ can: "blueprint/review-submit",
1811
+ sideEffect: true,
1812
+ confirmation: true,
1813
+ required: ["workspaceId"],
1814
+ properties: { workspaceId: WORKSPACE_ID }
1815
+ },
1816
+ {
1817
+ type: "qi/blueprint.review-respond",
1818
+ can: "blueprint/review-respond",
1819
+ sideEffect: true,
1820
+ confirmation: true,
1821
+ required: ["workspaceId", "response"],
1822
+ properties: {
1823
+ workspaceId: WORKSPACE_ID,
1824
+ response: {
1825
+ type: "object",
1826
+ description: "Reviewer decision or provider response bound to the complete revision set."
1827
+ }
1828
+ }
1829
+ },
1830
+ {
1831
+ type: "qi/blueprint.release-compile",
1832
+ can: "blueprint/release-compile",
1833
+ sideEffect: true,
1834
+ confirmation: true,
1835
+ required: ["workspaceId"],
1836
+ properties: { workspaceId: WORKSPACE_ID }
1837
+ },
1838
+ {
1839
+ type: "qi/blueprint.publish",
1840
+ can: "blueprint/publish",
1841
+ sideEffect: true,
1842
+ confirmation: true,
1843
+ required: ["workspaceId", "releaseRef", "network"],
1844
+ properties: {
1845
+ workspaceId: WORKSPACE_ID,
1846
+ releaseRef: {
1847
+ type: "string",
1848
+ description: "Exact approved release to publish."
1849
+ },
1850
+ network: {
1851
+ type: "string",
1852
+ description: "Target IXO network selected by the user."
1853
+ }
1854
+ }
1855
+ }
1856
+ ];
1857
+ function requireInputs(inputs, required) {
1858
+ for (const field of required) {
1859
+ const value = inputs[field];
1860
+ if (value === void 0 || value === null || typeof value === "string" && value.trim().length === 0) {
1861
+ throw new Error(`${field} is required`);
1862
+ }
1863
+ }
1864
+ }
1865
+ async function executeBlueprintAction(spec, inputs, ctx) {
1866
+ requireInputs(inputs, spec.required);
1867
+ const execute = ctx.services.blueprint?.execute;
1868
+ if (!execute) {
1869
+ throw new Error(`${spec.type} handler not available`);
1870
+ }
1871
+ const response = await execute({
1872
+ action: spec.type,
1873
+ inputs,
1874
+ actorDid: ctx.actorDid,
1875
+ flowId: ctx.flowId,
1876
+ nodeId: ctx.nodeId
1877
+ });
1878
+ if (!response.receiptRef) {
1879
+ throw new Error(`${spec.type} returned no Blueprint Runtime receipt`);
1880
+ }
1881
+ return {
1882
+ output: {
1883
+ receiptRef: response.receiptRef,
1884
+ result: response.result ?? {}
1885
+ }
1886
+ };
1887
+ }
1888
+ for (const spec of ACTIONS) {
1889
+ registerAction({
1890
+ type: spec.type,
1891
+ can: spec.can,
1892
+ sideEffect: spec.sideEffect,
1893
+ defaultRequiresConfirmation: spec.confirmation,
1894
+ proof: { fields: ["receiptRef"] },
1895
+ inputSchema: {
1896
+ type: "object",
1897
+ required: spec.required,
1898
+ properties: spec.properties
1899
+ },
1900
+ outputSchema: OUTPUT_SCHEMA,
1901
+ run: async (inputs, ctx) => executeBlueprintAction(spec, inputs, ctx)
1902
+ });
1903
+ }
1904
+
1654
1905
  // src/core/lib/actionRegistry/actions/governance/memberProposal.ts
1655
1906
  var VALID_OPERATIONS = ["add", "remove", "update-weight"];
1656
1907
  function defaultTitle(operation, count) {
@@ -1681,6 +1932,15 @@ registerAction({
1681
1932
  { path: "operation", displayName: "Operation", type: "string", description: "add | remove | update-weight" },
1682
1933
  { path: "createdAt", displayName: "Created At", type: "string", description: "ISO timestamp of proposal creation" }
1683
1934
  ],
1935
+ // Mirrors run()'s throw-preamble (there is no inputSchema to declare
1936
+ // requiredness on): coreAddress, operation and a non-empty members list.
1937
+ getMissingInputs: (inputs) => {
1938
+ const missing = [];
1939
+ if (!String(inputs.coreAddress || "").trim()) missing.push("coreAddress");
1940
+ if (!String(inputs.operation || "").trim()) missing.push("operation");
1941
+ if (!Array.isArray(inputs.members) || inputs.members.length === 0) missing.push("members");
1942
+ return missing;
1943
+ },
1684
1944
  run: async (inputs, ctx) => {
1685
1945
  const handlers = ctx.handlers;
1686
1946
  if (!handlers) {
@@ -1770,6 +2030,17 @@ registerAction({
1770
2030
  { path: "coreAddress", displayName: "Core Address", type: "string", description: "The DAO core contract address" },
1771
2031
  { path: "createdAt", displayName: "Created At", type: "string", description: "ISO timestamp of proposal creation" }
1772
2032
  ],
2033
+ // Mirrors run()'s throw-preamble (there is no inputSchema to declare
2034
+ // requiredness on): coreAddress and the three numeric voting settings.
2035
+ getMissingInputs: (inputs) => {
2036
+ const missing = [];
2037
+ if (!String(inputs.coreAddress || "").trim()) missing.push("coreAddress");
2038
+ for (const name of ["votingPeriodHours", "quorumPercent", "thresholdPercent"]) {
2039
+ const value = inputs[name];
2040
+ if (value === void 0 || value === null || String(value).trim() === "") missing.push(name);
2041
+ }
2042
+ return missing;
2043
+ },
1773
2044
  run: async (inputs, ctx) => {
1774
2045
  const handlers = ctx.handlers;
1775
2046
  if (!handlers) {
@@ -1964,6 +2235,17 @@ registerAction({
1964
2235
  { path: "recipient", displayName: "Recipient", type: "string", description: "Destination address of the spend" },
1965
2236
  { path: "createdAt", displayName: "Created At", type: "string", description: "ISO timestamp of proposal creation" }
1966
2237
  ],
2238
+ // Mirrors run()'s throw-preamble (there is no inputSchema to declare
2239
+ // requiredness on): coreAddress, recipient, denom and amount.
2240
+ getMissingInputs: (inputs) => {
2241
+ const missing = [];
2242
+ for (const name of ["coreAddress", "recipient", "denom"]) {
2243
+ if (!String(inputs[name] || "").trim()) missing.push(name);
2244
+ }
2245
+ const amount = inputs.amount;
2246
+ if (amount === void 0 || amount === null || String(amount).trim() === "") missing.push("amount");
2247
+ return missing;
2248
+ },
1967
2249
  run: async (inputs, ctx) => {
1968
2250
  const handlers = ctx.handlers;
1969
2251
  if (!handlers) {
@@ -2883,6 +3165,9 @@ registerAction({
2883
3165
  body: { type: "string", description: "Request body; sent for non-GET methods. Accepts a string or an object (serialized to JSON)." }
2884
3166
  }
2885
3167
  },
3168
+ // run() accepts `endpoint` OR `url` — mirror the alias the schema's
3169
+ // required array can't express.
3170
+ getMissingInputs: (inputs) => String(inputs.endpoint || inputs.url || "").trim() ? [] : ["endpoint"],
2886
3171
  run: async (inputs, ctx) => {
2887
3172
  const endpoint = inputs.endpoint ?? inputs.url;
2888
3173
  const url = typeof endpoint === "string" ? endpoint : "";
@@ -2953,6 +3238,14 @@ registerAction({
2953
3238
  { path: "messageId", displayName: "Message ID", type: "string", description: "The unique ID of the sent email" },
2954
3239
  { path: "sentAt", displayName: "Sent At", type: "string", description: "Timestamp when the email was sent" }
2955
3240
  ],
3241
+ // run() accepts `template` OR `templateName` for the template — the
3242
+ // schema's required array can't express the alias, so mirror the OR here.
3243
+ getMissingInputs: (inputs) => {
3244
+ const missing = [];
3245
+ if (!String(inputs.to || "").trim()) missing.push("to");
3246
+ if (!String(inputs.template || "").trim() && !String(inputs.templateName || "").trim()) missing.push("templateName");
3247
+ return missing;
3248
+ },
2956
3249
  run: async (inputs, ctx) => {
2957
3250
  if (!ctx.services.email) {
2958
3251
  throw new Error("Email service not configured");
@@ -7409,6 +7702,10 @@ registerAction({
7409
7702
  type: COLLECTION_LIFECYCLE_ACTION_TYPE,
7410
7703
  can: "collection/lifecycle",
7411
7704
  sideEffect: true,
7705
+ // Chain transaction signed as the entity admin — only the human in the
7706
+ // Portal FlowDetail holds that authority. Orchestrators gather inputs and
7707
+ // hand off; they must not run or delegate this.
7708
+ executionOwner: "human",
7412
7709
  // Dynamic resolvers predate merge-by-default and intentionally control
7413
7710
  // the full vocabulary (e.g. returning [] to hide the static baseline).
7414
7711
  dynamicResolutionMode: "replace",
@@ -7671,6 +7968,10 @@ registerAction({
7671
7968
  type: COLLECTION_USERS_ACTION_TYPE,
7672
7969
  can: "collection/users",
7673
7970
  sideEffect: true,
7971
+ // Authz grants signed by the entity admin — only the human in the Portal
7972
+ // FlowDetail holds that authority. Orchestrators gather inputs and hand
7973
+ // off; they must not run or delegate this.
7974
+ executionOwner: "human",
7674
7975
  // Dynamic resolvers predate merge-by-default and intentionally control
7675
7976
  // the full vocabulary (e.g. returning [] to hide the static baseline).
7676
7977
  dynamicResolutionMode: "replace",
@@ -7707,6 +8008,16 @@ registerAction({
7707
8008
  members: { type: "array", description: "Resolved members to fan the grant out to when granteeKind is group-members." }
7708
8009
  }
7709
8010
  },
8011
+ // Only the decision inputs are human-askable: `operation` selects the
8012
+ // branch and `collectionId` targets the collection (often filled by the
8013
+ // `created` event of an upstream collection.lifecycle block). adminAddress,
8014
+ // role and grantee fields are resolved by the host/FlowDetail, so a blank
8015
+ // there is not something to escalate to a human for.
8016
+ getMissingInputs: (inputs) => {
8017
+ const operation = String(inputs?.operation || "").trim();
8018
+ if (!operation) return ["operation"];
8019
+ return String(inputs?.collectionId || "").trim() ? [] : ["collectionId"];
8020
+ },
7710
8021
  run: async (inputs, ctx) => {
7711
8022
  const service = ctx.services.collectionUsers;
7712
8023
  if (!service) {
@@ -8169,6 +8480,13 @@ function fieldValues(inputs) {
8169
8480
  function missingRequired(schema, values) {
8170
8481
  return (schema.parameters.required || []).filter((name) => !(values[name] ?? "").trim());
8171
8482
  }
8483
+ function delegatedToolMissingInputs(schema, rawInputs) {
8484
+ const parsed = parseDelegatedToolInputs(rawInputs);
8485
+ const missing = [];
8486
+ if (!parsed.connection?.bindingId) missing.push("connection");
8487
+ missing.push(...missingRequired(schema, fieldValues(parsed)));
8488
+ return missing;
8489
+ }
8172
8490
  function coerceToolArgs(schema, values) {
8173
8491
  const out = {};
8174
8492
  for (const [name, prop] of Object.entries(schema.parameters.properties || {})) {
@@ -8252,6 +8570,9 @@ registerAction({
8252
8570
  requiredCapability: "flow/block/execute",
8253
8571
  // Can be wired to another block's event (e.g. form submitted → send email).
8254
8572
  eligibleForEventTrigger: true,
8573
+ // Mirrors executeDelegatedTool's gates: the bound connection plus the
8574
+ // tool schema's required fields, so orchestrators ask before run() throws.
8575
+ getMissingInputs: (inputs) => delegatedToolMissingInputs(GMAIL_SEND_SCHEMA, inputs),
8255
8576
  outputSchema: GMAIL_SEND_OUTPUT_SCHEMA,
8256
8577
  events: [
8257
8578
  {
@@ -8329,6 +8650,9 @@ registerAction({
8329
8650
  requiredCapability: "flow/block/execute",
8330
8651
  // Can be wired to another block's event (e.g. form submitted → send email).
8331
8652
  eligibleForEventTrigger: true,
8653
+ // Mirrors executeDelegatedTool's gates: the bound connection plus the
8654
+ // tool schema's required fields, so orchestrators ask before run() throws.
8655
+ getMissingInputs: (inputs) => delegatedToolMissingInputs(OUTLOOK_SEND_SCHEMA, inputs),
8332
8656
  outputSchema: OUTLOOK_SEND_OUTPUT_SCHEMA,
8333
8657
  events: [
8334
8658
  {
@@ -8403,6 +8727,9 @@ registerAction({
8403
8727
  requiredCapability: "flow/block/execute",
8404
8728
  // Can be wired to another block's event (e.g. form submitted → post message).
8405
8729
  eligibleForEventTrigger: true,
8730
+ // Mirrors executeDelegatedTool's gates: the bound connection plus the
8731
+ // tool schema's required fields, so orchestrators ask before run() throws.
8732
+ getMissingInputs: (inputs) => delegatedToolMissingInputs(SLACK_SEND_SCHEMA, inputs),
8406
8733
  outputSchema: SLACK_SEND_OUTPUT_SCHEMA,
8407
8734
  events: [
8408
8735
  {
@@ -8479,6 +8806,9 @@ registerAction({
8479
8806
  defaultRequiresConfirmation: true,
8480
8807
  requiredCapability: "flow/block/execute",
8481
8808
  eligibleForEventTrigger: true,
8809
+ // Mirrors executeDelegatedTool's gates: the bound connection plus the
8810
+ // tool schema's required fields, so orchestrators ask before run() throws.
8811
+ getMissingInputs: (inputs) => delegatedToolMissingInputs(GOOGLECALENDAR_CREATE_SCHEMA, inputs),
8482
8812
  outputSchema: GOOGLECALENDAR_CREATE_OUTPUT_SCHEMA,
8483
8813
  events: [
8484
8814
  {
@@ -15221,4 +15551,4 @@ export {
15221
15551
  executeQueuedFlowAgentCoreCommands,
15222
15552
  FlowAgentService
15223
15553
  };
15224
- //# sourceMappingURL=chunk-7GS4HTDO.js.map
15554
+ //# sourceMappingURL=chunk-2WSXLAX5.js.map