@bike4mind/cli 0.2.30-subagent-delegation.19188 → 0.2.31-feat-python-playground.19300

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.
@@ -171,6 +171,20 @@ var ChatModels;
171
171
  })(ChatModels || (ChatModels = {}));
172
172
  var CHAT_MODELS = Object.values(ChatModels);
173
173
  var supportedChatModels = z.nativeEnum(ChatModels);
174
+ var REASONING_SUPPORTED_MODELS = /* @__PURE__ */ new Set([
175
+ ChatModels.O1,
176
+ ChatModels.O3_MINI,
177
+ ChatModels.O3,
178
+ ChatModels.O4_MINI,
179
+ ChatModels.GPT5,
180
+ ChatModels.GPT5_MINI,
181
+ ChatModels.GPT5_NANO,
182
+ ChatModels.GPT5_CHAT_LATEST,
183
+ ChatModels.GPT5_1,
184
+ ChatModels.GPT5_1_CHAT_LATEST,
185
+ ChatModels.GPT5_2,
186
+ ChatModels.GPT5_2_CHAT_LATEST
187
+ ]);
174
188
  var SpeechToTextModels;
175
189
  (function(SpeechToTextModels2) {
176
190
  SpeechToTextModels2["WHISPER_1"] = "whisper-1";
@@ -310,9 +324,7 @@ var b4mLLMTools = z5.enum([
310
324
  "iss_tracker",
311
325
  "planet_visibility",
312
326
  // Knowledge base search
313
- "search_knowledge_base",
314
- // Agent delegation
315
- "delegate_to_agent"
327
+ "search_knowledge_base"
316
328
  ]);
317
329
  var B4MLLMToolsList = b4mLLMTools.options.map((tool) => tool);
318
330
  var RechartsChartTypeSchema = z5.enum([
@@ -461,6 +473,15 @@ var LatticeArtifactSchema = ArtifactSchema.extend({
461
473
  lastComputedAt: z6.date().optional()
462
474
  })
463
475
  });
476
+ var PythonArtifactSchema = ArtifactSchema.extend({
477
+ type: z6.literal("python"),
478
+ metadata: ArtifactMetadataSchema.extend({
479
+ packages: z6.array(z6.string()).default([]),
480
+ hasOutput: z6.boolean().default(false),
481
+ executionState: z6.enum(["idle", "running", "completed", "error"]).optional(),
482
+ lastExecutionTime: z6.number().optional()
483
+ })
484
+ });
464
485
  var MermaidChartMetadataSchema = z6.object({
465
486
  chartType: z6.enum([
466
487
  "flowchart",
@@ -495,7 +516,8 @@ var ClaudeArtifactMimeTypes = {
495
516
  RECHARTS: "application/vnd.ant.recharts",
496
517
  CODE: "application/vnd.ant.code",
497
518
  MARKDOWN: "text/markdown",
498
- LATTICE: "application/vnd.b4m.lattice"
519
+ LATTICE: "application/vnd.b4m.lattice",
520
+ PYTHON: "application/vnd.ant.python"
499
521
  };
500
522
 
501
523
  // ../../b4m-core/packages/common/dist/src/types/entities/AppFileTypes.js
@@ -1063,6 +1085,25 @@ var WebhookDeliveryStatus;
1063
1085
  WebhookDeliveryStatus2["Pending"] = "pending";
1064
1086
  })(WebhookDeliveryStatus || (WebhookDeliveryStatus = {}));
1065
1087
 
1088
+ // ../../b4m-core/packages/common/dist/src/types/entities/JiraWebhookConfigTypes.js
1089
+ var COMMON_JIRA_WEBHOOK_EVENTS = [
1090
+ "jira:issue_created",
1091
+ "jira:issue_updated",
1092
+ "comment_created",
1093
+ "comment_updated",
1094
+ "sprint_started",
1095
+ "sprint_closed"
1096
+ ];
1097
+
1098
+ // ../../b4m-core/packages/common/dist/src/types/entities/JiraWebhookDeliveryTypes.js
1099
+ var JiraWebhookDeliveryStatus;
1100
+ (function(JiraWebhookDeliveryStatus2) {
1101
+ JiraWebhookDeliveryStatus2["Success"] = "success";
1102
+ JiraWebhookDeliveryStatus2["Failed"] = "failed";
1103
+ JiraWebhookDeliveryStatus2["Filtered"] = "filtered";
1104
+ JiraWebhookDeliveryStatus2["Pending"] = "pending";
1105
+ })(JiraWebhookDeliveryStatus || (JiraWebhookDeliveryStatus = {}));
1106
+
1066
1107
  // ../../b4m-core/packages/common/dist/src/types/common.js
1067
1108
  var SupportedFabFileMimeTypes;
1068
1109
  (function(SupportedFabFileMimeTypes2) {
@@ -7258,6 +7299,632 @@ var AgileApi = class {
7258
7299
  }
7259
7300
  };
7260
7301
 
7302
+ // ../../b4m-core/packages/common/dist/src/jira/webhook/format.js
7303
+ function daysUntil(dateString) {
7304
+ const expirationDate = new Date(dateString);
7305
+ const now = /* @__PURE__ */ new Date();
7306
+ const diffMs = expirationDate.getTime() - now.getTime();
7307
+ return Math.ceil(diffMs / (1e3 * 60 * 60 * 24));
7308
+ }
7309
+ function formatWebhook(webhook) {
7310
+ const daysUntilExpiry = daysUntil(webhook.expirationDate);
7311
+ return {
7312
+ id: webhook.id,
7313
+ events: webhook.events,
7314
+ jqlFilter: webhook.jqlFilter,
7315
+ expirationDate: webhook.expirationDate,
7316
+ daysUntilExpiry,
7317
+ isExpiringSoon: daysUntilExpiry < 7
7318
+ };
7319
+ }
7320
+ function formatWebhookList(response) {
7321
+ return {
7322
+ webhooks: response.values.map(formatWebhook),
7323
+ total: response.total,
7324
+ hasMore: !response.isLast
7325
+ };
7326
+ }
7327
+ function extractAdfText(body, maxLength = 500) {
7328
+ if (!body || typeof body !== "object")
7329
+ return "";
7330
+ const doc = body;
7331
+ if (doc.type !== "doc" || !Array.isArray(doc.content))
7332
+ return "";
7333
+ const parts = [];
7334
+ let totalLength = 0;
7335
+ function walk(nodes) {
7336
+ for (const node of nodes) {
7337
+ if (totalLength >= maxLength)
7338
+ return;
7339
+ if (!node || typeof node !== "object")
7340
+ continue;
7341
+ const n = node;
7342
+ if (n.type === "text" && typeof n.text === "string") {
7343
+ const remaining = maxLength - totalLength;
7344
+ const text = n.text.slice(0, remaining);
7345
+ parts.push(text);
7346
+ totalLength += text.length;
7347
+ }
7348
+ if (Array.isArray(n.content)) {
7349
+ walk(n.content);
7350
+ }
7351
+ }
7352
+ }
7353
+ walk(doc.content);
7354
+ const result = parts.join("");
7355
+ if (totalLength >= maxLength)
7356
+ return result + "...";
7357
+ return result;
7358
+ }
7359
+ function escapeSlackMrkdwn(text) {
7360
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\*/g, "\u2217").replace(/_/g, "\uFF3F").replace(/~/g, "\u223C").replace(/`/g, "\u02CB");
7361
+ }
7362
+ var PRIORITY_EMOJI = {
7363
+ Highest: ":red_circle:",
7364
+ High: ":large_orange_circle:",
7365
+ Medium: ":large_yellow_circle:",
7366
+ Low: ":large_green_circle:",
7367
+ Lowest: ":white_circle:"
7368
+ };
7369
+ function getPriorityEmoji(priority) {
7370
+ if (!priority)
7371
+ return "";
7372
+ return PRIORITY_EMOJI[priority] || ":blue_circle:";
7373
+ }
7374
+ function formatIssueEventForSlack(event, siteUrl) {
7375
+ const { issue, webhookEvent, user, changelog } = event;
7376
+ const { fields } = issue;
7377
+ const priorityEmoji = getPriorityEmoji(fields.priority?.name);
7378
+ const issueUrl = `${siteUrl}/browse/${issue.key}`;
7379
+ let action;
7380
+ let emoji;
7381
+ switch (webhookEvent) {
7382
+ case "jira:issue_created":
7383
+ action = "created";
7384
+ emoji = ":new:";
7385
+ break;
7386
+ case "jira:issue_updated":
7387
+ action = "updated";
7388
+ emoji = ":pencil2:";
7389
+ break;
7390
+ case "jira:issue_deleted":
7391
+ action = "deleted";
7392
+ emoji = ":wastebasket:";
7393
+ break;
7394
+ default:
7395
+ action = "changed";
7396
+ emoji = ":bell:";
7397
+ }
7398
+ let changelogText = "";
7399
+ if (changelog?.items && changelog.items.length > 0) {
7400
+ const changes = changelog.items.slice(0, 3).map((item) => {
7401
+ const from = escapeSlackMrkdwn(item.fromString || "None");
7402
+ const to = escapeSlackMrkdwn(item.toString || "None");
7403
+ if (item.field === "status") {
7404
+ return `Status: ${from} \u2192 ${to}`;
7405
+ }
7406
+ if (item.field === "assignee") {
7407
+ return `Assignee: ${escapeSlackMrkdwn(item.fromString || "Unassigned")} \u2192 ${escapeSlackMrkdwn(item.toString || "Unassigned")}`;
7408
+ }
7409
+ if (item.field === "priority") {
7410
+ return `Priority: ${from} \u2192 ${to}`;
7411
+ }
7412
+ return `${escapeSlackMrkdwn(item.field)}: ${from} \u2192 ${to}`;
7413
+ });
7414
+ if (changes.length > 0) {
7415
+ changelogText = "\n" + changes.map((c) => `\u2022 ${c}`).join("\n");
7416
+ if (changelog.items.length > 3) {
7417
+ changelogText += `
7418
+ _...and ${changelog.items.length - 3} more changes_`;
7419
+ }
7420
+ }
7421
+ }
7422
+ const blocks = [
7423
+ {
7424
+ type: "header",
7425
+ text: {
7426
+ type: "plain_text",
7427
+ text: `${emoji} Issue ${action}: ${escapeSlackMrkdwn(issue.key)}`,
7428
+ emoji: true
7429
+ }
7430
+ },
7431
+ {
7432
+ type: "section",
7433
+ text: {
7434
+ type: "mrkdwn",
7435
+ text: `*<${issueUrl}|${escapeSlackMrkdwn(issue.key)}>* ${escapeSlackMrkdwn(fields.summary)}`
7436
+ }
7437
+ },
7438
+ {
7439
+ type: "section",
7440
+ text: {
7441
+ type: "mrkdwn",
7442
+ text: [
7443
+ `${priorityEmoji} *Priority:* ${escapeSlackMrkdwn(fields.priority?.name || "None")}`,
7444
+ `*Status:* ${escapeSlackMrkdwn(fields.status.name)}`,
7445
+ `*Type:* ${escapeSlackMrkdwn(fields.issuetype.name)}`,
7446
+ `*Assignee:* ${escapeSlackMrkdwn(fields.assignee?.displayName || "Unassigned")}`
7447
+ ].join(" | ")
7448
+ }
7449
+ }
7450
+ ];
7451
+ if (changelogText) {
7452
+ blocks.push({
7453
+ type: "section",
7454
+ text: {
7455
+ type: "mrkdwn",
7456
+ text: `*Changes:*${changelogText}`
7457
+ }
7458
+ });
7459
+ }
7460
+ blocks.push({
7461
+ type: "context",
7462
+ elements: [
7463
+ {
7464
+ type: "mrkdwn",
7465
+ text: `${escapeSlackMrkdwn(user?.displayName || "Someone")} \u2022 ${escapeSlackMrkdwn(fields.project.name)} (${escapeSlackMrkdwn(fields.project.key)})`
7466
+ }
7467
+ ]
7468
+ });
7469
+ blocks.push({
7470
+ type: "actions",
7471
+ elements: [
7472
+ {
7473
+ type: "button",
7474
+ text: {
7475
+ type: "plain_text",
7476
+ text: "View in Jira",
7477
+ emoji: true
7478
+ },
7479
+ url: issueUrl,
7480
+ style: "primary"
7481
+ }
7482
+ ]
7483
+ });
7484
+ return {
7485
+ blocks,
7486
+ text: `${emoji} ${escapeSlackMrkdwn(issue.key)} ${action}: ${escapeSlackMrkdwn(fields.summary)}`
7487
+ };
7488
+ }
7489
+ function formatCommentEventForSlack(event, siteUrl) {
7490
+ const { issue, comment, webhookEvent } = event;
7491
+ const issueUrl = `${siteUrl}/browse/${issue.key}`;
7492
+ let action;
7493
+ let emoji;
7494
+ switch (webhookEvent) {
7495
+ case "comment_created":
7496
+ action = "commented on";
7497
+ emoji = ":speech_balloon:";
7498
+ break;
7499
+ case "comment_updated":
7500
+ action = "updated comment on";
7501
+ emoji = ":pencil:";
7502
+ break;
7503
+ case "comment_deleted":
7504
+ action = "deleted comment on";
7505
+ emoji = ":x:";
7506
+ break;
7507
+ default:
7508
+ action = "commented on";
7509
+ emoji = ":speech_balloon:";
7510
+ }
7511
+ const blocks = [
7512
+ {
7513
+ type: "header",
7514
+ text: {
7515
+ type: "plain_text",
7516
+ text: `${emoji} ${escapeSlackMrkdwn(comment.author.displayName)} ${action} ${escapeSlackMrkdwn(issue.key)}`,
7517
+ emoji: true
7518
+ }
7519
+ },
7520
+ {
7521
+ type: "section",
7522
+ text: {
7523
+ type: "mrkdwn",
7524
+ text: `*<${issueUrl}|${escapeSlackMrkdwn(issue.key)}>* ${escapeSlackMrkdwn(issue.fields.summary)}`
7525
+ }
7526
+ }
7527
+ ];
7528
+ if (webhookEvent !== "comment_deleted") {
7529
+ const bodyText = extractAdfText(comment.body);
7530
+ if (bodyText) {
7531
+ blocks.push({
7532
+ type: "section",
7533
+ text: {
7534
+ type: "mrkdwn",
7535
+ text: `> ${escapeSlackMrkdwn(bodyText).replace(/\n/g, "\n> ")}`
7536
+ }
7537
+ });
7538
+ }
7539
+ }
7540
+ blocks.push({
7541
+ type: "context",
7542
+ elements: [
7543
+ {
7544
+ type: "mrkdwn",
7545
+ text: `${escapeSlackMrkdwn(issue.fields.project.name)} \u2022 ${escapeSlackMrkdwn(issue.fields.issuetype.name)}`
7546
+ }
7547
+ ]
7548
+ }, {
7549
+ type: "actions",
7550
+ elements: [
7551
+ {
7552
+ type: "button",
7553
+ text: {
7554
+ type: "plain_text",
7555
+ text: "View in Jira",
7556
+ emoji: true
7557
+ },
7558
+ url: issueUrl,
7559
+ style: "primary"
7560
+ }
7561
+ ]
7562
+ });
7563
+ return {
7564
+ blocks,
7565
+ text: `${emoji} ${escapeSlackMrkdwn(comment.author.displayName)} ${action} ${escapeSlackMrkdwn(issue.key)}: ${escapeSlackMrkdwn(issue.fields.summary)}`
7566
+ };
7567
+ }
7568
+ function formatSprintEventForSlack(event, siteUrl) {
7569
+ const { sprint, webhookEvent, user } = event;
7570
+ let action;
7571
+ let emoji;
7572
+ switch (webhookEvent) {
7573
+ case "sprint_created":
7574
+ action = "created";
7575
+ emoji = ":calendar:";
7576
+ break;
7577
+ case "sprint_started":
7578
+ action = "started";
7579
+ emoji = ":rocket:";
7580
+ break;
7581
+ case "sprint_closed":
7582
+ action = "completed";
7583
+ emoji = ":checkered_flag:";
7584
+ break;
7585
+ case "sprint_updated":
7586
+ action = "updated";
7587
+ emoji = ":pencil2:";
7588
+ break;
7589
+ case "sprint_deleted":
7590
+ action = "deleted";
7591
+ emoji = ":wastebasket:";
7592
+ break;
7593
+ default:
7594
+ action = "changed";
7595
+ emoji = ":bell:";
7596
+ }
7597
+ const sprintUrl = `${siteUrl}/secure/RapidBoard.jspa?rapidView=${sprint.originBoardId}`;
7598
+ const blocks = [
7599
+ {
7600
+ type: "header",
7601
+ text: {
7602
+ type: "plain_text",
7603
+ text: `${emoji} Sprint ${action}: ${escapeSlackMrkdwn(sprint.name)}`,
7604
+ emoji: true
7605
+ }
7606
+ },
7607
+ {
7608
+ type: "section",
7609
+ text: {
7610
+ type: "mrkdwn",
7611
+ text: [
7612
+ `*State:* ${escapeSlackMrkdwn(sprint.state)}`,
7613
+ sprint.startDate ? `*Start:* ${new Date(sprint.startDate).toLocaleDateString()}` : "",
7614
+ sprint.endDate ? `*End:* ${new Date(sprint.endDate).toLocaleDateString()}` : ""
7615
+ ].filter(Boolean).join(" | ")
7616
+ }
7617
+ }
7618
+ ];
7619
+ if (sprint.goal) {
7620
+ blocks.push({
7621
+ type: "section",
7622
+ text: {
7623
+ type: "mrkdwn",
7624
+ text: `*Goal:* ${escapeSlackMrkdwn(sprint.goal)}`
7625
+ }
7626
+ });
7627
+ }
7628
+ blocks.push({
7629
+ type: "context",
7630
+ elements: [
7631
+ {
7632
+ type: "mrkdwn",
7633
+ text: user?.displayName ? escapeSlackMrkdwn(user.displayName) : "System"
7634
+ }
7635
+ ]
7636
+ });
7637
+ blocks.push({
7638
+ type: "actions",
7639
+ elements: [
7640
+ {
7641
+ type: "button",
7642
+ text: {
7643
+ type: "plain_text",
7644
+ text: "View Board",
7645
+ emoji: true
7646
+ },
7647
+ url: sprintUrl,
7648
+ style: "primary"
7649
+ }
7650
+ ]
7651
+ });
7652
+ return {
7653
+ blocks,
7654
+ text: `${emoji} Sprint ${action}: ${escapeSlackMrkdwn(sprint.name)}`
7655
+ };
7656
+ }
7657
+ function formatGenericEventForSlack(eventType, payload, siteUrl) {
7658
+ const issue = payload.issue;
7659
+ const user = payload.user;
7660
+ const issueLink = payload.issueLink;
7661
+ const changelog = payload.changelog;
7662
+ const project = payload.project ?? issue?.fields?.project;
7663
+ const version = payload.version;
7664
+ const worklog = payload.worklog;
7665
+ const board = payload.board;
7666
+ const readableEvent = eventType.replace(/^jira:/, "").replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
7667
+ const blocks = [
7668
+ {
7669
+ type: "header",
7670
+ text: {
7671
+ type: "plain_text",
7672
+ text: `:bell: ${readableEvent}`,
7673
+ emoji: true
7674
+ }
7675
+ }
7676
+ ];
7677
+ const details = [];
7678
+ if (issue?.key) {
7679
+ const issueUrl = `${siteUrl}/browse/${issue.key}`;
7680
+ blocks.push({
7681
+ type: "section",
7682
+ text: {
7683
+ type: "mrkdwn",
7684
+ text: `*<${issueUrl}|${escapeSlackMrkdwn(issue.key)}>* ${escapeSlackMrkdwn(issue.fields?.summary || "")}`
7685
+ }
7686
+ });
7687
+ const meta = [];
7688
+ if (issue.fields?.status?.name)
7689
+ meta.push(`*Status:* ${escapeSlackMrkdwn(issue.fields.status.name)}`);
7690
+ if (issue.fields?.issuetype?.name)
7691
+ meta.push(`*Type:* ${escapeSlackMrkdwn(issue.fields.issuetype.name)}`);
7692
+ if (issue.fields?.priority?.name) {
7693
+ const emoji = getPriorityEmoji(issue.fields.priority.name);
7694
+ meta.push(`${emoji} *Priority:* ${escapeSlackMrkdwn(issue.fields.priority.name)}`);
7695
+ }
7696
+ if (issue.fields?.assignee?.displayName)
7697
+ meta.push(`*Assignee:* ${escapeSlackMrkdwn(issue.fields.assignee.displayName)}`);
7698
+ if (meta.length > 0)
7699
+ details.push(meta.join(" | "));
7700
+ }
7701
+ if (issueLink?.issueLinkType) {
7702
+ const linkType = issueLink.issueLinkType;
7703
+ const linkDesc = escapeSlackMrkdwn(linkType.outwardName || linkType.name || "linked");
7704
+ details.push(`*Link type:* ${linkDesc}`);
7705
+ if (issueLink.sourceIssueId)
7706
+ details.push(`*Source issue ID:* ${issueLink.sourceIssueId}`);
7707
+ if (issueLink.destinationIssueId)
7708
+ details.push(`*Destination issue ID:* ${issueLink.destinationIssueId}`);
7709
+ }
7710
+ if (version?.name) {
7711
+ const versionParts = [`*Version:* ${escapeSlackMrkdwn(version.name)}`];
7712
+ if (version.description)
7713
+ versionParts.push(escapeSlackMrkdwn(version.description));
7714
+ if (version.released !== void 0)
7715
+ versionParts.push(version.released ? ":white_check_mark: Released" : "Unreleased");
7716
+ details.push(versionParts.join(" | "));
7717
+ }
7718
+ if (worklog) {
7719
+ const wlParts = [];
7720
+ if (worklog.author?.displayName)
7721
+ wlParts.push(`*By:* ${escapeSlackMrkdwn(worklog.author.displayName)}`);
7722
+ if (worklog.timeSpent)
7723
+ wlParts.push(`*Time:* ${escapeSlackMrkdwn(worklog.timeSpent)}`);
7724
+ if (wlParts.length > 0)
7725
+ details.push(wlParts.join(" | "));
7726
+ }
7727
+ if (board?.name) {
7728
+ details.push(`*Board:* ${escapeSlackMrkdwn(board.name)}`);
7729
+ }
7730
+ if (changelog?.items && changelog.items.length > 0) {
7731
+ const changes = changelog.items.slice(0, 3).map((item) => `\u2022 ${escapeSlackMrkdwn(item.field || "")}: ${escapeSlackMrkdwn(item.fromString || "None")} \u2192 ${escapeSlackMrkdwn(item.toString || "None")}`);
7732
+ if (changelog.items.length > 3) {
7733
+ changes.push(`_...and ${changelog.items.length - 3} more_`);
7734
+ }
7735
+ details.push(`*Changes:*
7736
+ ${changes.join("\n")}`);
7737
+ }
7738
+ if (details.length > 0) {
7739
+ blocks.push({
7740
+ type: "section",
7741
+ text: {
7742
+ type: "mrkdwn",
7743
+ text: details.join("\n")
7744
+ }
7745
+ });
7746
+ }
7747
+ const contextParts = [];
7748
+ if (user?.displayName)
7749
+ contextParts.push(escapeSlackMrkdwn(user.displayName));
7750
+ if (project?.name)
7751
+ contextParts.push(`${escapeSlackMrkdwn(project.name)}${project.key ? ` (${escapeSlackMrkdwn(project.key)})` : ""}`);
7752
+ if (contextParts.length > 0) {
7753
+ blocks.push({
7754
+ type: "context",
7755
+ elements: [{ type: "mrkdwn", text: contextParts.join(" \u2022 ") }]
7756
+ });
7757
+ }
7758
+ if (issue?.key) {
7759
+ const issueUrl = `${siteUrl}/browse/${issue.key}`;
7760
+ blocks.push({
7761
+ type: "actions",
7762
+ elements: [
7763
+ {
7764
+ type: "button",
7765
+ text: { type: "plain_text", text: "View in Jira", emoji: true },
7766
+ url: issueUrl,
7767
+ style: "primary"
7768
+ }
7769
+ ]
7770
+ });
7771
+ }
7772
+ const summary = issue?.key ? `${escapeSlackMrkdwn(issue.key)}: ${escapeSlackMrkdwn(issue.fields?.summary || readableEvent)}` : readableEvent;
7773
+ return {
7774
+ blocks,
7775
+ text: `:bell: ${summary}`
7776
+ };
7777
+ }
7778
+
7779
+ // ../../b4m-core/packages/common/dist/src/jira/webhook/api.js
7780
+ var WebhookApi = class {
7781
+ config;
7782
+ constructor(config) {
7783
+ this.config = config;
7784
+ }
7785
+ /**
7786
+ * Build URL for webhook API endpoints.
7787
+ *
7788
+ * Note: Webhooks use a different base URL than other Jira APIs.
7789
+ */
7790
+ buildUrl(path, query = {}) {
7791
+ const url = new URL(`${this.config.apiBaseUrl}${path}`);
7792
+ for (const [key, value] of Object.entries(query)) {
7793
+ if (value !== void 0) {
7794
+ url.searchParams.append(key, String(value));
7795
+ }
7796
+ }
7797
+ return url.toString();
7798
+ }
7799
+ /**
7800
+ * Make an authenticated request to the Jira Webhook API.
7801
+ */
7802
+ async request(method, path, options = {}) {
7803
+ const url = this.buildUrl(path, options.query);
7804
+ const headers = {
7805
+ Authorization: this.config.authHeader,
7806
+ Accept: "application/json",
7807
+ "Content-Type": "application/json"
7808
+ };
7809
+ const response = await fetch(url, {
7810
+ method,
7811
+ headers,
7812
+ body: options.body ? JSON.stringify(options.body) : void 0
7813
+ });
7814
+ if (!response.ok) {
7815
+ const errorBody = await response.text();
7816
+ throw new Error(`Jira Webhook API error (${response.status}): ${errorBody}`);
7817
+ }
7818
+ if (response.status === 204) {
7819
+ return {};
7820
+ }
7821
+ const data = await response.json();
7822
+ return data;
7823
+ }
7824
+ // ============================================================================
7825
+ // Webhook CRUD Operations
7826
+ // ============================================================================
7827
+ /**
7828
+ * List all webhooks registered by this OAuth app.
7829
+ *
7830
+ * @param startAt - Pagination start index (default: 0)
7831
+ * @param maxResults - Max results per page (default: 50, max: 100)
7832
+ */
7833
+ async listWebhooks(params = {}) {
7834
+ const { startAt = 0, maxResults = 50 } = params;
7835
+ const response = await this.request("GET", "/webhook", {
7836
+ query: { startAt, maxResults }
7837
+ });
7838
+ return formatWebhookList(response);
7839
+ }
7840
+ /**
7841
+ * Register a new webhook.
7842
+ *
7843
+ * @param url - The URL where Jira will POST webhook events
7844
+ * @param events - Events to subscribe to
7845
+ * @param jqlFilter - Optional JQL filter (only matching issues trigger events)
7846
+ * @returns The created webhook ID
7847
+ */
7848
+ async registerWebhook(params) {
7849
+ const { url, events, jqlFilter } = params;
7850
+ const webhook = {
7851
+ // Jira webhook API requires jqlFilter but has limited operator support.
7852
+ // "IS NOT EMPTY" and empty strings are rejected. Use a universally-true expression.
7853
+ jqlFilter: jqlFilter || "project != null",
7854
+ events
7855
+ };
7856
+ const body = {
7857
+ url,
7858
+ webhooks: [webhook]
7859
+ };
7860
+ const response = await this.request("POST", "/webhook", {
7861
+ body
7862
+ });
7863
+ console.log("[JIRA-WEBHOOK-API] registerWebhook raw response:", JSON.stringify(response, null, 2));
7864
+ if (!response.webhookRegistrationResult || response.webhookRegistrationResult.length === 0) {
7865
+ throw new Error("Failed to register webhook: No registration result returned");
7866
+ }
7867
+ const result = response.webhookRegistrationResult[0];
7868
+ if (result.errors && result.errors.length > 0) {
7869
+ throw new Error(`Failed to register webhook: ${result.errors.join(", ")}`);
7870
+ }
7871
+ if (result.createdWebhookId === void 0 || result.createdWebhookId === null) {
7872
+ throw new Error(`Failed to register webhook: No webhook ID in response. Full result: ${JSON.stringify(result)}`);
7873
+ }
7874
+ return {
7875
+ webhookId: result.createdWebhookId
7876
+ };
7877
+ }
7878
+ /**
7879
+ * Refresh webhook expiration dates.
7880
+ *
7881
+ * Jira webhooks expire after 30 days. Call this to extend expiration.
7882
+ *
7883
+ * @param webhookIds - IDs of webhooks to refresh
7884
+ * @returns New expiration date
7885
+ */
7886
+ async refreshWebhooks(params) {
7887
+ const { webhookIds } = params;
7888
+ const body = {
7889
+ webhookIds
7890
+ };
7891
+ const response = await this.request("PUT", "/webhook/refresh", {
7892
+ body
7893
+ });
7894
+ return {
7895
+ expirationDate: response.expirationDate
7896
+ };
7897
+ }
7898
+ /**
7899
+ * Delete webhooks by ID.
7900
+ *
7901
+ * @param webhookIds - IDs of webhooks to delete
7902
+ */
7903
+ async deleteWebhooks(params) {
7904
+ const { webhookIds } = params;
7905
+ const body = {
7906
+ webhookIds
7907
+ };
7908
+ await this.request("DELETE", "/webhook", {
7909
+ body
7910
+ });
7911
+ }
7912
+ /**
7913
+ * Get a specific webhook by ID.
7914
+ *
7915
+ * Note: Jira API doesn't have a direct "get by ID" endpoint,
7916
+ * so we list and filter.
7917
+ */
7918
+ async getWebhook(params) {
7919
+ const { webhookId } = params;
7920
+ const response = await this.request("GET", "/webhook", {
7921
+ query: { startAt: 0, maxResults: 100 }
7922
+ });
7923
+ const webhook = response.values.find((w) => w.id === webhookId);
7924
+ return webhook || null;
7925
+ }
7926
+ };
7927
+
7261
7928
  // ../../b4m-core/packages/common/dist/src/jira/api.js
7262
7929
  var JIRA_MAX_ATTACHMENT_SIZE = 20 * 1024 * 1024;
7263
7930
  function isValidIssueKey(key) {
@@ -8009,8 +8676,71 @@ var JiraApi = class {
8009
8676
  }
8010
8677
  return this._agileApi;
8011
8678
  }
8679
+ // ============================================================================
8680
+ // Webhook API Access (Webhook Management)
8681
+ // ============================================================================
8682
+ _webhookApi = null;
8683
+ /**
8684
+ * Get the Webhook API client for webhook management operations.
8685
+ * Lazily instantiated on first access.
8686
+ */
8687
+ get webhook() {
8688
+ if (!this._webhookApi) {
8689
+ this._webhookApi = new WebhookApi(this.config);
8690
+ }
8691
+ return this._webhookApi;
8692
+ }
8012
8693
  };
8013
8694
 
8695
+ // ../../b4m-core/packages/common/dist/src/jira/webhook/types.js
8696
+ function isIssueWebhookEvent(payload) {
8697
+ const event = payload.webhookEvent;
8698
+ if (typeof event !== "string" || !event.startsWith("jira:issue_"))
8699
+ return false;
8700
+ const issue = payload.issue;
8701
+ if (!issue || typeof issue.key !== "string")
8702
+ return false;
8703
+ const fields = issue.fields;
8704
+ if (!fields || typeof fields.summary !== "string")
8705
+ return false;
8706
+ const status = fields.status;
8707
+ const issuetype = fields.issuetype;
8708
+ const project = fields.project;
8709
+ if (!status?.name || !issuetype?.name || !project?.key)
8710
+ return false;
8711
+ return true;
8712
+ }
8713
+ function isCommentWebhookEvent(payload) {
8714
+ const event = payload.webhookEvent;
8715
+ if (typeof event !== "string" || !event.startsWith("comment_"))
8716
+ return false;
8717
+ const issue = payload.issue;
8718
+ if (!issue || typeof issue.key !== "string")
8719
+ return false;
8720
+ const comment = payload.comment;
8721
+ if (!comment || typeof comment.id !== "string")
8722
+ return false;
8723
+ const author = comment.author;
8724
+ if (!author || typeof author.displayName !== "string")
8725
+ return false;
8726
+ return true;
8727
+ }
8728
+ function isSprintWebhookEvent(payload) {
8729
+ const event = payload.webhookEvent;
8730
+ if (typeof event !== "string" || !event.startsWith("sprint_"))
8731
+ return false;
8732
+ const sprint = payload.sprint;
8733
+ if (!sprint || typeof sprint.name !== "string")
8734
+ return false;
8735
+ return true;
8736
+ }
8737
+ function extractWebhookEventType(payload) {
8738
+ const event = payload.webhookEvent;
8739
+ if (typeof event !== "string" || event.length === 0)
8740
+ return null;
8741
+ return event;
8742
+ }
8743
+
8014
8744
  // ../../b4m-core/packages/common/dist/src/atlassian/config.js
8015
8745
  function getErrorMessage(error) {
8016
8746
  if (error instanceof Error) {
@@ -8242,6 +8972,16 @@ var MermaidArtifactV2Schema = BaseArtifactSchema.extend({
8242
8972
  description: z28.string().optional()
8243
8973
  })
8244
8974
  });
8975
+ var PythonArtifactV2Schema = BaseArtifactSchema.extend({
8976
+ type: z28.literal("python"),
8977
+ content: z28.string(),
8978
+ metadata: EnhancedArtifactMetadataSchema.extend({
8979
+ packages: z28.array(z28.string()).default([]),
8980
+ hasOutput: z28.boolean().default(false),
8981
+ executionState: z28.enum(["idle", "running", "completed", "error"]).optional(),
8982
+ lastExecutionTime: z28.number().optional()
8983
+ })
8984
+ });
8245
8985
  var ArtifactStatuses;
8246
8986
  (function(ArtifactStatuses2) {
8247
8987
  ArtifactStatuses2["DRAFT"] = "draft";
@@ -8265,6 +9005,9 @@ var validateSvgArtifactV2 = (data) => {
8265
9005
  var validateMermaidArtifactV2 = (data) => {
8266
9006
  return MermaidArtifactV2Schema.parse(data);
8267
9007
  };
9008
+ var validatePythonArtifactV2 = (data) => {
9009
+ return PythonArtifactV2Schema.parse(data);
9010
+ };
8268
9011
 
8269
9012
  // ../../b4m-core/packages/common/dist/src/schemas/questmaster.js
8270
9013
  import { z as z29 } from "zod";
@@ -8597,6 +9340,7 @@ export {
8597
9340
  ChatModels,
8598
9341
  CHAT_MODELS,
8599
9342
  supportedChatModels,
9343
+ REASONING_SUPPORTED_MODELS,
8600
9344
  SpeechToTextModels,
8601
9345
  SPEECH_TO_TEXT_MODELS,
8602
9346
  supportedSpeechToTextModels,
@@ -8633,6 +9377,7 @@ export {
8633
9377
  MermaidArtifactSchema,
8634
9378
  RechartsArtifactSchema,
8635
9379
  LatticeArtifactSchema,
9380
+ PythonArtifactSchema,
8636
9381
  MermaidChartMetadataSchema,
8637
9382
  ChatHistoryItemWithArtifactsSchema,
8638
9383
  ArtifactOperationSchema,
@@ -8703,6 +9448,8 @@ export {
8703
9448
  isPlaceholderValue,
8704
9449
  SecretAuditEvents,
8705
9450
  WebhookDeliveryStatus,
9451
+ COMMON_JIRA_WEBHOOK_EVENTS,
9452
+ JiraWebhookDeliveryStatus,
8706
9453
  SupportedFabFileMimeTypes,
8707
9454
  REASONING_EFFORT_LABELS,
8708
9455
  REASONING_EFFORT_DESCRIPTIONS,
@@ -8940,11 +9687,24 @@ export {
8940
9687
  formatIssueLinkTypes,
8941
9688
  formatIssueLinks,
8942
9689
  AgileApi,
9690
+ formatWebhook,
9691
+ formatWebhookList,
9692
+ extractAdfText,
9693
+ escapeSlackMrkdwn,
9694
+ formatIssueEventForSlack,
9695
+ formatCommentEventForSlack,
9696
+ formatSprintEventForSlack,
9697
+ formatGenericEventForSlack,
9698
+ WebhookApi,
8943
9699
  JIRA_MAX_ATTACHMENT_SIZE,
8944
9700
  isValidIssueKey,
8945
9701
  wikiMarkupToAdf,
8946
9702
  containsWikiTable,
8947
9703
  JiraApi,
9704
+ isIssueWebhookEvent,
9705
+ isCommentWebhookEvent,
9706
+ isSprintWebhookEvent,
9707
+ extractWebhookEventType,
8948
9708
  getErrorMessage,
8949
9709
  getAtlassianConfig,
8950
9710
  MCP_PROVIDER_METADATA,
@@ -8958,12 +9718,14 @@ export {
8958
9718
  HtmlArtifactV2Schema,
8959
9719
  SvgArtifactV2Schema,
8960
9720
  MermaidArtifactV2Schema,
9721
+ PythonArtifactV2Schema,
8961
9722
  ArtifactStatuses,
8962
9723
  validateBaseArtifact,
8963
9724
  validateReactArtifactV2,
8964
9725
  validateHtmlArtifactV2,
8965
9726
  validateSvgArtifactV2,
8966
9727
  validateMermaidArtifactV2,
9728
+ validatePythonArtifactV2,
8967
9729
  QuestStatusSchema,
8968
9730
  QuestSchema,
8969
9731
  QuestResourceSchema,