@bike4mind/cli 0.2.28-slack-native-search.18717 → 0.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,6 +29,9 @@ var ModelBackend;
29
29
  var ImageModels;
30
30
  (function(ImageModels2) {
31
31
  ImageModels2["GPT_IMAGE_1"] = "gpt-image-1";
32
+ ImageModels2["GPT_IMAGE_1_5"] = "gpt-image-1.5";
33
+ ImageModels2["GPT_IMAGE_1_MINI"] = "gpt-image-1-mini";
34
+ ImageModels2["DALL_E_2"] = "dall-e-2";
32
35
  ImageModels2["FLUX_PRO"] = "flux-pro";
33
36
  ImageModels2["FLUX_PRO_1_1"] = "flux-pro-1.1";
34
37
  ImageModels2["FLUX_PRO_ULTRA"] = "flux-pro-1.1-ultra";
@@ -1955,7 +1958,11 @@ var ChatCompletionCreateInputSchema = z16.object({
1955
1958
  content: z16.string()
1956
1959
  })).optional()
1957
1960
  });
1958
- var OPENAI_IMAGE_MODELS = [ImageModels.GPT_IMAGE_1];
1961
+ var OPENAI_IMAGE_MODELS = [
1962
+ ImageModels.GPT_IMAGE_1,
1963
+ ImageModels.GPT_IMAGE_1_5,
1964
+ ImageModels.GPT_IMAGE_1_MINI
1965
+ ];
1959
1966
  var ALL_IMAGE_MODELS = [
1960
1967
  ...OPENAI_IMAGE_MODELS,
1961
1968
  ...BFL_IMAGE_MODELS,
@@ -4436,7 +4443,9 @@ var GenerateImageToolCallSchema = OpenAIImageGenerationInput.extend({
4436
4443
  safety_tolerance: z25.number().optional(),
4437
4444
  prompt_upsampling: z25.boolean().optional(),
4438
4445
  output_format: z25.enum(["jpeg", "png"]).nullable().optional(),
4439
- seed: z25.number().nullable().optional()
4446
+ seed: z25.number().nullable().optional(),
4447
+ editModel: z25.string().optional()
4448
+ // Model to use for image editing operations (separate from generation model)
4440
4449
  }).omit({
4441
4450
  prompt: true
4442
4451
  });
@@ -4534,6 +4543,81 @@ var WEBSITE_URL = "https://www.bike4mind.com";
4534
4543
  var getWebsiteUrl = (path) => {
4535
4544
  return path ? `${WEBSITE_URL}/${path.replace(/^\//, "")}` : WEBSITE_URL;
4536
4545
  };
4546
+ function formatFileSize(bytes) {
4547
+ if (bytes >= 1024 * 1024) {
4548
+ return `${(bytes / 1024 / 1024).toFixed(2)} MB`;
4549
+ }
4550
+ return `${(bytes / 1024).toFixed(1)} KB`;
4551
+ }
4552
+ function getFileTypeEmoji(mimeType) {
4553
+ const type = mimeType.toLowerCase();
4554
+ if (type.startsWith("image/"))
4555
+ return "\u{1F5BC}\uFE0F";
4556
+ if (type === "application/pdf")
4557
+ return "\u{1F4C4}";
4558
+ if (type.includes("word") || type.includes("document"))
4559
+ return "\u{1F4C4}";
4560
+ if (type.includes("spreadsheet") || type.includes("excel") || type === "text/csv")
4561
+ return "\u{1F4CA}";
4562
+ if (type.includes("presentation") || type.includes("powerpoint"))
4563
+ return "\u{1F4FD}\uFE0F";
4564
+ if (type.includes("zip") || type.includes("tar") || type.includes("compressed") || type.includes("archive"))
4565
+ return "\u{1F4E6}";
4566
+ if (type.startsWith("audio/"))
4567
+ return "\u{1F3B5}";
4568
+ if (type.startsWith("video/"))
4569
+ return "\u{1F3AC}";
4570
+ if (type.startsWith("text/") || type.includes("json") || type.includes("xml") || type.includes("javascript"))
4571
+ return "\u{1F4DD}";
4572
+ return "\u{1F4CE}";
4573
+ }
4574
+ var MIME_TYPE_MAP = {
4575
+ // Images
4576
+ ".png": "image/png",
4577
+ ".jpg": "image/jpeg",
4578
+ ".jpeg": "image/jpeg",
4579
+ ".gif": "image/gif",
4580
+ ".webp": "image/webp",
4581
+ ".svg": "image/svg+xml",
4582
+ ".ico": "image/x-icon",
4583
+ // Documents
4584
+ ".pdf": "application/pdf",
4585
+ ".doc": "application/msword",
4586
+ ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
4587
+ ".xls": "application/vnd.ms-excel",
4588
+ ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
4589
+ ".ppt": "application/vnd.ms-powerpoint",
4590
+ ".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
4591
+ ".odt": "application/vnd.oasis.opendocument.text",
4592
+ ".ods": "application/vnd.oasis.opendocument.spreadsheet",
4593
+ // Text
4594
+ ".txt": "text/plain",
4595
+ ".csv": "text/csv",
4596
+ ".json": "application/json",
4597
+ ".xml": "application/xml",
4598
+ ".html": "text/html",
4599
+ ".md": "text/markdown",
4600
+ // Archives
4601
+ ".zip": "application/zip",
4602
+ ".tar": "application/x-tar",
4603
+ ".gz": "application/gzip",
4604
+ ".rar": "application/vnd.rar",
4605
+ ".7z": "application/x-7z-compressed",
4606
+ // Code/Config
4607
+ ".js": "text/javascript",
4608
+ ".ts": "text/typescript",
4609
+ ".py": "text/x-python",
4610
+ ".java": "text/x-java-source",
4611
+ ".yaml": "text/yaml",
4612
+ ".yml": "text/yaml",
4613
+ ".log": "text/plain"
4614
+ };
4615
+ function detectMimeType(filename) {
4616
+ const lower = filename.toLowerCase();
4617
+ const dotIndex = lower.lastIndexOf(".");
4618
+ const ext = dotIndex >= 0 ? lower.slice(dotIndex) : "";
4619
+ return MIME_TYPE_MAP[ext] || "application/octet-stream";
4620
+ }
4537
4621
  async function parallelLimit(items, limit, asyncFn) {
4538
4622
  const results = [];
4539
4623
  let i = 0;
@@ -4947,6 +5031,7 @@ function formatPageRestrictions(restrictionsResponse, pageId) {
4947
5031
  // ../../b4m-core/packages/common/dist/src/confluence/api.js
4948
5032
  var RESTRICTION_OPERATIONS = ["read", "update"];
4949
5033
  var RESTRICTION_SUBJECT_TYPES = ["user", "group"];
5034
+ var CONFLUENCE_MAX_ATTACHMENT_SIZE = 25 * 1024 * 1024;
4950
5035
  var ConfluenceApi = class {
4951
5036
  config;
4952
5037
  constructor(config) {
@@ -4971,7 +5056,6 @@ var ConfluenceApi = class {
4971
5056
  */
4972
5057
  async request(method, path, options = {}) {
4973
5058
  const url = this.buildUrl(path, options.query, options.useV1);
4974
- console.error(`Confluence API Request: ${method} ${url}`);
4975
5059
  const headers = {
4976
5060
  Authorization: this.config.authHeader,
4977
5061
  Accept: "application/json",
@@ -4982,11 +5066,6 @@ var ConfluenceApi = class {
4982
5066
  headers,
4983
5067
  body: options.body ? JSON.stringify(options.body) : void 0
4984
5068
  });
4985
- console.error(`Confluence API Response: ${response.status} ${response.statusText}`);
4986
- const scopes = response.headers.get("X-OAuth-Scopes") || response.headers.get("x-oauth-scopes");
4987
- if (scopes) {
4988
- console.error(`[Debug] Current Token Scopes: ${scopes}`);
4989
- }
4990
5069
  if (!response.ok) {
4991
5070
  const rawBody = await response.text();
4992
5071
  let errorDetail = response.statusText;
@@ -5625,6 +5704,148 @@ var ConfluenceApi = class {
5625
5704
  subject
5626
5705
  };
5627
5706
  }
5707
+ // ============================================================================
5708
+ // Attachment Operations
5709
+ // ============================================================================
5710
+ /**
5711
+ * List all attachments for a page
5712
+ * Uses v2 API which works with granular OAuth scopes (read:attachment:confluence)
5713
+ */
5714
+ async listAttachments(params) {
5715
+ const { pageId, limit = 50 } = params;
5716
+ if (!pageId) {
5717
+ throw new Error("pageId is required to list attachments.");
5718
+ }
5719
+ const result = await this.get(`/pages/${pageId}/attachments`, {
5720
+ limit: Math.min(Math.max(limit, 1), 100)
5721
+ });
5722
+ const attachments = result?.results || [];
5723
+ return attachments.map((att) => ({
5724
+ id: att.id,
5725
+ title: att.title,
5726
+ mediaType: att.mediaType || att.mediaTypeDescription || "application/octet-stream",
5727
+ fileSize: att.fileSize || 0,
5728
+ webuiLink: att.webuiLink || att._links?.webui ? this.buildWebUrl(att.webuiLink || att._links?.webui) : void 0,
5729
+ downloadLink: att.downloadLink || att._links?.download ? this.buildWebUrl(att.downloadLink || att._links?.download) : void 0,
5730
+ comment: att.comment,
5731
+ author: att.version?.authorId || att.history?.createdBy?.displayName,
5732
+ createdAt: att.version?.createdAt || att.history?.createdDate,
5733
+ version: att.version
5734
+ }));
5735
+ }
5736
+ /**
5737
+ * Upload an attachment to a page.
5738
+ * Confluence requires multipart/form-data with X-Atlassian-Token: no-check header.
5739
+ * Uses v1 API which properly supports OAuth attachment uploads.
5740
+ *
5741
+ * @param params.pageId - The page ID
5742
+ * @param params.filename - Name for the uploaded file
5743
+ * @param params.content - Base64-encoded file content
5744
+ * @param params.mimeType - MIME type (auto-detected if omitted)
5745
+ * @param params.comment - Optional comment describing the attachment
5746
+ */
5747
+ async uploadAttachment(params) {
5748
+ const { pageId, filename, content, mimeType, comment } = params;
5749
+ if (!pageId) {
5750
+ throw new Error("pageId is required to upload an attachment.");
5751
+ }
5752
+ const binaryContent = Buffer.from(content, "base64");
5753
+ if (binaryContent.length > CONFLUENCE_MAX_ATTACHMENT_SIZE) {
5754
+ throw new Error(`File size (${Math.round(binaryContent.length / 1024 / 1024)}MB) exceeds maximum allowed size (${CONFLUENCE_MAX_ATTACHMENT_SIZE / 1024 / 1024}MB)`);
5755
+ }
5756
+ const detectedMimeType = mimeType || detectMimeType(filename);
5757
+ const formData = new FormData();
5758
+ const blob = new Blob([binaryContent], { type: detectedMimeType });
5759
+ formData.append("file", blob, filename);
5760
+ if (comment) {
5761
+ formData.append("comment", comment);
5762
+ }
5763
+ const url = `${this.config.apiBaseUrlV1}/content/${pageId}/child/attachment`;
5764
+ const response = await fetch(url, {
5765
+ method: "POST",
5766
+ headers: {
5767
+ Authorization: this.config.authHeader,
5768
+ Accept: "application/json",
5769
+ "X-Atlassian-Token": "no-check"
5770
+ // Required for attachment uploads
5771
+ },
5772
+ body: formData
5773
+ });
5774
+ if (!response.ok) {
5775
+ const errorBody = await response.text();
5776
+ if (response.status === 413) {
5777
+ throw new Error(`File too large: The attachment exceeds Confluence's maximum file size limit.`);
5778
+ }
5779
+ throw new Error(`Confluence attachment upload error (${response.status}): ${errorBody}`);
5780
+ }
5781
+ const result = await response.json();
5782
+ const attachment = "results" in result && result.results ? result.results[0] : result;
5783
+ if (!attachment) {
5784
+ throw new Error("Unexpected response: No attachment returned after upload");
5785
+ }
5786
+ const ext = attachment.extensions;
5787
+ return {
5788
+ id: attachment.id,
5789
+ title: attachment.title,
5790
+ mediaType: attachment.mediaType || ext?.mediaType,
5791
+ fileSize: attachment.fileSize ?? ext?.fileSize,
5792
+ webuiLink: attachment._links?.webui ? this.buildWebUrl(attachment._links.webui) : void 0,
5793
+ downloadLink: attachment._links?.download ? this.buildWebUrl(attachment._links.download) : void 0,
5794
+ comment: attachment.comment || ext?.comment,
5795
+ version: attachment.version
5796
+ };
5797
+ }
5798
+ /**
5799
+ * Download an attachment by ID.
5800
+ * Returns the file content as base64-encoded string.
5801
+ * Uses v2 API for metadata and v1 API for actual download (OAuth-compatible).
5802
+ */
5803
+ async downloadAttachment(params) {
5804
+ const { attachmentId } = params;
5805
+ if (!attachmentId) {
5806
+ throw new Error("attachmentId is required to download an attachment.");
5807
+ }
5808
+ const metadata = await this.get(`/attachments/${attachmentId}`);
5809
+ const downloadPath = metadata.downloadLink || metadata._links?.download;
5810
+ if (!downloadPath) {
5811
+ throw new Error(`Attachment ${attachmentId} has no download URL`);
5812
+ }
5813
+ const pageIdMatch = downloadPath.match(/\/download\/attachments\/(\d+)\//);
5814
+ if (!pageIdMatch) {
5815
+ throw new Error(`Unable to extract page ID from download path: ${downloadPath}`);
5816
+ }
5817
+ const pageId = pageIdMatch[1];
5818
+ const downloadUrl = `${this.config.apiBaseUrlV1}/content/${pageId}/child/attachment/${attachmentId}/download`;
5819
+ const response = await fetch(downloadUrl, {
5820
+ method: "GET",
5821
+ headers: {
5822
+ Authorization: this.config.authHeader
5823
+ },
5824
+ redirect: "follow"
5825
+ });
5826
+ if (!response.ok) {
5827
+ throw new Error(`Failed to download attachment (${response.status}): ${response.statusText}`);
5828
+ }
5829
+ const arrayBuffer = await response.arrayBuffer();
5830
+ const contentBase64 = Buffer.from(arrayBuffer).toString("base64");
5831
+ return {
5832
+ filename: metadata.title,
5833
+ mimeType: metadata.mediaType || "application/octet-stream",
5834
+ size: metadata.fileSize || arrayBuffer.byteLength,
5835
+ content: contentBase64
5836
+ };
5837
+ }
5838
+ /**
5839
+ * Delete an attachment by ID.
5840
+ * Uses v2 API which works with granular OAuth scopes (write:attachment:confluence)
5841
+ */
5842
+ async deleteAttachment(params) {
5843
+ const { attachmentId } = params;
5844
+ if (!attachmentId) {
5845
+ throw new Error("attachmentId is required to delete an attachment.");
5846
+ }
5847
+ await this.request("DELETE", `/attachments/${attachmentId}`);
5848
+ }
5628
5849
  };
5629
5850
 
5630
5851
  // ../../b4m-core/packages/common/dist/src/jira/agile/format.js
@@ -6270,6 +6491,7 @@ var AgileApi = class {
6270
6491
  };
6271
6492
 
6272
6493
  // ../../b4m-core/packages/common/dist/src/jira/api.js
6494
+ var JIRA_MAX_ATTACHMENT_SIZE = 20 * 1024 * 1024;
6273
6495
  function isValidIssueKey(key) {
6274
6496
  return /^[A-Z][A-Z0-9]*-\d+$/.test(key);
6275
6497
  }
@@ -6881,6 +7103,111 @@ var JiraApi = class {
6881
7103
  return null;
6882
7104
  }
6883
7105
  // ============================================================================
7106
+ // Attachment Operations
7107
+ // ============================================================================
7108
+ /**
7109
+ * List all attachments for an issue
7110
+ */
7111
+ async listAttachments(params) {
7112
+ const { issueKey } = params;
7113
+ if (!isValidIssueKey(issueKey)) {
7114
+ throw new Error(`Invalid issue key format: ${issueKey}. Expected format: PROJECT-123`);
7115
+ }
7116
+ const issue = await this.request("GET", `/issue/${issueKey}`, {
7117
+ query: { fields: "attachment" }
7118
+ });
7119
+ const attachments = issue.fields?.attachment || [];
7120
+ return attachments.map((att) => ({
7121
+ id: att.id,
7122
+ self: att.self,
7123
+ filename: att.filename,
7124
+ author: att.author,
7125
+ created: att.created,
7126
+ size: att.size,
7127
+ mimeType: att.mimeType,
7128
+ content: att.content,
7129
+ thumbnail: att.thumbnail
7130
+ }));
7131
+ }
7132
+ /**
7133
+ * Upload an attachment to an issue.
7134
+ * Jira requires multipart/form-data with X-Atlassian-Token: no-check header.
7135
+ *
7136
+ * @param params.issueKey - The issue key (e.g., PROJ-123)
7137
+ * @param params.filename - Name for the uploaded file
7138
+ * @param params.content - Base64-encoded file content
7139
+ * @param params.mimeType - MIME type (auto-detected if omitted)
7140
+ */
7141
+ async uploadAttachment(params) {
7142
+ const { issueKey, filename, content, mimeType } = params;
7143
+ if (!isValidIssueKey(issueKey)) {
7144
+ throw new Error(`Invalid issue key format: ${issueKey}. Expected format: PROJECT-123`);
7145
+ }
7146
+ const binaryContent = Buffer.from(content, "base64");
7147
+ if (binaryContent.length > JIRA_MAX_ATTACHMENT_SIZE) {
7148
+ throw new Error(`File size (${Math.round(binaryContent.length / 1024 / 1024)}MB) exceeds maximum allowed size (${JIRA_MAX_ATTACHMENT_SIZE / 1024 / 1024}MB)`);
7149
+ }
7150
+ const detectedMimeType = mimeType || detectMimeType(filename);
7151
+ const formData = new FormData();
7152
+ const blob = new Blob([binaryContent], { type: detectedMimeType });
7153
+ formData.append("file", blob, filename);
7154
+ const url = `${this.config.apiBaseUrl}/issue/${issueKey}/attachments`;
7155
+ const response = await fetch(url, {
7156
+ method: "POST",
7157
+ headers: {
7158
+ Authorization: this.config.authHeader,
7159
+ Accept: "application/json",
7160
+ "X-Atlassian-Token": "no-check"
7161
+ // Required for attachment uploads
7162
+ },
7163
+ body: formData
7164
+ });
7165
+ if (!response.ok) {
7166
+ const errorBody = await response.text();
7167
+ if (response.status === 413) {
7168
+ throw new Error(`File too large: The attachment exceeds Jira's maximum file size limit.`);
7169
+ }
7170
+ throw new Error(`Jira attachment upload error (${response.status}): ${errorBody}`);
7171
+ }
7172
+ const result = await response.json();
7173
+ return result;
7174
+ }
7175
+ /**
7176
+ * Download an attachment by ID.
7177
+ * Returns the file content as base64-encoded string.
7178
+ */
7179
+ async downloadAttachment(params) {
7180
+ const { attachmentId } = params;
7181
+ const metadata = await this.request("GET", `/attachment/${attachmentId}`);
7182
+ if (!metadata.content) {
7183
+ throw new Error(`Attachment ${attachmentId} has no download URL`);
7184
+ }
7185
+ const response = await fetch(metadata.content, {
7186
+ method: "GET",
7187
+ headers: {
7188
+ Authorization: this.config.authHeader
7189
+ }
7190
+ });
7191
+ if (!response.ok) {
7192
+ throw new Error(`Failed to download attachment (${response.status}): ${response.statusText}`);
7193
+ }
7194
+ const arrayBuffer = await response.arrayBuffer();
7195
+ const content = Buffer.from(arrayBuffer).toString("base64");
7196
+ return {
7197
+ filename: metadata.filename,
7198
+ mimeType: metadata.mimeType,
7199
+ size: metadata.size,
7200
+ content
7201
+ };
7202
+ }
7203
+ /**
7204
+ * Delete an attachment by ID.
7205
+ */
7206
+ async deleteAttachment(params) {
7207
+ const { attachmentId } = params;
7208
+ await this.request("DELETE", `/attachment/${attachmentId}`);
7209
+ }
7210
+ // ============================================================================
6884
7211
  // Agile API Access (Jira Software - Boards, Sprints)
6885
7212
  // ============================================================================
6886
7213
  _agileApi = null;
@@ -6931,7 +7258,7 @@ function getAtlassianConfig() {
6931
7258
  }
6932
7259
  const normalizedSiteUrl = siteUrl.replace(/\/$/, "");
6933
7260
  const confluenceWebBaseUrl = normalizedSiteUrl.endsWith("/wiki") ? normalizedSiteUrl : `${normalizedSiteUrl}/wiki`;
6934
- const confluenceApiBaseUrlV1 = `https://api.atlassian.com/ex/confluence/${cloudId}/rest/api`;
7261
+ const confluenceApiBaseUrlV1 = `https://api.atlassian.com/ex/confluence/${cloudId}/wiki/rest/api`;
6935
7262
  const confluenceApiBaseUrlV2 = `https://api.atlassian.com/ex/confluence/${cloudId}/wiki/api/v2`;
6936
7263
  const jiraWebBaseUrl = normalizedSiteUrl.endsWith("/wiki") ? normalizedSiteUrl.replace(/\/wiki$/, "/jira") : `${normalizedSiteUrl}/jira`;
6937
7264
  const jiraApiBaseUrl = `https://api.atlassian.com/ex/jira/${cloudId}/rest/api/3`;
@@ -7707,12 +8034,17 @@ export {
7707
8034
  APP_NAME,
7708
8035
  WEBSITE_URL,
7709
8036
  getWebsiteUrl,
8037
+ formatFileSize,
8038
+ getFileTypeEmoji,
8039
+ MIME_TYPE_MAP,
8040
+ detectMimeType,
7710
8041
  parallelLimit,
7711
8042
  extractSnippetMeta,
7712
8043
  searchSchema,
7713
8044
  LinkedInApi,
7714
8045
  RESTRICTION_OPERATIONS,
7715
8046
  RESTRICTION_SUBJECT_TYPES,
8047
+ CONFLUENCE_MAX_ATTACHMENT_SIZE,
7716
8048
  ConfluenceApi,
7717
8049
  formatBoard,
7718
8050
  formatBoardList,
@@ -7735,6 +8067,7 @@ export {
7735
8067
  formatIssueLinkTypes,
7736
8068
  formatIssueLinks,
7737
8069
  AgileApi,
8070
+ JIRA_MAX_ATTACHMENT_SIZE,
7738
8071
  isValidIssueKey,
7739
8072
  wikiMarkupToAdf,
7740
8073
  containsWikiTable,
@@ -7,11 +7,11 @@ import {
7
7
  getSettingsMap,
8
8
  getSettingsValue,
9
9
  secureParameters
10
- } from "./chunk-JQOZTED2.js";
10
+ } from "./chunk-UNOJBVD2.js";
11
11
  import {
12
12
  KnowledgeType,
13
13
  SupportedFabFileMimeTypes
14
- } from "./chunk-F3HPUK2I.js";
14
+ } from "./chunk-XJRPAAUS.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/fabFileService/create.js
17
17
  import { z } from "zod";
@@ -2,9 +2,9 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-5ZYPV3TT.js";
6
- import "./chunk-JQOZTED2.js";
7
- import "./chunk-F3HPUK2I.js";
5
+ } from "./chunk-ZEMWV6IR.js";
6
+ import "./chunk-UNOJBVD2.js";
7
+ import "./chunk-XJRPAAUS.js";
8
8
  import "./chunk-OCYRD7D6.js";
9
9
  export {
10
10
  createFabFile,