@ixo/editor 5.38.0 → 5.39.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.
- package/dist/{chunk-VBNP5MV5.js → chunk-JXTHVI23.js} +4 -4
- package/dist/{chunk-VBNP5MV5.js.map → chunk-JXTHVI23.js.map} +1 -1
- package/dist/{chunk-G4ZJJPZY.js → chunk-RDM56DB7.js} +1412 -943
- package/dist/chunk-RDM56DB7.js.map +1 -0
- package/dist/{chunk-7MGFSE63.js → chunk-YWZJYSOP.js} +439 -7
- package/dist/chunk-YWZJYSOP.js.map +1 -0
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +2 -2
- package/dist/{graphql-client-BCvy3UcL.d.ts → graphql-client-jOgmcMNg.d.ts} +1 -1
- package/dist/{index-bxGFYpnb.d.ts → index-B4Qe8xbv.d.ts} +47 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/mantine/index.d.ts +3 -3
- package/dist/mantine/index.js +2 -2
- package/dist/{store-BjCD9Lpk.d.ts → store-B-2A-Tlv.d.ts} +20 -7
- package/package.json +1 -1
- package/dist/chunk-7MGFSE63.js.map +0 -1
- package/dist/chunk-G4ZJJPZY.js.map +0 -1
|
@@ -116,7 +116,12 @@ var CAN_TO_TYPE = {
|
|
|
116
116
|
"pod/governance-config": "qi/pod.governance-config",
|
|
117
117
|
"pod/member-multi-select": "qi/pod.member-multi-select",
|
|
118
118
|
"pod/list-domain-flows": "qi/pod.list-domain-flows",
|
|
119
|
-
//
|
|
119
|
+
// Delegated integrations (author connects once, runners execute on their behalf)
|
|
120
|
+
"gmail.email/send": "qi/gmail.email.send",
|
|
121
|
+
"outlook.email/send": "qi/outlook.email.send",
|
|
122
|
+
"slack.message/send": "qi/slack.message.send",
|
|
123
|
+
"googlecalendar.event/create": "qi/googlecalendar.event.create",
|
|
124
|
+
// Calendar integration (self-connected)
|
|
120
125
|
"calendar.event/create": "qi/calendar.event.create",
|
|
121
126
|
"calendar.event/update": "qi/calendar.event.update",
|
|
122
127
|
"calendar.event/list": "qi/calendar.event.list",
|
|
@@ -238,7 +243,8 @@ function buildServicesFromHandlers(handlers) {
|
|
|
238
243
|
integrations: handlers?.integrations?.executeTool ? {
|
|
239
244
|
executeTool: async (args) => handlers.integrations.executeTool(args),
|
|
240
245
|
fetchCurrentState: handlers.integrations.fetchCurrentState ? async (args) => handlers.integrations.fetchCurrentState(args) : void 0,
|
|
241
|
-
getEntityDid: handlers?.getEntityDid ? () => handlers.getEntityDid() : void 0
|
|
246
|
+
getEntityDid: handlers?.getEntityDid ? () => handlers.getEntityDid() : void 0,
|
|
247
|
+
executeBinding: handlers.integrations.executeBinding ? async (args) => handlers.integrations.executeBinding(args) : void 0
|
|
242
248
|
} : void 0,
|
|
243
249
|
oracle: handlers?.generateWallet ? {
|
|
244
250
|
generateWallet: async () => handlers.generateWallet(),
|
|
@@ -1157,6 +1163,10 @@ function registerFormSubmitAction(type, can) {
|
|
|
1157
1163
|
sideEffect: true,
|
|
1158
1164
|
defaultRequiresConfirmation: false,
|
|
1159
1165
|
requiredCapability: "flow/execute",
|
|
1166
|
+
// Additive: makes the form an event SOURCE so downstream blocks can
|
|
1167
|
+
// auto-trigger on submission (e.g. form → send email). Nothing existing
|
|
1168
|
+
// consumes this; it only enables new event wiring.
|
|
1169
|
+
eligibleForEventTrigger: true,
|
|
1160
1170
|
inputSchema: {
|
|
1161
1171
|
type: "object",
|
|
1162
1172
|
required: [],
|
|
@@ -1168,6 +1178,15 @@ function registerFormSubmitAction(type, can) {
|
|
|
1168
1178
|
{ path: "form.answers", displayName: "Form Answers JSON", type: "string", description: "JSON stringified form answers, matching form block runtime output." },
|
|
1169
1179
|
{ path: "answers", displayName: "Form Answers", type: "object", description: "Parsed form answers object for convenience." }
|
|
1170
1180
|
],
|
|
1181
|
+
events: [
|
|
1182
|
+
{
|
|
1183
|
+
name: "form.submitted",
|
|
1184
|
+
displayName: "Form submitted",
|
|
1185
|
+
description: "Fires when the human submits the form. Payload carries the parsed answers.",
|
|
1186
|
+
payloadSchema: [{ path: "answers", displayName: "Form Answers", type: "object" }],
|
|
1187
|
+
pendingDisplayFields: ["answers"]
|
|
1188
|
+
}
|
|
1189
|
+
],
|
|
1171
1190
|
run: async (inputs) => {
|
|
1172
1191
|
const answers = normalizeAnswers(inputs.answers ?? inputs.form?.answers);
|
|
1173
1192
|
const answersJson = JSON.stringify(answers);
|
|
@@ -1177,7 +1196,8 @@ function registerFormSubmitAction(type, can) {
|
|
|
1177
1196
|
answers: answersJson
|
|
1178
1197
|
},
|
|
1179
1198
|
answers
|
|
1180
|
-
}
|
|
1199
|
+
},
|
|
1200
|
+
events: [{ name: "form.submitted", payload: { answers } }]
|
|
1181
1201
|
};
|
|
1182
1202
|
}
|
|
1183
1203
|
});
|
|
@@ -6292,6 +6312,379 @@ registerAction({
|
|
|
6292
6312
|
}
|
|
6293
6313
|
});
|
|
6294
6314
|
|
|
6315
|
+
// src/core/lib/actionRegistry/actions/_shared/delegatedTool.ts
|
|
6316
|
+
function parseBoundConnection(raw) {
|
|
6317
|
+
if (!raw || typeof raw !== "object") return null;
|
|
6318
|
+
const c = raw;
|
|
6319
|
+
if (typeof c.bindingId !== "string" || !c.bindingId) return null;
|
|
6320
|
+
if (typeof c.connectedAccountId !== "string") return null;
|
|
6321
|
+
if (typeof c.toolkit !== "string") return null;
|
|
6322
|
+
return {
|
|
6323
|
+
bindingId: c.bindingId,
|
|
6324
|
+
connectedAccountId: c.connectedAccountId,
|
|
6325
|
+
toolkit: c.toolkit,
|
|
6326
|
+
label: typeof c.label === "string" ? c.label : null
|
|
6327
|
+
};
|
|
6328
|
+
}
|
|
6329
|
+
function parseDelegatedToolInputs(raw) {
|
|
6330
|
+
let parsed = {};
|
|
6331
|
+
try {
|
|
6332
|
+
parsed = typeof raw === "string" ? JSON.parse(raw || "{}") : raw || {};
|
|
6333
|
+
} catch {
|
|
6334
|
+
parsed = {};
|
|
6335
|
+
}
|
|
6336
|
+
return { ...parsed, connection: parseBoundConnection(parsed.connection) };
|
|
6337
|
+
}
|
|
6338
|
+
function serializeDelegatedToolInputs(inputs) {
|
|
6339
|
+
return JSON.stringify(inputs);
|
|
6340
|
+
}
|
|
6341
|
+
function fieldValues(inputs) {
|
|
6342
|
+
const out = {};
|
|
6343
|
+
for (const [k, v] of Object.entries(inputs)) {
|
|
6344
|
+
if (k === "connection") continue;
|
|
6345
|
+
if (typeof v === "string") out[k] = v;
|
|
6346
|
+
}
|
|
6347
|
+
return out;
|
|
6348
|
+
}
|
|
6349
|
+
function missingRequired(schema, values) {
|
|
6350
|
+
return (schema.parameters.required || []).filter((name) => !(values[name] ?? "").trim());
|
|
6351
|
+
}
|
|
6352
|
+
function coerceToolArgs(schema, values) {
|
|
6353
|
+
const out = {};
|
|
6354
|
+
for (const [name, prop] of Object.entries(schema.parameters.properties || {})) {
|
|
6355
|
+
const raw = values[name];
|
|
6356
|
+
if (typeof raw !== "string" || raw.trim() === "") continue;
|
|
6357
|
+
const type = prop.type;
|
|
6358
|
+
if (type === "boolean") {
|
|
6359
|
+
out[name] = raw === "true";
|
|
6360
|
+
} else if (type === "array") {
|
|
6361
|
+
out[name] = raw.split(/[\n,]+/).map((s) => s.trim()).filter(Boolean);
|
|
6362
|
+
} else if (type === "number" || type === "integer") {
|
|
6363
|
+
const n = Number(raw);
|
|
6364
|
+
if (!Number.isNaN(n)) out[name] = n;
|
|
6365
|
+
} else {
|
|
6366
|
+
out[name] = raw;
|
|
6367
|
+
}
|
|
6368
|
+
}
|
|
6369
|
+
return out;
|
|
6370
|
+
}
|
|
6371
|
+
async function executeDelegatedTool(ctx, opts) {
|
|
6372
|
+
const svc = ctx.services.integrations;
|
|
6373
|
+
if (!svc?.executeBinding) {
|
|
6374
|
+
throw new Error(`${opts.toolkitLabel} integration is not configured.`);
|
|
6375
|
+
}
|
|
6376
|
+
const bindingId = opts.connection?.bindingId;
|
|
6377
|
+
if (!bindingId) {
|
|
6378
|
+
throw new Error(`No ${opts.toolkitLabel} account is bound. The template author must connect and bind ${opts.toolkitLabel}.`);
|
|
6379
|
+
}
|
|
6380
|
+
const missing = missingRequired(opts.schema, opts.values);
|
|
6381
|
+
if (missing.length > 0) {
|
|
6382
|
+
throw new Error(`Missing required field${missing.length === 1 ? "" : "s"}: ${missing.join(", ")}`);
|
|
6383
|
+
}
|
|
6384
|
+
const args = coerceToolArgs(opts.schema, opts.values);
|
|
6385
|
+
const result = await svc.executeBinding({ bindingId, toolSlug: opts.toolSlug, arguments: args });
|
|
6386
|
+
if (!result.successful) {
|
|
6387
|
+
if (result.code === "AUTH_EXPIRED") {
|
|
6388
|
+
throw new Error(`The template author's ${opts.toolkitLabel} access expired \u2014 they need to reconnect it in the template.`);
|
|
6389
|
+
}
|
|
6390
|
+
if (result.code === "UPSTREAM_4XX" && /not found|removed/i.test(result.error || "")) {
|
|
6391
|
+
throw new Error(`This ${opts.toolkitLabel} integration was removed by the template author.`);
|
|
6392
|
+
}
|
|
6393
|
+
throw new Error(result.error || `${opts.toolkitLabel} action failed.`);
|
|
6394
|
+
}
|
|
6395
|
+
return result.data ?? {};
|
|
6396
|
+
}
|
|
6397
|
+
|
|
6398
|
+
// src/core/lib/actionRegistry/actions/gmail/emailSend.types.ts
|
|
6399
|
+
var GMAIL_SEND_SLUG = "GMAIL_SEND_EMAIL";
|
|
6400
|
+
var GMAIL_SENT_EVENT = "email.sent";
|
|
6401
|
+
var GMAIL_SEND_SCHEMA = {
|
|
6402
|
+
slug: GMAIL_SEND_SLUG,
|
|
6403
|
+
name: "Send Email",
|
|
6404
|
+
description: "Send an email from the template author's Gmail account.",
|
|
6405
|
+
parameters: {
|
|
6406
|
+
type: "object",
|
|
6407
|
+
required: ["recipient_email", "body"],
|
|
6408
|
+
properties: {
|
|
6409
|
+
recipient_email: { type: "string", title: "To", description: "Recipient's email address." },
|
|
6410
|
+
subject: { type: "string", title: "Subject" },
|
|
6411
|
+
body: { type: "string", title: "Body", description: 'Email body. Plain text unless "HTML body" is set.' },
|
|
6412
|
+
cc: { type: "array", title: "Cc", description: "Comma-separated email addresses." },
|
|
6413
|
+
bcc: { type: "array", title: "Bcc", description: "Comma-separated email addresses." },
|
|
6414
|
+
is_html: { type: "boolean", title: "HTML body", description: "Render the body as HTML." }
|
|
6415
|
+
}
|
|
6416
|
+
}
|
|
6417
|
+
};
|
|
6418
|
+
var GMAIL_SEND_OUTPUT_SCHEMA = [
|
|
6419
|
+
{ path: "messageId", displayName: "Message ID", type: "string", description: "Gmail id of the sent message" },
|
|
6420
|
+
{ path: "threadId", displayName: "Thread ID", type: "string" },
|
|
6421
|
+
{ path: "sentAt", displayName: "Sent At", type: "string", description: "ISO timestamp when sent" }
|
|
6422
|
+
];
|
|
6423
|
+
|
|
6424
|
+
// src/core/lib/actionRegistry/actions/gmail/emailSend.ts
|
|
6425
|
+
registerAction({
|
|
6426
|
+
type: "qi/gmail.email.send",
|
|
6427
|
+
can: "gmail.email/send",
|
|
6428
|
+
sideEffect: true,
|
|
6429
|
+
defaultRequiresConfirmation: true,
|
|
6430
|
+
requiredCapability: "flow/block/execute",
|
|
6431
|
+
// Can be wired to another block's event (e.g. form submitted → send email).
|
|
6432
|
+
eligibleForEventTrigger: true,
|
|
6433
|
+
outputSchema: GMAIL_SEND_OUTPUT_SCHEMA,
|
|
6434
|
+
events: [
|
|
6435
|
+
{
|
|
6436
|
+
name: GMAIL_SENT_EVENT,
|
|
6437
|
+
displayName: "Email sent",
|
|
6438
|
+
description: "Fired after the email is sent from the author\u2019s Gmail.",
|
|
6439
|
+
payloadSchema: [
|
|
6440
|
+
{ path: "messageId", displayName: "Message ID", type: "string" },
|
|
6441
|
+
{ path: "recipient_email", displayName: "To", type: "string" }
|
|
6442
|
+
],
|
|
6443
|
+
pendingDisplayFields: ["messageId"]
|
|
6444
|
+
}
|
|
6445
|
+
],
|
|
6446
|
+
run: async (inputs, ctx) => {
|
|
6447
|
+
const parsed = parseDelegatedToolInputs(inputs);
|
|
6448
|
+
const values = fieldValues(parsed);
|
|
6449
|
+
const data = await executeDelegatedTool(ctx, {
|
|
6450
|
+
connection: parsed.connection,
|
|
6451
|
+
schema: GMAIL_SEND_SCHEMA,
|
|
6452
|
+
toolSlug: GMAIL_SEND_SLUG,
|
|
6453
|
+
values,
|
|
6454
|
+
toolkitLabel: "Gmail"
|
|
6455
|
+
});
|
|
6456
|
+
const envelope = data.response_data ?? data;
|
|
6457
|
+
const messageId = String(envelope.id ?? envelope.messageId ?? "");
|
|
6458
|
+
const threadId = String(envelope.threadId ?? "");
|
|
6459
|
+
return {
|
|
6460
|
+
output: {
|
|
6461
|
+
messageId,
|
|
6462
|
+
threadId,
|
|
6463
|
+
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6464
|
+
},
|
|
6465
|
+
events: messageId ? [{ name: GMAIL_SENT_EVENT, payload: { messageId, recipient_email: values.recipient_email ?? "" } }] : void 0
|
|
6466
|
+
};
|
|
6467
|
+
}
|
|
6468
|
+
});
|
|
6469
|
+
|
|
6470
|
+
// src/core/lib/actionRegistry/actions/outlook/emailSend.types.ts
|
|
6471
|
+
var OUTLOOK_SEND_SLUG = "OUTLOOK_OUTLOOK_SEND_EMAIL";
|
|
6472
|
+
var OUTLOOK_SENT_EVENT = "email.sent";
|
|
6473
|
+
var OUTLOOK_SEND_SCHEMA = {
|
|
6474
|
+
slug: OUTLOOK_SEND_SLUG,
|
|
6475
|
+
name: "Send Email",
|
|
6476
|
+
description: "Send an email from the template author's Outlook account.",
|
|
6477
|
+
parameters: {
|
|
6478
|
+
type: "object",
|
|
6479
|
+
required: ["subject", "body", "to_email"],
|
|
6480
|
+
properties: {
|
|
6481
|
+
to_email: { type: "string", title: "To", description: "Recipient's email address." },
|
|
6482
|
+
to_name: { type: "string", title: "To name", description: "Optional display name for the recipient." },
|
|
6483
|
+
subject: { type: "string", title: "Subject" },
|
|
6484
|
+
body: { type: "string", title: "Body", description: 'Email body. Plain text unless "HTML body" is set.' },
|
|
6485
|
+
cc_emails: { type: "array", title: "Cc", description: "Comma-separated email addresses." },
|
|
6486
|
+
bcc_emails: { type: "array", title: "Bcc", description: "Comma-separated email addresses." },
|
|
6487
|
+
is_html: { type: "boolean", title: "HTML body", description: "Render the body as HTML." }
|
|
6488
|
+
}
|
|
6489
|
+
}
|
|
6490
|
+
};
|
|
6491
|
+
var OUTLOOK_SEND_OUTPUT_SCHEMA = [
|
|
6492
|
+
{ path: "messageId", displayName: "Message ID", type: "string" },
|
|
6493
|
+
{ path: "sentAt", displayName: "Sent At", type: "string", description: "ISO timestamp when sent" }
|
|
6494
|
+
];
|
|
6495
|
+
|
|
6496
|
+
// src/core/lib/actionRegistry/actions/outlook/emailSend.ts
|
|
6497
|
+
registerAction({
|
|
6498
|
+
type: "qi/outlook.email.send",
|
|
6499
|
+
can: "outlook.email/send",
|
|
6500
|
+
sideEffect: true,
|
|
6501
|
+
defaultRequiresConfirmation: true,
|
|
6502
|
+
requiredCapability: "flow/block/execute",
|
|
6503
|
+
// Can be wired to another block's event (e.g. form submitted → send email).
|
|
6504
|
+
eligibleForEventTrigger: true,
|
|
6505
|
+
outputSchema: OUTLOOK_SEND_OUTPUT_SCHEMA,
|
|
6506
|
+
events: [
|
|
6507
|
+
{
|
|
6508
|
+
name: OUTLOOK_SENT_EVENT,
|
|
6509
|
+
displayName: "Email sent",
|
|
6510
|
+
description: "Fired after the email is sent from the author\u2019s Outlook.",
|
|
6511
|
+
payloadSchema: [
|
|
6512
|
+
{ path: "messageId", displayName: "Message ID", type: "string" },
|
|
6513
|
+
{ path: "to_email", displayName: "To", type: "string" }
|
|
6514
|
+
],
|
|
6515
|
+
pendingDisplayFields: ["messageId"]
|
|
6516
|
+
}
|
|
6517
|
+
],
|
|
6518
|
+
run: async (inputs, ctx) => {
|
|
6519
|
+
const parsed = parseDelegatedToolInputs(inputs);
|
|
6520
|
+
const values = fieldValues(parsed);
|
|
6521
|
+
const data = await executeDelegatedTool(ctx, {
|
|
6522
|
+
connection: parsed.connection,
|
|
6523
|
+
schema: OUTLOOK_SEND_SCHEMA,
|
|
6524
|
+
toolSlug: OUTLOOK_SEND_SLUG,
|
|
6525
|
+
values,
|
|
6526
|
+
toolkitLabel: "Outlook"
|
|
6527
|
+
});
|
|
6528
|
+
const envelope = data.response_data ?? data;
|
|
6529
|
+
const messageId = String(envelope.id ?? envelope.messageId ?? "");
|
|
6530
|
+
return {
|
|
6531
|
+
output: {
|
|
6532
|
+
messageId,
|
|
6533
|
+
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6534
|
+
},
|
|
6535
|
+
// Outlook often returns no id, so emit unconditionally.
|
|
6536
|
+
events: [{ name: OUTLOOK_SENT_EVENT, payload: { messageId, to_email: values.to_email ?? "" } }]
|
|
6537
|
+
};
|
|
6538
|
+
}
|
|
6539
|
+
});
|
|
6540
|
+
|
|
6541
|
+
// src/core/lib/actionRegistry/actions/slack/messageSend.types.ts
|
|
6542
|
+
var SLACK_SEND_SLUG = "SLACK_CHAT_POST_MESSAGE";
|
|
6543
|
+
var SLACK_SENT_EVENT = "message.sent";
|
|
6544
|
+
var SLACK_SEND_SCHEMA = {
|
|
6545
|
+
slug: SLACK_SEND_SLUG,
|
|
6546
|
+
name: "Post Message",
|
|
6547
|
+
description: "Post a message to a Slack channel from the template author's Slack account.",
|
|
6548
|
+
parameters: {
|
|
6549
|
+
type: "object",
|
|
6550
|
+
required: ["channel"],
|
|
6551
|
+
properties: {
|
|
6552
|
+
channel: { type: "string", title: "Channel", description: "Channel ID or name, e.g. #general or C0123456." },
|
|
6553
|
+
markdown_text: {
|
|
6554
|
+
type: "string",
|
|
6555
|
+
title: "Message",
|
|
6556
|
+
description: "Message text in Slack markdown. Preferred over the deprecated plain text field."
|
|
6557
|
+
},
|
|
6558
|
+
thread_ts: { type: "string", title: "Thread", description: "Optional parent message timestamp to reply within a thread." }
|
|
6559
|
+
}
|
|
6560
|
+
}
|
|
6561
|
+
};
|
|
6562
|
+
var SLACK_SEND_OUTPUT_SCHEMA = [
|
|
6563
|
+
{ path: "messageTs", displayName: "Message ts", type: "string" },
|
|
6564
|
+
{ path: "channel", displayName: "Channel", type: "string" },
|
|
6565
|
+
{ path: "sentAt", displayName: "Sent At", type: "string", description: "ISO timestamp when sent" }
|
|
6566
|
+
];
|
|
6567
|
+
|
|
6568
|
+
// src/core/lib/actionRegistry/actions/slack/messageSend.ts
|
|
6569
|
+
registerAction({
|
|
6570
|
+
type: "qi/slack.message.send",
|
|
6571
|
+
can: "slack.message/send",
|
|
6572
|
+
sideEffect: true,
|
|
6573
|
+
defaultRequiresConfirmation: true,
|
|
6574
|
+
requiredCapability: "flow/block/execute",
|
|
6575
|
+
// Can be wired to another block's event (e.g. form submitted → post message).
|
|
6576
|
+
eligibleForEventTrigger: true,
|
|
6577
|
+
outputSchema: SLACK_SEND_OUTPUT_SCHEMA,
|
|
6578
|
+
events: [
|
|
6579
|
+
{
|
|
6580
|
+
name: SLACK_SENT_EVENT,
|
|
6581
|
+
displayName: "Message posted",
|
|
6582
|
+
description: "Fired after the message is posted to Slack.",
|
|
6583
|
+
payloadSchema: [
|
|
6584
|
+
{ path: "messageTs", displayName: "Message ts", type: "string" },
|
|
6585
|
+
{ path: "channel", displayName: "Channel", type: "string" }
|
|
6586
|
+
],
|
|
6587
|
+
pendingDisplayFields: ["messageTs"]
|
|
6588
|
+
}
|
|
6589
|
+
],
|
|
6590
|
+
run: async (inputs, ctx) => {
|
|
6591
|
+
const parsed = parseDelegatedToolInputs(inputs);
|
|
6592
|
+
const values = fieldValues(parsed);
|
|
6593
|
+
const data = await executeDelegatedTool(ctx, {
|
|
6594
|
+
connection: parsed.connection,
|
|
6595
|
+
schema: SLACK_SEND_SCHEMA,
|
|
6596
|
+
toolSlug: SLACK_SEND_SLUG,
|
|
6597
|
+
values,
|
|
6598
|
+
toolkitLabel: "Slack"
|
|
6599
|
+
});
|
|
6600
|
+
const envelope = data.response_data ?? data;
|
|
6601
|
+
const messageTs = String(envelope.ts ?? "");
|
|
6602
|
+
const channel = String(envelope.channel ?? values.channel ?? "");
|
|
6603
|
+
return {
|
|
6604
|
+
output: {
|
|
6605
|
+
messageTs,
|
|
6606
|
+
channel,
|
|
6607
|
+
sentAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6608
|
+
},
|
|
6609
|
+
events: messageTs ? [{ name: SLACK_SENT_EVENT, payload: { messageTs, channel } }] : void 0
|
|
6610
|
+
};
|
|
6611
|
+
}
|
|
6612
|
+
});
|
|
6613
|
+
|
|
6614
|
+
// src/core/lib/actionRegistry/actions/googlecalendar/eventCreate.types.ts
|
|
6615
|
+
var GOOGLECALENDAR_CREATE_SLUG = "GOOGLECALENDAR_CREATE_EVENT";
|
|
6616
|
+
var GOOGLECALENDAR_CREATED_EVENT = "event.created";
|
|
6617
|
+
var GOOGLECALENDAR_CREATE_SCHEMA = {
|
|
6618
|
+
slug: GOOGLECALENDAR_CREATE_SLUG,
|
|
6619
|
+
name: "Create Event",
|
|
6620
|
+
description: "Create an event on the template author's Google Calendar.",
|
|
6621
|
+
parameters: {
|
|
6622
|
+
type: "object",
|
|
6623
|
+
required: ["start_datetime"],
|
|
6624
|
+
properties: {
|
|
6625
|
+
start_datetime: { type: "string", title: "Start time", description: "ISO 8601, e.g. 2026-05-12T09:00:00." },
|
|
6626
|
+
summary: { type: "string", title: "Title" },
|
|
6627
|
+
description: { type: "string", title: "Description" },
|
|
6628
|
+
location: { type: "string", title: "Location" },
|
|
6629
|
+
timezone: { type: "string", title: "Timezone", description: "IANA name, e.g. Europe/London." },
|
|
6630
|
+
attendees: { type: "array", title: "Attendees", description: "Comma-separated email addresses." },
|
|
6631
|
+
calendar_id: { type: "string", title: "Calendar", description: "Use 'primary' for the author's main calendar." },
|
|
6632
|
+
event_duration_minutes: { type: "number", title: "Duration (minutes)", description: "Defaults to the calendar default if blank." }
|
|
6633
|
+
}
|
|
6634
|
+
}
|
|
6635
|
+
};
|
|
6636
|
+
var GOOGLECALENDAR_CREATE_OUTPUT_SCHEMA = [
|
|
6637
|
+
{ path: "eventId", displayName: "Event ID", type: "string" },
|
|
6638
|
+
{ path: "htmlLink", displayName: "Event link", type: "string" },
|
|
6639
|
+
{ path: "summary", displayName: "Summary", type: "string" },
|
|
6640
|
+
{ path: "startIso", displayName: "Start", type: "string" }
|
|
6641
|
+
];
|
|
6642
|
+
|
|
6643
|
+
// src/core/lib/actionRegistry/actions/googlecalendar/eventCreate.ts
|
|
6644
|
+
registerAction({
|
|
6645
|
+
type: "qi/googlecalendar.event.create",
|
|
6646
|
+
can: "googlecalendar.event/create",
|
|
6647
|
+
sideEffect: true,
|
|
6648
|
+
defaultRequiresConfirmation: true,
|
|
6649
|
+
requiredCapability: "flow/block/execute",
|
|
6650
|
+
eligibleForEventTrigger: true,
|
|
6651
|
+
outputSchema: GOOGLECALENDAR_CREATE_OUTPUT_SCHEMA,
|
|
6652
|
+
events: [
|
|
6653
|
+
{
|
|
6654
|
+
name: GOOGLECALENDAR_CREATED_EVENT,
|
|
6655
|
+
displayName: "Calendar event created",
|
|
6656
|
+
description: "Fired after the event is created on the author\u2019s calendar.",
|
|
6657
|
+
payloadSchema: [
|
|
6658
|
+
{ path: "eventId", displayName: "Event ID", type: "string" },
|
|
6659
|
+
{ path: "htmlLink", displayName: "Event link", type: "string" },
|
|
6660
|
+
{ path: "summary", displayName: "Summary", type: "string" }
|
|
6661
|
+
],
|
|
6662
|
+
pendingDisplayFields: ["summary", "eventId"]
|
|
6663
|
+
}
|
|
6664
|
+
],
|
|
6665
|
+
run: async (inputs, ctx) => {
|
|
6666
|
+
const parsed = parseDelegatedToolInputs(inputs);
|
|
6667
|
+
const values = fieldValues(parsed);
|
|
6668
|
+
const data = await executeDelegatedTool(ctx, {
|
|
6669
|
+
connection: parsed.connection,
|
|
6670
|
+
schema: GOOGLECALENDAR_CREATE_SCHEMA,
|
|
6671
|
+
toolSlug: GOOGLECALENDAR_CREATE_SLUG,
|
|
6672
|
+
values,
|
|
6673
|
+
toolkitLabel: "Google Calendar"
|
|
6674
|
+
});
|
|
6675
|
+
const envelope = data.response_data ?? data;
|
|
6676
|
+
const eventId = String(envelope.id ?? "");
|
|
6677
|
+
const htmlLink = String(envelope.htmlLink ?? "");
|
|
6678
|
+
const summary = String(envelope.summary ?? values.summary ?? "");
|
|
6679
|
+
const start = envelope.start;
|
|
6680
|
+
const startIso = String(start?.dateTime ?? start?.date ?? values.start_datetime ?? "");
|
|
6681
|
+
return {
|
|
6682
|
+
output: { eventId, htmlLink, summary, startIso },
|
|
6683
|
+
events: eventId ? [{ name: GOOGLECALENDAR_CREATED_EVENT, payload: { eventId, htmlLink, summary } }] : void 0
|
|
6684
|
+
};
|
|
6685
|
+
}
|
|
6686
|
+
});
|
|
6687
|
+
|
|
6295
6688
|
// src/core/lib/actionRegistry/actions/calendar/eventCreate.types.ts
|
|
6296
6689
|
var EMPTY = {
|
|
6297
6690
|
connection: null,
|
|
@@ -10725,6 +11118,9 @@ function compileBaseUcanFlow(plan, registry) {
|
|
|
10725
11118
|
if (cap.condition) {
|
|
10726
11119
|
props.conditions = compileCondition(cap.condition, blockIndex);
|
|
10727
11120
|
}
|
|
11121
|
+
if (cap.trigger) {
|
|
11122
|
+
props.trigger = compileTrigger(cap.trigger, blockIndex);
|
|
11123
|
+
}
|
|
10728
11124
|
props.triggerMode = cap.trigger?.type || "manual";
|
|
10729
11125
|
blocks.push({
|
|
10730
11126
|
id: blockId,
|
|
@@ -10795,6 +11191,18 @@ function compileCondition(condition, blockIndex) {
|
|
|
10795
11191
|
};
|
|
10796
11192
|
return JSON.stringify(conditionConfig);
|
|
10797
11193
|
}
|
|
11194
|
+
function compileTrigger(trigger, blockIndex) {
|
|
11195
|
+
if (trigger.type === "block.event" && trigger.sourceBlockId) {
|
|
11196
|
+
return JSON.stringify({ ...trigger, sourceBlockId: blockIndex[trigger.sourceBlockId.trim()] });
|
|
11197
|
+
}
|
|
11198
|
+
if (trigger.type === "block.event.all" && trigger.sources) {
|
|
11199
|
+
return JSON.stringify({
|
|
11200
|
+
...trigger,
|
|
11201
|
+
sources: trigger.sources.map((src) => ({ ...src, sourceBlockId: blockIndex[src.sourceBlockId.trim()] }))
|
|
11202
|
+
});
|
|
11203
|
+
}
|
|
11204
|
+
return JSON.stringify(trigger);
|
|
11205
|
+
}
|
|
10798
11206
|
function collectOutputRefs(value) {
|
|
10799
11207
|
const refs = [];
|
|
10800
11208
|
walk(value);
|
|
@@ -11150,9 +11558,13 @@ function mergeCompiledFlows(existing, incoming, strategy) {
|
|
|
11150
11558
|
|
|
11151
11559
|
// src/core/lib/flowCompiler/decompile.ts
|
|
11152
11560
|
function decompileToBaseUcanFlow(compiled) {
|
|
11561
|
+
const nodeIdByBlockId = {};
|
|
11562
|
+
for (const [nodeId, blockId] of Object.entries(compiled.blockIndex)) {
|
|
11563
|
+
nodeIdByBlockId[blockId] = nodeId;
|
|
11564
|
+
}
|
|
11153
11565
|
const capabilities = compiled.order.map((nodeId) => {
|
|
11154
11566
|
const node = compiled.nodes[nodeId];
|
|
11155
|
-
return nodeToCapability(node);
|
|
11567
|
+
return nodeToCapability(node, nodeIdByBlockId);
|
|
11156
11568
|
});
|
|
11157
11569
|
return {
|
|
11158
11570
|
kind: "qi.flow.base-ucan",
|
|
@@ -11167,7 +11579,7 @@ function decompileToBaseUcanFlow(compiled) {
|
|
|
11167
11579
|
capabilities
|
|
11168
11580
|
};
|
|
11169
11581
|
}
|
|
11170
|
-
function nodeToCapability(node) {
|
|
11582
|
+
function nodeToCapability(node, nodeIdByBlockId) {
|
|
11171
11583
|
const cap = {
|
|
11172
11584
|
id: node.id,
|
|
11173
11585
|
can: node.can,
|
|
@@ -11202,7 +11614,7 @@ function nodeToCapability(node) {
|
|
|
11202
11614
|
try {
|
|
11203
11615
|
const trigger = JSON.parse(node.props.trigger);
|
|
11204
11616
|
if (trigger && typeof trigger === "object" && typeof trigger.type === "string") {
|
|
11205
|
-
cap.trigger = trigger;
|
|
11617
|
+
cap.trigger = triggerToNodeIds(trigger, nodeIdByBlockId);
|
|
11206
11618
|
}
|
|
11207
11619
|
} catch {
|
|
11208
11620
|
}
|
|
@@ -11218,6 +11630,18 @@ function nodeToCapability(node) {
|
|
|
11218
11630
|
}
|
|
11219
11631
|
return cap;
|
|
11220
11632
|
}
|
|
11633
|
+
function triggerToNodeIds(trigger, nodeIdByBlockId) {
|
|
11634
|
+
if (trigger.type === "block.event" && trigger.sourceBlockId) {
|
|
11635
|
+
return { ...trigger, sourceBlockId: nodeIdByBlockId[trigger.sourceBlockId] ?? trigger.sourceBlockId };
|
|
11636
|
+
}
|
|
11637
|
+
if (trigger.type === "block.event.all" && trigger.sources) {
|
|
11638
|
+
return {
|
|
11639
|
+
...trigger,
|
|
11640
|
+
sources: trigger.sources.map((src) => ({ ...src, sourceBlockId: nodeIdByBlockId[src.sourceBlockId] ?? src.sourceBlockId }))
|
|
11641
|
+
};
|
|
11642
|
+
}
|
|
11643
|
+
return trigger;
|
|
11644
|
+
}
|
|
11221
11645
|
|
|
11222
11646
|
// src/core/lib/flowCompiler/setup.ts
|
|
11223
11647
|
import * as Y7 from "yjs";
|
|
@@ -12851,6 +13275,14 @@ export {
|
|
|
12851
13275
|
didToMatrixUserId,
|
|
12852
13276
|
findOrCreateDMRoom,
|
|
12853
13277
|
sendDirectMessage,
|
|
13278
|
+
parseDelegatedToolInputs,
|
|
13279
|
+
serializeDelegatedToolInputs,
|
|
13280
|
+
fieldValues,
|
|
13281
|
+
missingRequired,
|
|
13282
|
+
GMAIL_SEND_SCHEMA,
|
|
13283
|
+
OUTLOOK_SEND_SCHEMA,
|
|
13284
|
+
SLACK_SEND_SCHEMA,
|
|
13285
|
+
GOOGLECALENDAR_CREATE_SCHEMA,
|
|
12854
13286
|
parseCalendarEventCreateInputs,
|
|
12855
13287
|
serializeCalendarEventCreateInputs,
|
|
12856
13288
|
parseAttendeesField,
|
|
@@ -12942,4 +13374,4 @@ export {
|
|
|
12942
13374
|
executeQueuedFlowAgentCoreCommands,
|
|
12943
13375
|
FlowAgentService
|
|
12944
13376
|
};
|
|
12945
|
-
//# sourceMappingURL=chunk-
|
|
13377
|
+
//# sourceMappingURL=chunk-YWZJYSOP.js.map
|